From cdb011744b7271ecbb678b7e371ec7b7a68fdd89 Mon Sep 17 00:00:00 2001 From: samuele794 Date: Mon, 13 May 2019 22:24:57 +0200 Subject: [PATCH 01/12] Aggiunto TakaoBot con SpringBoot --- .gitignore | 2 + SpringBootTakaoBot/.gitignore | 30 ++ SpringBootTakaoBot/build.gradle | 100 ++++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 56177 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + SpringBootTakaoBot/gradlew | 172 +++++++ SpringBootTakaoBot/gradlew.bat | 84 ++++ SpringBootTakaoBot/settings.gradle | 6 + .../src/main/META-INF/MANIFEST.MF | 3 + .../src/main/kotlin/it/discordbot/StartBot.kt | 13 + .../main/kotlin/it/discordbot/TestCommand.kt | 25 + .../kotlin/it/discordbot/beans/RSSLink.kt | 30 ++ .../kotlin/it/discordbot/beans/RSSMessage.kt | 5 + .../it/discordbot/beans/ServerDiscord.kt | 61 +++ .../it/discordbot/beans/ServerToChannel.kt | 17 + .../kotlin/it/discordbot/beans/boss/Boss.kt | 3 + .../kotlin/it/discordbot/beans/boss/Giorno.kt | 3 + .../it/discordbot/command/BDO/BDOCommand.kt | 130 +++++ .../command/BDO/RSS/BDONewsRSSScheduler.kt | 54 +++ .../command/BDO/RSS/BDOPatchRSSScheduler.kt | 64 +++ .../command/BDO/RSS/BDORSSReader.kt | 64 +++ .../command/BDO/boss/BDOBossScheduler.kt | 31 ++ .../discordbot/command/BDO/boss/BossUtil.kt | 135 ++++++ .../it/discordbot/command/ControlCommand.kt | 34 ++ .../command/generalCommand/GeneralCommand.kt | 150 ++++++ .../command/generalCommand/JoinListener.kt | 32 ++ .../discordbot/command/music/MusicCommand.kt | 70 +++ .../music/config/AudioPlayerSendHandler.kt | 35 ++ .../command/music/config/GuildMusicManager.kt | 22 + .../command/music/config/MusicManager.kt | 443 ++++++++++++++++++ .../command/music/config/TrackScheduler.kt | 62 +++ .../command/tpl/atmAlert/ATMCommand.kt | 66 +++ .../command/tpl/atmAlert/ATMRSSReader.kt | 75 +++ .../command/tpl/atmAlert/ATMRSSScheduler.kt | 55 +++ .../tpl/atmAlert/ATMTwitterScheduler.kt | 125 +++++ .../it/discordbot/core/JDAController.kt | 60 +++ .../kotlin/it/discordbot/core/TakaoLog.kt | 23 + .../it/discordbot/core/TwitterManager.kt | 59 +++ .../database/interfaces/ATMInterface.kt | 51 ++ .../database/interfaces/BDOBossInterface.kt | 43 ++ .../database/interfaces/BDONewsInterface.kt | 58 +++ .../database/interfaces/BDOPatchInterface.kt | 56 +++ .../interfaces/ServerManagementInterface.kt | 40 ++ .../database/repository/RSSLinkRepository.kt | 9 + .../repository/ServerDiscordRepository.kt | 33 ++ .../src/main/resources/application.properties | 11 + .../src/main/resources/jsonboss.json | 387 +++++++++++++++ .../discordbot/test/DemoApplicationTests.kt | 31 ++ build.gradle | 2 +- src/main/java/beans/ServersDiscord.java | 5 - src/main/java/interfaces/TwitterManager.java | 2 +- 51 files changed, 3069 insertions(+), 7 deletions(-) create mode 100644 SpringBootTakaoBot/.gitignore create mode 100644 SpringBootTakaoBot/build.gradle create mode 100644 SpringBootTakaoBot/gradle/wrapper/gradle-wrapper.jar create mode 100644 SpringBootTakaoBot/gradle/wrapper/gradle-wrapper.properties create mode 100644 SpringBootTakaoBot/gradlew create mode 100644 SpringBootTakaoBot/gradlew.bat create mode 100644 SpringBootTakaoBot/settings.gradle create mode 100644 SpringBootTakaoBot/src/main/META-INF/MANIFEST.MF create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/StartBot.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/TestCommand.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSLink.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSMessage.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Boss.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/ControlCommand.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/JDAController.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TakaoLog.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TwitterManager.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt create mode 100644 SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt create mode 100644 SpringBootTakaoBot/src/main/resources/application.properties create mode 100644 SpringBootTakaoBot/src/main/resources/jsonboss.json create mode 100644 SpringBootTakaoBot/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt diff --git a/.gitignore b/.gitignore index cac4058..dd8eebf 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,5 @@ src/main/bin/logback.xml src/main/bin/jsonboss.json src/main/resources/twitter4j.properties src/main/resources/hibernate.cfg.xml +SpringBootTakaoBot/src/main/resources/application-dev.properties +SpringBootTakaoBot/src/main/resources/application-prod.properties diff --git a/SpringBootTakaoBot/.gitignore b/SpringBootTakaoBot/.gitignore new file mode 100644 index 0000000..63177e3 --- /dev/null +++ b/SpringBootTakaoBot/.gitignore @@ -0,0 +1,30 @@ +HELP.md +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/SpringBootTakaoBot/build.gradle b/SpringBootTakaoBot/build.gradle new file mode 100644 index 0000000..54c80a8 --- /dev/null +++ b/SpringBootTakaoBot/build.gradle @@ -0,0 +1,100 @@ +plugins { + id 'org.springframework.boot' version '2.1.4.RELEASE' + id 'org.jetbrains.kotlin.jvm' version '1.3.31' + id 'org.jetbrains.kotlin.plugin.spring' version '1.3.31' + id 'java' + id 'application' + id 'com.github.johnrengelman.shadow' version '4.0.4' +} + +apply plugin: 'io.spring.dependency-management' + +group = 'it.discordbot' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '1.8' + +repositories { + mavenCentral() + jcenter() +} + +jar { + enabled = true +} + +springBoot { + buildInfo() +} + +bootJar { + classifier = 'boot' + manifest { + attributes 'Start-Class': 'it.discordbot.StartBotKt' + + } + launchScript() +} + + +dependencies { + + + + implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.jetbrains.kotlin:kotlin-reflect' + annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" + implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + + //SPRING LIBRARY + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web + implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.4.RELEASE' + implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.+" + + + + implementation 'net.dv8tion:JDA:3.8.3_463' + + //RSS + HTML PARSER + // https://mvnrepository.com/artifact/com.rometools/rome + implementation group: 'com.rometools', name: 'rome', version: '1.12.0' + // jsoup HTML parser library @ https://jsoup.org/ + implementation 'org.jsoup:jsoup:1.11.3' + + //ESCAPE UTIL + // https://mvnrepository.com/artifact/commons-io/commons-io + implementation "org.apache.commons:commons-text:1.3" + + //POSTGRESQL DRIVER + // https://mvnrepository.com/artifact/org.postgresql/postgresql + implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.5' + + //TwitterAPI + // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-core + implementation group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7' + // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-stream + implementation group: 'org.twitter4j', name: 'twitter4j-stream', version: '4.0.7' + // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-async + implementation group: 'org.twitter4j', name: 'twitter4j-async', version: '4.0.7' + + //MUSIC PLAYER + implementation 'com.sedmelluq:lavaplayer:1.3.17' + +} + +compileKotlin { + kotlinOptions { + freeCompilerArgs = ['-Xjsr305=strict'] + jvmTarget = '1.8' + } +} + +compileTestKotlin { + kotlinOptions { + freeCompilerArgs = ['-Xjsr305=strict'] + jvmTarget = '1.8' + } +} + +compileJava.options.encoding = 'UTF-8' diff --git a/SpringBootTakaoBot/gradle/wrapper/gradle-wrapper.jar b/SpringBootTakaoBot/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..94336fcae912db8a11d55634156fa011f4686124 GIT binary patch literal 56177 zcmagFV{~WVwk?_pE4FRhwr$(CRk3Z`c2coz+fFL^#m=jD_df5v|GoR1_hGCxKaAPt z?5)i;2YO!$(jcHHKtMl#0s#RD{xu*V;Q#dm0)qVemK9YIq?MEtqXz*}_=h7rUxk;@ zUkCNS_ILXK>nJNICn+YXtU@O%b}u_MDI-lwHxDaKOEoh!+oZ&>#JqQWH$^)pIW0R) zElKkO>LS!6^{7~jvK^hY^r+ZqY@j9c3=``N^WF*I^y7b9^Y1eM&*nh?j_sYy|BrqB ze|@0;?PKm_XkugfKe{6S)79O{(80mf>HnBQ#34(~1_lH~4+R87`=6%>+1tA~yZoIm zYiMbw>|*HTV(LU^Y-8x`9HXY~z9@$9g*K^XB=U0vl0(2qg20WAtt2@$xbznx$sQ<{ za5-cN#nT4jm=e{bj#uy8d$;dF3%#$cK8}{$`MLEw^&9;gXiiG?9(MN0QMDR#6Z5?< zGxwc7yuUZl9+2NpqF`phD>1E+?C4hlFGsd;XAjPBFq0uCzMuGXpbg8|rqN&xm~|8FNJG}`RKnZg45_9^T=D3C+BKkzDBTQ5f5NVs=-m9GYb_yg>yI~N z0*$o@HIrw2F#?E!Q<|P|4xTid-M&g$W@w)-o92)dG-oJ3iY_kQl!<648r8pJ~dk@K5;JAztVD-R2@5QsN81< zBR&WBUmt~pxa3IT&?&COh8s%j+K7_~L4V@3sZa3;>*oXvLvzipOR9^fcE=2D>phM^ zvv=|`F^N89g;#Aoa=I=v7GWvM=Fk-s)+y~JwK@4LugDb99J*Gj2r}PUwiq3$wI3T? z$Fa_@$waHnWgk?evWmc^YCUkVOZ1yzvRMc-$tf&FYc@FfY;a;&s&5246dJ&Tqv8xR zhT6&#qzP86Qq&7b*npvK#XBnZ({8EVhH57jay$X6=mEmQ2$GzInz#n+#o<`hHp zoBDSv&BD7%zxj(!Kl)1|P^V{%w`UBw7#%WoYIGfnPmF!JJf65-IYz76!R4?CM+OtM z7oSzSn@U-1gXfaoz9PEz(mf`xuMJ@(W-dpaB4+b(bn!YP*7ba#ST?r z;mOda0fr40t1SX&d4+6<-qeCdm+8(}u!9~db63LUBj@fmO%XHcaw)VRp7#d8BjOjD zOjLB{uU5hu*ty3s+Z_6ZFmHC>{^2}$nJFHvurpdoc`^C#F|0NE=Jj9Q&EPouZdXOB zj<5{T7`zqQj6!NI>DPqZ873hK4Xiflz3}>KZ@5Y;?0O-+kpd@pM^s!ZbDV_R!VE;J z4U9w~$y98zFT`I8=$iI3Z>@#g%EPG<0wjGBNE2^j=f0Q2;Sb~k?!z7W^MeG9N!eFV z1xYJ>kv&1bu7)T+**L=evIl@ZZ^I9u0*;Fj*Js-?R~pef6{9)Bp)kY)<3Sx#EF=&Z zgCq?3a|;w@JN@3%m#VHR>Li~JGjm!{Q*mS2;wa?XpA0Y`fV!1@twpJJLZw_ zpe(lnL$65kHnC*!oz)06cR%I(U?wiSxl-R9IkvSHM7c{?A-?fQ3_jvj3=&vE^(Mq! zx#o!;5dMA2jr4v#&;Q&&jeYUl{yQvyRpi^jiu&xlWC>JK5tvu5{(12Wp?~MJ7@5G6 zJr>!3|F=Ze0Hl;HbPi91KJ-P0TQw6M;X0H-rOBW*D0QdQZc2SFFj@;9go1Z&^4sQL=|s#bi6*{2+D&M&na)7^jE!`QRF@>ND$+2NWl7z4%u@^YA|4h zO-wt1UfK~oczniW<87e4sJf2L90Sp8g|aq#tmP;MS(Oy``;%4;6d^H)aly9vR?kal zW1$^Q46s;|tSOuR6;OQt>uisEn;;mi0G&yQ|AoN@$FAJ=d=KQG7+0N4df@*CVS&Ff zj^+Ocqk@yYho_*ci-oD3i>0xli~YZ2O^ULvJ(3^_FG%vRsimW8{fd;WwQgnOQk?|@ z8K|+5kW7*l@?sgKjKQ>97)(&IzR5vS&zcyr|1bUt4~TLkDXs0W4);Ht&odp)=Kf!A zPau81Jgo_0{h>jDAt@+!8ydq}P?wZ6SkI|3uv@K&VdjR51Gu3_O$1O6&Y|tot7k z`tSLXH1lVvG&rRFfT`NaFt=BgIcykY65hul3hE~It|Zh0Fa4Z?RAExWF=3EroklV`JFe?bjw|%I;N3u#_3at$%`y9ZzUl1Y=Q}W#@6S{@3s@!*%fy-2Xe;nq3ztpVEm_%q&E32wfDO-f3 z>p(AtkpD2eI}`I}0n^qfVpB#PLqR3gqSz>QDSOE7(tN9YQglhMRd7A^?iF+t5- zx(-L+r)T9>S%lN8A}26&I~(0|vW-o3 z$n;7gHsXj@bX)M{VDmBIH#l9A>$r4LxOBZ^3Qc3h?mrLMCFF@s3mgzo94-(L;s1QV z{`CpvXhIsGta^U=S++21#RO|O(qd@9tO=F%W7s%ikkAE?1fvOpjyw^>6o)L=@^DAR z=WviEvx#GSk;n-tbIWaU*=D1Z8HULEkXSlqw*J{}mh~#O_4<9j-5i5^>}?N!Erq=d zna_Unvip8>^C|Ch+)3XBYLKJ@WAL*Md@hDwz47_7@-@=RPnfm0Ld}12$oj_zo8M^P z4LCyI4cP7bOAyc(f`4&l9aSd3+H@YM1H{)--ztm`?=P+oO(4M!Payw*UX{sRg=zha zmrI~8@LiSZ-O7_2;1}-?VW97Df2HZm6qCnUvL4jF-aUQTkE{rPcmvw6BH#;oT7v_A zkQe$7chsJkZ^%7=fIpeo(vqH1F<;z~+o*$yio6bULB0EB}G zjIxX}6)YrZJ%~PANu+)Qie$^h@|;*B!7mUc>xqG1pd~ZOqMI1lzxQ^Ea>5E+Z8;6Inn;RwQZICdr-dBuaL@qfEv+FgC+1v{EYJhQ#LSaDw5VAqfL;jHS39n9FV zkUqE(gi<~E)L8CbO2%cl&*i>crLK}N8x6*-*s6zD#k1Hk3rp0e$QeXrCn;ADiqAEb zj*|vNd^ot09Wz%Hb7u5)>LSaCvv@q4wsGbyjA4y7U{#mQrz5y^ExmQjlcbpz+vqWz znL&o|u$1!{%EQGlIfUfrqKBG#ti#@zK;ERH7`b!B(0$xEjL;vEX#jHrfK5h+H)IeZe- zb7wQR_Q_G*WH(JjZ8EVfOqD{VUw0xC$TZ_s&K$=vWjt8h4WsQkXva^(ugfzpQ-u@C zU6x~J!he`dq6oENJG9Nec~N*Q;kiHURO+o#=h>&&XlRjHi(`c5UasAkxHvW&u%+H? zYuP4(0{TDFd(>C1qv6TJiOa5wn@sO_Uh?HaHZP=uH7bT`aUHv+$l5jmV#q8Pcfee$ zn6U}k)@CsesYMaa&0=O}XoDmBi{|Z;9s1MTu4~)YoekxMS~>zLapgGsE5Jg%Zj9X0 z&~6s#R}0WC@ZU9PG$w)YrADo%52rDX)|PoF*0nL{tMTTs_gfLc(jkGOqvvC&G?nz8 zLITsc&IiI!#Z^o}G$M4_niI3H$m1{rYGjEaNuAq*;64P25*dX zTS*dkTrzjoXR19%^$;@G3P~-rMnUS1d<* z(r)8+V!fo-3x?x(>(=|c?H2pU9vg|ijd>m^(phdfi!%y_PK?yhgvAb$4IKHIa%RcH zU3@0{m_7>wQ63SY3J2`glg!sN=ZSXGUPtw$-A=)p7Ls`)Fq~GBy*N!r?MPRSp4hwy zssj6^BfREg@js;H#v}!G`P$%5LF5o7GzoYN$p^u(wUc$W$Y?{i%*QD^cH<#vJQZvP zevy`$&Lt9ZT1FH_+o6VLkPdo`Cn7FKPasMcR=SI^ny=q(rH7mX0`rAlsVv9S6_TY# z-Jc&_p041Z$uZUTLB!*pLRn>kqa2B{IZoRRx#cXAW(epbZedV@yG1y{#trSDZdSkG z-~muhMP4nSTi<=cR0>%8b3*9HH3hr|l{x z{m3qgh?db*3#m6AD<*}XBxZ5`p7))Gsc)O)jy!YHzLYXZAgDH*ZOg`wYRQfr3DbI7 z%e|J3nH%m^bpOJa z2{VeU$B}`BFRu_DdKm*6|sA>)-a!sa0ZPcXTIhpA$N#C65szy2(vxkgFub(8i_HoQMWkxbns9@~I zh&g;kS`96_a%M8>S)I>j7XsgF>jmXmOUq}FrRiyNPh-k6$$rq6rz?2{Zwn#mT2%$V z0Yc(5d9G%Py6DAfzB9s`2m47eQ7L1yR$8KS0F#B)VPDPPQ>r_U~@ zSc`s+yRlZ&LPgjpW;vy>Iv*Zz5iv`{Ezg^rPQj{Z#63}Ek4r158)bg5VmPW-B+9RU zy!RNL$+AW#9pi>%af{iq7usOsyF^-*ZD(o?bCp5v(TJGTS0P;v&obm1<=AN9Gj1P4;}RO!ivCDYdF`xN)NNq)ny8{Kimq!0Xjo z;k-goG{a@^D$`S&>>$d3oF$D$TWhgrLV5jg<(psV7=t43C>N|#>WY)oTz;R@84qi+ zXBX=lBPLHeyX5kQ(r`41R7U&4vJhs4@4Q0)Hw|S;fmbfu6h5)%(QMbwCHKjFN@Pz4 zdZa(ce(d@V4XTtzWiXT`RdqkYZ$gK?QK#&F%_n1^35F5JE`w|V1zwyr_{z4RFRyia zeS{Bi3GRS<8*JnyThZ)8D67nkw>=$A>h#@|qQJ)|3IFg7;ih z_Jt?lz#vQ^m6!F&G{;)0Slzu5Y!+g;TCDceP4tuRfu$*2ay`)K<3z^GPTh`z%2>;m zOE~rxHkku~n7GWRb_X5qjlG(A*fTccm(4)@fzp|)z#kNT(cHV!J#oywSH0w;)jp&_ zLZ4Fgnet_=kt3Jovc`s4-{65D>JW?2XDMJByVLRRFliXJpq;lxhsBd}Sm6x=-h1!XFo-fF{Rs7%xS|J#feu1pb^oY;! z%jnRPw2M0+Ux$ugC4Qm2P!Wwi1u$Q!DkrG}e)uSqRH>W}M0DG5G^9b6F;xs4z93A9 zhParChorwS@Ci+p_k9sjm3ca}1W<$ft@Me*eq;xb!|+({8H49C&4B?DW?7t_`Kabq zb_L&ANFQfONqA(HvkFnmJsEESmSo!3*(qE2Nc9<|e5A9q5?IQgLd01GVHTn(TGn=Z zu>qkhY*1OUA00{jS+CCM{;e{Gm&-mgZ;zqOU>Nn_{PIaN^)Fybd_nSNnm%06HQd-( zWe)E0_f@yN=v`$AT?-bSz|s)6Y~T*c4)3s680iBud)<~-Rs=9NC+sn9W+yOcrVfm9 zoJcIo9I)p`l)@xa4qJj#S^Z}@o-pefqwzT}qFm`>MrYrNBg4>Gb(1>+sJ_h9L< zKb5x9ha%2oMzu^ma(dIFQ%Jt@e(`iZ*^U0;5f6reTPcAW>*;BJMX_dRG|4ZaJ+rhz z3)95}5zEpv&Z!bY* z*0R?IX20l}_72O4nEE&(U|xi;FbVxl`fQ?Mmfo_~Fs2hOF|x-8W$<_eIrEBx@r@1d zQLKaFnBn>QsrD^vHUpvsG`BxEV$)j8X-1}~wb}>>_n@`f5S|duRD2Q4@O&e>p>mtR zdM9%8l6y-zcZbU93MUw*tbtm{mi!~c5MS{AS@U`Z$P^a*t#v2<8sq<5^ZxCrm^+y| zJIh!)yO`SjSNGmErXMO$07dkMdeI71Wb#RLPGB=tH2$Zk(z_&nX*e;n@t1ZKUw&L9 z%Z3|zSSM%p>N^0mexNVtv_L+6sFKc!^l(l}J7ZcF4RSOXKr?ov8yQ%`k@sZ1o2UPC zP(hXJKsS@w@b_nhcn#9@2xvuvPQ6|$nPGto5fbfTwrGv1W+U1+%D`FHWL6i44s&d^ zG=a-pERGPm-20sMTEP2{f8wR|Djw_t2Lg(K0Rm$F&v->WjBQ+xG&c`VnJC>DU4M3<^B4N-w3P_`7^%^A*~2fB<_ zq7ew1(K~p^A*Bu-FC_x5BQ(l2J}XYAF0IVeonTH|Y13KS^rzx;%?llJu}{q?EvBMc z_M{BJR3R<%eXb^*G`;hKQ-7^mwY1Y(j0d)%FBBOb+xcH%&00M?gh@*y`7~nCi ztkQlxBk&TXGM5~epV?%iwQ(&^5AiYLJgRYz+Vsw8{SFP|;HPfm_CR*uQ~Z3v&Or4! z$3iVAIL2_cRI<)FE^^ZbG-`%sL8k8aD1LyMDZNT#M}zOy-C0JJ&c&@v*;(qqi*W0E znr)7jv$(6)_NM9LB@qS`{L!_RZeoa25smlFpU1u-k#EA3;4XW#laVPWf)Vhadr!0j z>Vv4Tvz9Nd0)ei{rn^M-;bmQ{hv|OHMF|Z75m#?kIByz{Fuan^CG5-#c?3G6G@EMq zR#GLJGt;EbhFWmzcA|WWEyecCWx8#)py-55KX+1v4k;XF!FjGIz?0pp^a}Kzb=}1* z^AcC*!>YKR40~hsuF&Vy#mWx3Uuyfht+@db%Z*VBivV69{ZaT^9>9`0`iaYj0^-{( zF)sfIG?!mtDmnmI&{2D|qOxeijq?T=B6O=#mj!2)9V(Z_*D_f)MZ9PYDATe35eAI^ z5creHr3(e?ts+)=40_9*d<;^g%M+J>aI(51R^35%6jaXoJW&&`r?Ors5lsG27)<7LNvfz*K;lgRyezJy^ax6*kF zu^91WyXL`hs)|>UC7wDVwQT2(GIY*{hud(pr-tf31>;{b32G5T(uUvcLc< zRUbUtwhL+cWSQi)mTE^-!mlBb^wKib#$2^lKjBJU z4@3Mw?;*B*midR!J&_Y72w?;8a)~7Jm1U9sa4$3LGf#B#nY82WSw`~6UV!AEa*52g z!XuoofBneZfe*%q8!FW4?D!)F{bYdrbSDkYAjHTMDIctl5P*qzm0a-iId7u03r}rUwk}_lceAd* z8xdF8b$w}s@q?h!N-NBz}B!nuncB`+|J@uB=5RD&7;suL0fEO@Ybl2dKSWIpPMqR9(&F=Bh;TL%-<07d&H5(P({Q+$bv(XJ~o2xXoxL3Jcons>6UJ~6NCfP z;D`oMc|=yr0|u*R#e!TK%WQ>A-sKEHYbm?29k1KP#%0qo$*V~KNdk$ z^aEAcBOAX-oU)c)8cz8RgVNLDd)N>*@6dh}sWo3zn2sYhSOj*IHCl`{`p0*F0-yBY z3sR@pW;{HM3l8~(?>!KRatr|U`!%-ed5*Xrcg_c7Tf4sV;g8e(5Xjp(0jAfOGCWVg zj)&{3vyWIH-UsrAmz_~vA9r|ckGxZIv@OdfO8KP_jm0{}OuSz#yZL&Ye4WB>tfWt_ zdSQtUq&VLFQf9`(Dvg0OCzA_Z0aOoZ)+-JZ*T4D z@Ne2)c~fpv0D%{p&@H-SiA4YkMM_&@0SVngnjR%0@JED$B5=YTN`?t4%t$OwSfrmS zJyJf=V*~tWY2`&VGDQH7fi!bd(V_E9wY&fKCjhw*1`XxmAR@X9ij0Ahu$CY=IJ#Ja zKPn$$mQ;o^{HKDHiS7t=LK*3lM7k-44x1X9`yzM9^3;LT2E~nu} z#b&AUO4Hx)bo>lM%zF#bu~LHd?YZp-P@))u7Hu-cz2B`%zeTSz;9|ag8i8K#f|*IGV4QhI-2m+S{Q_wPPeV z%xeJy!tOsjnrWKWK8ny$s1AT*39K%=7@#@<1Q_1Ma*M!yMcG{A-WKjIRbH~S$yM_4 z8=cWO`)@i&tn(YDhwt)nM5vilZa_(p6Uw-3ah3|TyGp?*yBFGAMXZ7Bb~k(T?+9VX zo!LDs;97~x*f6LvJ}8p$EZaVeAau9FAty%cN;$@JahZyB5PO0@vHlvO2n{krfv2c+ z1qx-5;S5CNvGMufBmgOGX?1QsUG*327NC$+Wg9wA4mt!5bMP;O4W%nKLbwqz(lD@y2=(>{!Nix_|9#@ zh}Fra#Xk%%*c$!*-_$Q;`=e;De|0Ba7(hT&|2d=k*CAH_mw4s>)}Q>FzR`g2L0-lD z=BIf-x?lfg!(apj>|sc42xcR6u?7y)2)mY!kr*$`XA@A(ybv*8UCUybMYm8Y``bLT zHoiG!n*;J(ChO03srOCyX7tx?4v96+p1!}v%^%;J%}d`=YZvY(FjS8c-(ey~?(SE1uR@5^^ zyS!)&h+kc#tw-L`t6ztY03E)HBmWGQhd_Ujo{vNzU$qe=Um-z>5hs}n%}8-zT%`tO z$5vbzii{_qK9Y;4@IWy;$v$rU*x2c{9X;>%Ac?B$C3(wVtN)OSFKD*X12|6^;OQec zj1C|L(^tDiMa{ZZMb#f%?S2U@el11cRl2o(eZ%#9Ddzd8HF+pT-%X0{xfzB>`B2z! zO4IQ>8os`JHKz9~JScm~2+Z>aKudl|qxKHe9p7Q2_72~ueBk*j+=`=uyd()+KXqT{ z6x0g8zjZ$0ZOpGOx|Z8N3%Kjo{i1hK;V*zF^0FaWvmYjINMH+?fMZUre@JI77f%Wm z$Pe#ovd-`3URusLR?ZPyZ>sCGCVhM*;)+C+*Ft*!wkeS{4H&V_SMUoZi~;PZpkxg{!zF zXrl-{5uTfs5$cvjJ1j6o^e({q`}3u`c&}E}Coq<2;p5Rg1oSn&eOMgbm>8&vM;8GW zfFD8!G-hP2lccpLWs; zH)ywsZ6ZS&M@L|#c~t69fnMmu*BKp3Yiy0ZFpSz7hmcWacy^o%I^#~Hp6^hut5F)Y zlAVNiWZp6s7G_pPU~P@)Il~U(>QgEtNE4kzye8JB@|u#N2N0oI4A7%d86}XRMUh5o zR7RK*<%b_u-1ISfTZEL?zlbc4nYO*aUnv+o=78iHP^kzQ!sEi~WUDiYgR z7V5D`M8srTBp!SScGhPd%9)bQJy{DJ11fqe*!TSGtHWuzkCJSv`OEH?E! z-Ac2^>4XCbQ*y-eu(B{#*Cx74N&33NtaPP47MIh+t@o&e%}Ar8?N8v;wmMHZ#W|V0kLC!Ck(-g8&7Urzb%cNnrrzdIU&uC5qlhT-98O2?=U zG5@ZulhTE8bH&=`WtRTYSY*BMeY4NDXE*x}3YT%xaKyo@=bvwgFxh~n{ljB#l;BBt z&+3m^LH2t=cK5_*K(;UGGlcV#YB9oHQ|P5@Fz73aPb!<70FOZt&ViO0NZNr{ZDtS< zZrCf0IL6=*Q3HptBWf@&TZCposbunl1K>ffz{LXCv<9!29L%(LSNZK{moRD1-4|h; z{Iz@m5tuEO4rRY8QkOqelO$(Z%aT5o<>?!54CRZ~B$?uNm5k^RaKXJD=jT?ch-Eg7>z)(>QSsK0qCbWOZ7vhH#1xqA$db$yMD5*NVTm1 zT8{Lj?+I+~Nz09+bAc{OgHFZlPW|eUc-G$+Y76VK*P8(qWu3dQC6YMdW1) z>`P}=c>;qZXFD4#<&+RC*YQ+T;4Xz&x-R2vo8_-?)LR0i2EDi~F-phJj#_)6E_$l* zx=Hu$tpuIFog1qLo}kALN@=2=SoCUY9H6XUte;w50x5O40w$r>ACKy*rW+62yfe2^ zbjcrgG-FyQtECNnp|F+K+AsA~LQCr{%PoPkW);P%>S#k~pA7;)-)e7p0&9dxV?LAG zoq%UK)6`0Rfz@+bOs5O%>B`dJ*1?J#uE}lU=YA|1;47Q+C!JZT-TcrV1adsRb%)L! z)rAdu_UZbSotn=H>rLpNLUFEsTUe%0ySD;lJPmI-iqH@ape3CkfCab~&vjG*991?Z z+&Ho9jP>l{Srw;oWqbahxII;m8(bw~SbKS*Sn+LAO;R5{XK$M3JvKr-{^nocdIOg)lu@r@zam`OD=mbo)!xicn} zfM8J;L`b@D;}Ti z5~T20ZhC+}+N{C^fJXI4yu|DNjFu{@;|bYzFB*~bwRncTnrW75*y=e4T0iz;o_-l)r(hB$;YVkf4$4%AJ4Y;nMLGPXapH<-7 z0mez?-^6+IuMz#{1X}XH#Do7zoJIfkdE(r-CCHkobql7S4EPf8g zbstfgZYt9qBr?3kWy<3M_Y2}4A!#|#w$U!P7%w(;gM7pO6Djv5IgdXC5D+`Ue~;A8 z*~QSt=D$ReIqI+O*y^ZXxvUEmckPZ_WTLVQSQliCO4^#4!5q+%*U6a^a#o{^k{~WL zvc(aj%tkB|N~w*>sVxYt2aR=xlq|Fj2P|{IA;2X9(57Mfujm{QT6^Bii8PaulDC{a z_B-Cs+mD^kyu9x>>cv#U(xDFrgpg5obgO4ud7yv2BS8-54!G}8Rf&woNILG)6!0Z5M zQeHbVa@~5O>MH<5QT355_-nOwQ=_7MVb6rSKQyE-4o!$6wt7)W(xoqjr9s zL+R+|bexEcGvj(swOEDO3`)nuz}(F-ji)+Z6`9o@T_noqb6>Z2sLU)kr6zFgUxWny z)r!RS-M@`YYl}%M1LFoTNw+yyC^D^a;)Q#7Hm$Yj8K^ST2D!~I(n{Z5 zGuSR}k~-)cF^;?nTCi2Ud9BOQHvfLl|Fv*qg85itxyTkOt&AM%Esz)Qc_uO0jI*Sx zJVPB7`Je;@ypeCK98`iH1+HGJKa^1m`=DLGKvu~+zn#9D&aPT+%AcGfX~)>yDJpb3T(*gi4vGhJUq#(4x&Tr4zaP^_F1vmjH5zp z61%WASsn~KLvhzC4B2}mH6JTke4y))+glL>+EQhxt=qBi`rBB2AmWgKx@U?*o1A*E z<19UJc9$LG5-~f}Mm$lQu;}(6103uH-FacrkDs1zeXVLrvj(_JhR9WUO7XRW`)Nuubqs>pFc_)(l7vIVAeZfB6n|Dd^!}2P zenGoTo>+QAH!OdvMgo6i9wdoRx$z0Njo4Mq#v4ZH98jgQQwM}@;CV!0dM-D7uy4iR zPvjq(gZjmgK};G|Xw(!Fc2nJb7oth}vXUkC_2x5SG}L~E-KxCzk4v6z+a)o?rA)O2 z-hLU7Hr5*_nQY}?IfTjaxRtc#9`CN_(!Z2a?hSn>EUFVa)M!jMt6y?Ol5*P&Du9LX zqP^tmNgRv|HD_&Ya%;>S^CRJRbz0NIHDRuFq`04DP;je`FyCG2XZy}Fq7{#58*-mT z-Xh=qk=aj-S{ftjJ9f$@de~1gZI&WlSH;~Ar!mK+&ajIY-wS7?!FP%>G&VjT*h^!zJd@9eQ&P~ zF1FoS^K0ch=_Ki}gCul$g42%YVg@HVnu1F);pGZ)V8%@mB=W#NGCH;9=dldj_j$p@ zTYWuaT@7Ey+wH*Bc6lJq3y(WnP#TYm4#DM!TQe+9SX{P87DtzyzBV3M zl}DQ{YIN5|$68kJ1;$79k1RK}pV&Aw9vYTUU{Vz1WK%b3@O4>XB}H9mDlRUT4W%&E z;-)Q_10tcU#j{~}O?AXenbg3us)}FQoqkjahf@bMUyfFpO&^5v`KP71>2u)q{8ERK zF)sV?O4%DE+CaBda3W3_B7PvPFD<0N%Me|C$@u0`O~9c$EM;mE^8GkH*_aTM&S!H3 zcYhAS79po(s#k!z(Lk3GPC1{xM_IwWOh8jKw2vXgtKC36IKdL*okNA6B@%7896j7` zLMYUa4rlxdR`!uu(>VVYkVVMa44-B}^bEF`LW=M-0x&OK)My;JLIWxP#-uS>;dYYD8CoZ5rG(uRHv!f_hSRMQ1-hI z73S~=`tT7o8^SxR{E|W4PUwNOSaoZ;Rl5sDzMSKZDYeQYD3bjP`EyjI>s%kE zf7?XWL&JV|@F4wXBnV~g*Z?H6E%pqZlIDKoGAm;-W*$HEAbuRt>CLg>LCZ&Ef;I6+ z?>F#2!}q=EqYd5PpXyAgfq)49n?&Vb;rrkHJxvG$m1ErRZ|6hZSO_74K1O*H6C^ey z6j(wD7Elrx5LF*Zy~H4Fz#m)^tEv`_YTXspd9I5AK~)tb2H=$d>`kk*7A^Cd&X(H9 z(%$dqKXhqF2=VbZ?>p>Y-oE;|Z*Kv-A}lezw@TD;$!5tcMJ1TT(`z;?ewMMRvyOTb zr^YOJHw1qBg!G=Cfz`6fW{GL{9Qv8S^yp3rX|+d2mSomC2PK3&qEGV69+_cf-k#vI zOCG6dVz)N*_>;~ir7D>nSoo(U4L;Fnai^YoRENk%_ac@P#TmPClb!)1sCati0Lez< zgfue8lBv9_edXdhBq#Jqt(LS<01`ZX%GZ*O-UzFn-VAjYM$M8(N}3r6`ifjqsaobT zuwjhAOKg~YS_U(VUKJn%kBvu%9Qjd?D*?Nhv3qMw7K_~)Cw`xcUiHq4p7tPrgpi&V z?JSDpYCqhkS%O*ru&GOBP%*|>Pm8eoxJ1<_I_z-4KHjV+joqm#Y?H^Q6~SAMEpKuc zHMQq-|Gt=CpW?M=1l?mi7-Rk;AK(4}y5zNBB&)kQR$baT!R8}j1l{_>m|oPxKHZ-P z!jDSlYig4JRQl*13G-73#VKMWjR`SH4-+nH{w^OeDua=1H!w29l)5stPFF#*$w%|} z19g%*O{Gp(tJMclS#FujI7ktRWk8mcRgDF~E^~6Jmj@|UQ*2Gk67;Y%jNaG@f>>78 zEZNdTm1IL@0fiMS&}@99e15@5OuBN3NX`q32z#(Ue7=u`Y;j})EW)*a!AN7;lz>qM z9cAp030EVt2O>-?z2>psgQmV;2jgd^>EojrP3ziE?8w$c83ZagFQC1xQLup@)_9A5 zFUG!Ac4sGx#(Q-p&PifevPDJJfO<___~nfGV{kN4kOVK{_JwfpBW}j?=1h>et@7w} zQTBd<^5+$C*+C|BP$RU(>}Z_oMsJE{#yONYEHwh8+$?))UIa?SjBu)p#np^Ecx)67 zE1)-vd^);a>O#TNA8ar6mMPU5Y7w*@=h{}8F_z5c%R|C4L4gBrfz6^Z^rJ4SHfegaAndFblMlRsp3 z4lUTUGdO6(noT7p#S}hlp~Ox&NN)k_ zEdDf1Aq02V?P^ez;kBOj@zB=AZnoC|S7wXfKw*Hr5nlFjl|s=q#(ca)$EKZ_L7+$2 zWbIKp)VFehDC7VptF9eyo*00op0>zupw-QvBtpd4NY)cNqYmPGVx`#zLQ8M>3x0T| zs)-N*Y!>7iSpz;*1uU5%^ywk0HMQ9O#rvAKmb}$-OiX?M1w88`I4zYu>+#aKa4^Hu z7m|-e*uj9-#2UJh?V_d~Q3WjlH)^Qpv9$5s&&)bX(>?>%Y8bg$7JloMIZKwSO^z4~ z7v5ZJQQKuEA9F-V&7eyx4n$uzpVCGHP`<8?*xmnx2qQymriEHl&o6D#u@oH&+>pM; z(^bpfoD#^I%0xc3X=cJk!yE(7?K4sxDzPQCUM_L05FwHGj%Nrryap;bVTr-*==d*bm7vi=Sl@^}l~38vo+;?I zRz7?{wf+ml$MYhq-)bp%99}Pp(W(!T#Vc+c6+RF57t4s5OOwlW`&2!utu&H(lOnF_unxBMNC55}SC0{9%n8;tD3`tjW=%@)=Aa6;#IH zGNqHma9Wx*%EcK})6I4&%3!J|CRrjWjJ~B-#U%Nbz-R5m5XpMNq=vHmEY-rH`6Sht zz*R321~q^9c$DGtyfDJzSU${JkuR?Exnxqs!Zv1_)T zKhRvSo(sQ8l<_vJm-#Pja`8&Voj>^g7AU(v^U2w$5H6ecp+&$~?57H=T|5_hE0E*Q zm&MYryNCU-&apqrV(HQ3vzvca+o`;_?Lv+C*prFLqw2F;eTC~mrYUy*d0MNfq86PA zkrFVo`NHmS_W*0z14Yn`zZ^8<4%p_}9o%&7NxKm)9@h!9@adi5Zr449+o`yx^ApIF z%fUy1t6lJ9?~ag}_w~@^u>lh@qbg+1@k}%t%hOYOA(su8y<-=dO6SLE_$W7{B}RC{ z-eUhocJi#B=4WlGvt_DGu=|j{STWQ(XBVSBlU)91)f*qyo%VES$jF2Ighsdg zU7H9ohegXP;W=BsskWBmzycZhN`I@qm4QD2_`XPpI7O*o>`M%VgtQ3rTDVXe#~=G> zF(JP}d(lJ2gfv}qS+tRlbJhy{67>pyAsZnMOteoWj)_FxoJ0@bLQopjNMH>AjLO3| znzN5~jYDKE{&9KBkLH=#@PoYLPl=sv!zLOm)(sN3iw~Uciu;?FXRdESu~}jBhfs~i zHaY}3kNosmXo(dF>Oik_-Nt11W%e*43Kg6t^O>dBIG-ee*Q6Q$liqx_`PVw5Xkq46 z^Y$0>vD&B18Tz|j&=u*0k8TM4iZ|KQv{y0{pM*k>KI(B>-b;p@Z^F$HA7{$cXhL2g zp+G?3odnNXz7F~$r4Es1{+sr1Y88KD60M6g2SDXW-T4O>e=tuMiv<=VBT?^G`tW|f zV!Lv_BIcSHu}wtPaD#X>^*$Um)&8*-2^(j$lH4i#i)_s9!fW0~>&*9odwuJC?VF2V z+V0}3?-!7$#R!*pnf#0J5*L?0N#!^DH+e-o-(&g=zHq>YK4Y|Ew`*&$cmW#^?@lRw z#BV;tYv0PEdXptJF8`6$iw{nF@jV`oK5;-+Hln{+3H$Y!{gNbzf|QK%-%a})AM6u?*rijx|PRW6H@2oxF?I?P-Q1+hXI4|+^fl7l!HgYoKE-Si-WKKt?y2z21#%FH})#`uS- zVvt)`37%Ta{QOAEquN+7QdJbw>t$!Q<8MLD^?JHCVJsxt9 zu@Sp-W=156D{AOlKPaCQ#otlRbjmU(Y#sFylq^iD>hL9Q!)>dkLxUWlRn{pmx3U%H z{c+<$AX?H(Lj%UTjegLNSxOlDm(iZ+Oj*ZLfNDXFrbkt7I-VD|QRFQ@diIxA^rZmh-_IO92K{{#cCT|6=Sbfa7SBEQJF{~j{&jA>XvQG{`-)wWT0&d)|_-tW@EDel$i>}7&wh4f?U z=lY*rw2z_IMYxjB+0k5V$;9R-i335+3PoNz07%wKvS|FHIg=%2a^kpJZakdj{ zXFsyEF7hF9PKcYxbBQ==dmPEXP>$6rVV+26YdUtK)!?rlI)pO0FmHuEi@O8}5OGb% zF&^fg1}a?t*}ugVQ*@309rTQec1~24YYEi?7wJ9~a0c7kZz&m%d&ZS{JB!5gg)O>- znGLic;?|@RZIS7S@>Z3E9VJ66Cb*oA9ip1Ym z3gkfRBGpTTE0963;Y?DHz>Z17_8 zZJ3;AYaEv&k`}h%t4lcqeHixJwOW`g9u=8Lh#w@mzhVoEs6LKsR4UD4b>&e z{Q{c2F&TSf0E2})<%G$-A;_eHUv3@Ba|$Lh-Fu76U$4`wW3{vO;wC!|Br;gSTYb*; zCT}m!3JYW#e3#DHCOpCKZmhsd8fTd+d@|%>44Z~~b=&S=8r?F8jGd_J=n91`6`__a zrj#2oik&FbET^=}3#8Q$h1sX-<{+FP4#{*RM=kl?Ag<8!8>mF=(s|?ZWrAbADJg7# z5Sz^ovnBb-b0$irD@5Fhw8Dr4+HB5^yTS##pxNc>TG1X3=V7gdqAGMj&z!kJ_3LuoSVg*lj7X4BlHLrygY%(&sh#)&UJ<< zESHfQnJ9v%Ygqt5)waqR*2Ph=kMY)}ldN5?Gux;;|0t_9ByA#vc-QF!J39Lsw=_T0 zn_$XME&$mE#M)~v^JBil;EvngrmfqX7B>(IqIvd zhM;6cG?wU#m)C}}Y?o*oy#3~ccqU)_2w_SkriOM=a2=Tcm4+IC5w#)Ll2P1SSX@2w zqnKI&*2X$3J>5X{gr>R-@RHf1U3OxSL5#sY+md8%r}$%>tLP70fFtT%kV+U)_9K#P zY)DNew1c*gCe7Ca(5JfG7h=bqo(b+-T^>y*{e&7-Uy&XnS zrmRlMqdExx4`Iew-9OR|TUdiKh3O3;#Rarg4C}0;N9lVbAvSAL@7sC{jViw;*A!fS z#T)FpT;%W6Th3Epu5PE~+gHUXgZv8Ut;lP#p+YPz0Xf5qRt%7)ED$HqJD}LR5-p9t zpWexJ=gQoNG3z1CJELTFhH;`c7)8Ok2gx{Or!CU--WMK&o+KTf4xunxZ)5k0B+j4C z0pFaZDdi8^u(0aHZ*RaOBE`LV`4&CsKzwkofTN+C&RP?spfxt1+ zX39xzn7aqdDJjlU&<~*^-!jv_)4;I~(vLL~^lq-lp-7L@sshZ=bn(!a0JAir`txi` z*w1e9wa2*egU&YTG0g$U^QG@BItfhe^K58m^hh67NK1B7M!!r3v)J(K^3bM@1p0nO zo=e~@$4UVh^T*z}K0t_?c6^`$pTPrws9WBcb4wAIuS9-sz1jCP{lG3M&2H(Of(_w( z3zCGl>~|2`akh-?Flny)U*mD_`oSi-Jz- zCPaw|Wvp{+72i)1Wv(EeylcM?b^&ZElx` zaXPB^z)x{+%}IW8?#S|4iA`YhTAg*cn)70-hj0VV)N%l;5T+p@HV_Q!e_M8%iH zGAMCqvw7h}*9T=L?!I%0$vHhjp84?QPB7Thw;eCb{$jP@MZPct% z2prUbYI2>@rqcCM_!0TMijRi+s~)K0ztT;Y19Z1p*b8K1NFrdr_Pn=;N-81UlMvQV zrknRR+Wk50@a62MH~Bqg-7^Y8VH$Fl;de)akV}Jtog;wQ(JzoAyDl#%t51e9x*ArrnVi4Tcpz}B4BbNV}+JffKWORxZ>#1IYnuIy2R7)D#N zfaU-LAh}}_PVzPI9g0B=@{5(>v{20Nxx+3{n(4y|h71{<4Bt`MV)o~Z__em*xu=y3 zmMbaCfpOs0WpFqycRVm?!LpTe@3S+K4M3gc$$34c$dQA%eml6-$SO<$( zB(pq~rV`z;RaYszrV8+GG3;@Yof>6G>)Ra51$YM`;DiCrbGB+61=6!m;bCL|auCFMmlND1S zVrl#-)32%*0|Fe*|(&k|XM* ziFH|{$C4BB@MJ8a8wa&+uqo#8^BmlIq@*RR&d}g)l3|t03pF07nxq$#6Yr>|d z!|1AKXp$D7l98*Wu#1bCow2Q%Gnt%&iIJ_?=NOl>l`+88%HbdVuqi6Kvbe%%?-S;0^Ud?k zcN%BpI)vLAYb3s^5Xun5iy~2o0%#P&NR;~Sy`}|^HE8f6gs-6QR7XFUlLuhC!?L)4 zU9g08_&@qWeM2Q2WC{!+;iJnqtm0mOdfY6KyTmO|$|>bA%3nq~AkonF$wg_IcQ~V! zzr0qR*M5@Isy1)M=4`SgWBEOmzn04LPH{cErXZO;k5YzxU{|5G#~Zvha(N{@-EDi9 zzIkqjAe~-Wu0{Zuv{v~*f+q`}uVhFx$x9i25nsR}ms?sFSXn6lGp?SB64=X@;>Cze zH%@98s-yc97rcSNVfOAYTwS83?c3T$GI^yTKQR1IS#fgB31hZ9@uh=M_K7TCU?=+G>Ni9Zb;RcL8FfbM4v}G@mE<#qM_gjauEyl?dL8 zC-PgUf8VoIa)FSTpY07spBy$6{~vbn_bN$>hLtGp0y;lv z?l1NTUErb&QnM|!8wyKq9hPo%^7K&Xxz$PGOCp2Sa-;l%E2SMtOI}Rp11Esj-8?=Z zoZ^Y;V(nr7xA%npde+l{|GEcim-cFmqn1NAb~>`&U<`CoJ3KCn77c8@escdT%_%gA zR$5k~lmeF74+n|d?NnQbk=mkdRAjtfO47&VcHSVxu&W=?0#TFVm+%6NGni^V%KIzG znSBi`d?nkmG{5l%G)cm@DvW&OlRFuDIs2wK#h*2>Hd3FSn0})UxRX8-{AS!_4896t zGDuEhEPc$2B&6oz(bt;2NirX<8=tQ?!JvcGS+0loCaFo2k&y0=h;lJWnpLHZx>0qZ zO*3azrM-c3Ir{-4?(L%8PX0FvSRlzwW07}G&Jyj)TJR#PM&T~ zq3OVu|0gGgY^ZNpEiq0uc0;_^;utO)ve#6j+(BUA{^Mq1V3!!NY!m5hvDsKMrv`$z zu;DmvAmeVD>q>G{C${4s`TFx5hQ*d-sFYT-lm2|85{8qBXRMCp++z9Mf~&WwKsPcA zu9uxU6bI82W{2Wm3uAgqf5hEgFYT0})=?ZImX-}@VR167pi7C`%hRH<^}(yq;s2qnM=o&P-U7UZj+fY zY;sBAoDwybKO?{++aeZkLsh}%);%czhd#b$?$ls4zeWkiLUcZ1j?!=lQBQk8&DzkR z_%9`ogmjygMXFV{Vh;RXnwA7aE&DFCFH+L1(SFPxMyC&1b?}r;TxkMiuqa#NyoMDg z`gS;s^(boXg+wB4J7Yh8CcXEXsCA-(O0yzPV2<2p5dWrSYA#^2h~r1WBRI&2m7E-EIAV>~ zIdf@~;1`sJp6UAlVB|1RzS2ctP2ba>loQC^cE|CH6J(OWc@Gz~dSnHnySDamSTeBN z@6V)~>;}(QaQz|rfb}|Vb1@rb=8WcN^rnQ}^WiW@&s^jgWjEL9uSdOs zH5aq(l!&8lkBtnaIk$ZL>7j?-92;b(+>5(t^#0~Ic%o$c^xi{-oX!u`#k;NB?-Q$CQ;F^|i(`DT?>#$Ae`+l*E~pmu!sdLEWD>RA_3>?`L+dTut0G9gxhT~(`hVDkVs^?`u&RMt;O7TQ#=4WRY*>TGo$ zitpz~l-R4B;PpC#VF(HxU}eCBUL%JRN%7iwB&&pHymCEtQ#qq=^2HPN?!&g0a|x(E z^pOglCTs}Acd^Q?YNzS;G$`+IY+ftrS&hi&hkD05wXhF!4oUil9PI8&-S*+HCJ}#o z7(<%&a&vU%7Lw>tzXianIbOJ#L)GmaQk$25RNFkEslF2|R}9)m?{MiHxj-eYDelhp zVfYc|eh}Yovj|AMY7AI>z2WoDxCX<}caX3?m8{*Z_m6gl9x0EEQ#ENBc;-=*IRa1= zl+a>%ls=F{B&`hZufwjlovmYRp#k{4leK?R$b?Sk09yLm8`v8a^qi*Eto8bL#IBt_ zLO9-Ch8aWRUf>lY#|Z|Gevic$ns15_c83AOp1~B=9sTj&xcI;L!p{iC5V%d1P`#B} zRFn+lLeY9eVhOtnyVFYV?4dA>Go)cqeMqSFmrre7L@6G4W+ZgUQxsgmelZl|y28l- zCQS#o9mlsJ%ddl~a!dl&#qO~^K&fT?sG`~ zlOWgC%FIQ|$o`XE_n#cMs;Zi3?;O%x#CT#tb6RSV8a?!Nm=)wwy6Dza5HeKZ9gCt| z6q3E%N5c_94)=aFidhqjVZQ;VawV+yA}Shk2Sd1R{uGrg?r;er|Rf2Hs~5 zRUL_)A8$K~Ac|W$AZzJLm(Cyv>CoR$RAIM49}As%KpvUfC>W%!Qu$1$5$OZS$%?d6Mbf6C#-)g>x|AHHbNTDi z({X>cGO_aVi!yT%@JjCOlAlFl3|pGhBs$vm%85hjDCn9`Ov_mqjP3%y4u^-8B=mVrOlz9kM!^kExmd6#ng1kqEp#pUL*vM#2ER~CvLhi8caNUtIXEO%+(`HE zgpjl_)r9{28#;%%`HjM~So*hbS!Uk0UbggQ7Wlm^RyTTo7LKGERG-k-T+6vL3|b2* z@$+$_d%@ahCgQkTtGH9){Um{S4SX4q$F-0dvf%&;`p-KoL8R++vWC7-&yhc))c@dh zFK{qejvs5Qc+ze-6pm)fXMZhUx!&+>E&#&b6a z9ER3`^6s;afk+iqyIQ`@l#OJ$!gElWDtkj0THXV8w5lG*@SPv=lbQ6&4xPi92Jfh? zKtUh+bOqLj!+~cY(!gj{)w@E~leD371uSg9cBQ^ebGCIUtFF;(x%F4#if=+)rdq-v zI<&-D^vMHe@l`GgVCFWRAdxwPP&%ZC9=$kk9@&wLP#gbe=ec@A)<|D5BmNX@j}LIkJ0J9jM8MOJ23N{fskhFpFPaK*w2`)x>-~ zUpKs>VBhUHV;gqoVVZ%%+WI3A#GHO$A!n3vPv(VJw5~PSLxts$^h4B@n+1`T&N2V% zYXaV;6W*=^QCI6$d)N+fH4f6Q=8&7PXK)6zWcT!fKisxE=8WvpAx#jpa=AFj^VDP= z3^*29R(QrqrP8BlFxI5oJWc!&r6tT*eY!|B)+6oUJ}@x{JJRKN?_eA5UIFh~?@f;HYA z+wOyhpZu~l2-=u9$iad|=Fe|hm6iiKgR<|D*~`5B^&>9Z93F?F`39@1Fm-tc@9hzr@)A!K zx$l9GeFQB!IZ?GSYu9$}EpD$fiUV?TV~5xPlF_kzQyj8{2rctB_y;wlMeBLKboZhl zR;Q@qj{UY_eptgf-96#ICnD#vxKIh7;K|b`(Z>H}uJ|9rn4%8$=2jK}XQO{+p)pBz zim1X!gC8pv$HF-vpyE}LjbV-|kU7#GrIBUEr9#`d&LItW)SAxj^L>g%5it>ruONO@ zJEv=4XRY!+tgO7OA4?k(O`RXFuaLQcl2&>>KCp12QoT}J1P@WGYRxT^(rqj*t^16`pHKhtP4Ymyr^sH4J*#07likw~UG#d1KmL(%rscp(i7@Kxz@gK< zb_U+iWYfwa7-c#pSkE8oTy@3~Q*1*3q}yq*$mK? zPNt4rudrsXCez+MIQ|J_qw!fjTxx!2N9R+&(K^~Nm_KyXypCq#CBD0-^Xb9Wl1V!5 zT{@8R?g*hPr`+09R z^c)0F!WlxpGGQH1@+y?@kFZ|PJ|i;m6CRP2ADHO(1#uzw4Lf{)Wm$6S8;&KBP|je{ zmQ!I1ff=#hA{voPuxJjf*hUHBtLeYHkn-gxOhpQWb9&X|i?I=D7g zEsoLPP;IyzQd$kES+#%%-;IYW%G-uBPcq_B38wp?jT6uH3m3tf z*VWD(Ka4JnSJ^%r@pgt_NiwyqJCb!G;_z7%i1q}D?Fz9$6&g1s$$pQ|-KzJa+0V!nwRRG(`CgAUH%hpSgV0s*8RC{Mq{VZ!bC zFwsZoNy5D?J!rz6ryV{Ykv>Y%M>N_?EAx-&VBSl#3a;LYoAzg0=p2(fMy6hIJ})d~W~@(mZ#!PiLYrqN(KUT?vptfBpv=ucc*a5W4Q=u{nFQC zRnr?V=NwdcniRnFNy^G*NzEzRrE5+P6|c|v8jXqszGmc-O^odUJ#oyVNC^DhJITCn zsI{q>&?T2>WV4K?cuN(od5s1YlFhIIwHbN6eugY9tSM;}($saQY((YdpXvZh$j%Ns z7a*?en&JS_Z-xA~$SkXkO(UrRmq&`btHg2e{>(D@GW#+ZDJ~vynauXQ;QKT$M3us9j6lcF8AR_HEy=VI;a0!-VX8B?7=7?Yil)>sC#*V2sC z2Hdas6O*pgY{FEOK3i7=SUriKl+mVLxl^*4~H{qEl#Y{-(gUgDpK%6n(bVZt5RrnVa#r-cAnYE@yfZ^+aK+g78Nw=v?X8nL+sfeX+^Icc-W)0!J8APDB$~} z^`u)1RNH31ol>AK_FuW=(BU0?<5dbWoF&zcf=zK4PqcjU9@M)-XGF0eLU*0hRP*hQ zYe5Ngx$`o3aTSNG(M1)bS&b)~u0p1Fh)RN8kCCtI#*gfXSZhaZO8~Yj$ugDQ7LLSq zi}j7{)0;D=I({5?fQvp@KH!#sdjoIJawS+zrtf#{}nt!@6 z=IWz!O#9_nbY|Y;XTQlTyL;XLn)d6o*bsSPnDnFXSp{0*?@!o`&y89cNY#5!$!7XC zo`@k-1q^sX_uiD^#D-KHAf-z>dVFPfL9(E0_QSCo07%VHt)yL|z_nt4Gi*YLMWu$1 zliYG?j1{(>702;9!We`V0Uvw9=YYON;_?Q_pU`% zT?`4U`+0sr9?Z`b)pm*2FKE@mB=lm&72KODYjHTh^sQz(PNg5 z!!QI5&LN{WwfCmkWKqXHs~0#jc1(``tfUB=%wp425SXNWNALs1|B{O(hloVC-kM+~ zY#7}AegL&$QMfbffavaORRXjs-?~&3oS7p&0-^eqqMT4+Ne5OMUm8AX>`TT^X5%B2 zx?9~nQ|=lrt~qaN$WOQlK@~hK;*<7%hY7#RNnJof@Y&1J+6ivl)@Vp!P(P)~Cub0j zcn}V(NPVJZ<9rqI`fX$sHG5R}p+2^Kr-lw2ZTFGV_NdJra(O!@8Q*)NP0CFvHX)}$ zOC%86sls=3e1Yk_WDK=Z9ke)w-3ZMo^IWFz9>!U#3m}wyc-yguRXaGms6@vAQEEwR zH{{L2yek901zM5BG86Q522`XRn1JFZRZJPaKzen&*H~W9MCiZ^xPB~&slRe%B z7W199)Czu#tePl2T^oSWRL4br7p)|-i_rs?CuO=v(u0V4&C;XyT~mdnBl56>&(9VB zu=?A}b!(pX5aXpT!hT(z!#Pp9)Q`Xj84=1R;w1TGoD87-d)}74p)F8>75A&-o1x7a zx}Rs?&X&1mnzR|=R4Cx0PL@f4O@5++$#E()ip5AMGnQ<`Rmd}agGSm5cHh$AMGO3UHu4$Sruzst z<5<@59%{1gy5c1=28f@frlFRVk!(H zx6d}oYAn#tuYglGlgGUp#Cc~0oDMxq*b&<)8!a}E-8FsW)cBz0TUV%;A^)_GK@RP; z-HFb*QAzVwIKmHss7%2=E%Y_ltxtp#EewGRYpkTt&$UUsT~6)hryGiSXu(oliYKMS41y^gB`tKNY}=wzkz$WXwp3IiXS(cmrKj5l@U|w9CCD;wH_KoLyL zT@zvC4Wqop!m13|g7*eemdNLYPC@%Q(`NHQ}ud4j7Y+!b>Q`_l}js+Bj72lWkIy560U zn7Tfi=a+;h=o)7|&eFJHxKF##Etesl@F*r6Y2Up>xPOj@7BSq2?6<6Y+;SDaOx`jy zkCWR_>I(sW0`|_DZ~tp3B4KP^AwDQpX=2X}Y< z#_b(uEOiCO1~@A+oa~5IkhsEXK_6dAX{*MK$ zXO`Bys^kZk41nPEt{^#sDZXyG<&w+Enb1ubQ&4_Bin1bspxL+)66q{ZxhZu|>F$ z#`yQO>woaX8Ld4-r#UQu)<=MtwQ?)llaPAx_=38mZ$ERZs8i*eJ%|Fy-N%`(oc*>r zPKp(Fs)1?x)2QsiX7WK|RI8+!poT7Ob$ z$YmSsFjboM*?gbL#9O7+Gf?umDBL9~xlMju4MfEX)3Dc%F-}Ok2327m)Vlh3Rs-uN zJdM1lZwfE<{wUA!CpzARKPHX@E77T|RfX#InT&X9Fk(gS?7y~Y#yW?6+qQ7svL6i4 z8=haSF6L=)VvHdEFl<_=-rk=GP9sgNH(yd|;^mpt%Wrtj-fuN+k2MN?Px3Nrk6^~$ z!9o?5b0DP@Nl6H!FbT}DEg&)u%Q+-*Gds$-^2(B^J+T{EwhKDlyGQ`!j zz(T{d+so;ysq>nGJcy>>&I+J)enBUZH#?}JuZg6XhOAIpUw|)hio+f-_~Ti6H$dQ} zig8g0la>G4jQUBK?+YKb&4+y=<-{o6)VT3u@dIL7l?>h`>+pVvolfsGI%yfEgUQ~a zh%4A+9FQ|@XAss=g%--tk#N_I@qJ%GHcw}oCidl7AopR;k+X{NTfv<8+K^4kyj`di zZ_Vs0IaSi*UAks#ula1}<-Y_UjF%Fo%7$#l*TChT_X5a%>9f)YNybKi~0 z#yxI`80_D;wGn69Q#Rcy4y#3YL=byNib#jxH%uZh4zRMj-9@o5dOmAC;}9g@36W%G zfFIDrf*jf3g5BPwaw9Kmkzk9G#X$Hb1v5m_Hj8hE<4iFR_CQ6qW!oUjzj&Q5eI z`+6LrV5olr^*EJ<`40K-fQoO`gs0?Z_loSNNBs}p^j|hCVP^|~-KU__Cqb{7<39nz zl!S2^aAvd+#b?%nCZLWT?Qzd}qdL^81}q6|&t^~R`K(pCggMIaSZU2(`DPE)WnLc{ zy?P_Gxl@w2^M$+O(97TnZU8HrEY-KsU^`3zCIZ+&CS3MC^l{ibzi**|nE2tHYQOj* zKMo2S!(KYFnlHnm9Y$O_&XjUtN(Li14no;BMNU+RYY%E5s$uyQ96G+_7#zvD{s>pG zu`LlM&6qL8OvOO}f1zF^!*|>Uvb?;acW2=#gYC1QEa_BFru(|R{Q>3?6!U2sNXgGE zs-SKA0}dyQCMBPa9XS>TJ#a$MK)m*a{euCOI&Ntjg?{&rF+ByG8P(Ml@MqRj;XP;T0+B7*)PAM{{r#vtJ1Ks{fzy&Di)usLjAuT%fGD3Ut*gWWqH|NAtc|~KLc|$ z<&={oY_Jl197ROp%Ft9~9vj6c_2g?qZmQ2Ke2?I-%G(?vC~~m+T5kK}zaK(>m907&Gf3Z&ZteKa88rcaovVPXT;;5ispEVuySTsP9&$#rt0; zpzX;*j42i}9W^QWsEiV(RU*D&^*L=W$$FfJ{J{7$hhC`@=W@o4#PA-#|2Y!(?h1>U5epTxxqnvsYEI2%OY?!<&aYF9s+h&Z+ z@Qc^sH%jXVJv8S^1ftF^YxS79svTI~_jxNIw0xs2(4rx=f5p*uuFFr^$%Y1Bm%Gad zxh8=W5A$O9FAzC+1;QKrCp@0{zk7B57DN8a{Z;%IQ_s?ncAwQid*9_sHHjj_LZKWJ zrHYkzTw#-w?nNqY#11HwhEYa45?I3>6D=rqeSqyUFGVGL}DPSheSAGBSeCQVhdnWJSl#6ID~o zELekjZ&rB?klEEPW2BMW`Bq~>JM z)SO5(o?tjIhJMq~+C-GsnPE6FM#fs4!O>_sGL=Ny(l5^blVG-Cxe&i^A6Lf4Q&qMs zH8m9pYo?)1A2epV~Ow7s2fVHHbQ=hmxyOVoTR{A73C9Uz4)gC!)->Q@-(}|4Fa_3(4La zOJRaAIXORoj1QBH#B~%kN>sJ0C+w_9e>@V2X4D#nK?wMK zr|gPCrAUxgkiDdF=#|g64BnKeJ?$uItbUBTw}|>es0FMqaTaGS!e8kB2KbY?Os|A~ z+M_$?%iSa0RNF-b%VE?I{R_Q4=nNJZAz8E7QnabxJ}9huDKJ6x_(}d_Sz{j>9f#%< zt+?3Aa+_|D>z9wPoBItaTbU_V5uFUlM0qmhq7@F-U?4p(s|az=JB84GCpd8OvgPtk zq&w|Vrh9?pHnjx3Jn(V%)r?-;FJXDq#Is?WqS1`CAv4$4kD^2s_x-4$Bvu;w_`G`p zmfxdV z#NfO&%wH|gu3^nbGWdG+!s(s-^v&)3OoVWut>qb9{_^HcclFT>^1UI?3MEIB{lbv$@^hA=OJQWGI7!l`nn~ef@*mx zM4^)MVjPRCWT#QWb6Yz*{HBkn$0PRj=a3Wahs80aV0{l97Kp74>V5o^!7}VdQI>Dx z{p@+b1q}XAQ@r?YTmbZAl(0-$=a6VG*CAQvu1qs0+#kV3s6;p4{{62%6=6D;BJ{zy z`#O5LwgWQvbuW{4V3f%~XH9#9Pd`;W2JK2GW|%nX3*AgkX;{gZ@P)6xghP>;?vBli7N`^e32p@(tMTn_%vj(?=aPBwRzZY$L-rv5ATRL0qgM zb^>Mq4j`5RpkU*adsKM?+xheTNMVetL7_py!rAao>ehO zuDKP*k!Y{^1C)fFdUE<86H4Aqy{SP!OcJ3_Ttu%Nj`@sYAOB#equfbh0owwmW)5&( z>Sj>7LkFvNL6T6xh*Gd6&SJBHSi?h{#uqAL25EB{`Av_pT}RyQh)I$pHg3+Y|j5pa1|0Q z{5KU)@ej);9XPkW)^M93gFGte$Uw^QGbP;_h{WS9Jr58>^5SOKEuVdVfwA`g(r=K! zBY{Uo&TnX0%KVjL+(XAIPYS53Vaq85*rqkL%l5byxR~h`je`HuR1Ho?+8;>GZ>(3M zb5@VYIp~iB5ow>zuq!TfIfa%ELz6jH!DD3q1pVJ6WmG1Qws?IRA2GgdvUW|qEIRBu zl-dj*{zVA1p3e71`Loyg0hZY>^-WNFq*AWpQ-l*0hmG>aw5tgL^~I&HVoL_2v#Y0D6Xm2g$yGoFpIB2w8a*@D1$&A{qwk zAn}C+q7On2HXUWFixin;8>|?T3`-|^L1r4&7)#39OCWurNKg2yIh+hro}ImnHA7kH zb$ubG8NbAGQe-)nDtv?J-TcQq(^3m;$KoYT5P#mDX{f@47LA>`>03)OHBt%hXJXk? zUP$|@XTIFh2G4(`8Cp3>3dv`5Sbv{Nje-+==SU$hE|t8X|Y>0|2|M(+!akK zJn-BuzdRhZDi+{YN7gAH<2_o@<>3>mPh8VV297Bj{aJtq$KseM!Z?=1<2dQR=jcmg zG9-b|mN;h)x2h_%*uxINOlXs_2(}oDu-9|!31I+jP#7~Z=u)M`h&Mf~Nh1o4XpL=G z;#9NKtx`t!9gN8QtQ@b_p{2O!gToDWwZ)-A;Lx#FM3;8c#I07D{jOw+&Muq9i5RZ` zYyftBvXmQyAt`adKMr_ScQr=Vl2Nlz;h@Eg%DzHUw`%-8fCbEGGNlS3y2H3=AceO+ zZntHE*O-V=GuNNMd2y%J2Fsqlw7xw*(c0?)ELENTiG zU8Kuc!o#yA_!NOyqA z5Z1a$D4ZX4n+7&OImMiub=U3RppIfMVgfJHzq)9)auex_Vd{!7%69i^$ho(t=7GC! zH%EXv2VK}tPe=%dZFbxBV3XO?E;@KXtU5W#IV^3VNpr`3iqYVk=Z1*Z{eV^N`A!Wg z0A{g2;jkZY0fxowg2%=z(k$khG3GXvR2j#$5V2kxg+&6ZNxK$q4E9Qo(GQ-;8!iCh z-!Fc(Xx~dRP2Tp1`R`f8{hpy&;omZd&#v^psIC0xUFpA`)W1i(E`NVQt5WO~XO%uD zYkuLL9Dc#23ZH}v6oO06%MWKp_JJN2Lp4P;T&l|G}z@|3Rkrq}|^|d-+n?O4H}!2hb0r@CD=x6+hVHH1S6(xqwf}-Ut<~&W8gH0_&FX;%g+_M2 ze%pCYJ_1EkyAyS{6n=OE=R{3rHtKNUm%JH$N4>8He(4j>s}s{X^l!z4ikB}DaHFtF z_25QTmsH*W-u+f|9$F4KW8g)TiZoy8Iq?~+_ggQP@_}qk{qdUy@)Qfq!&3*5&?5cp zq2G&Fqh*o==4?JdknwF>KJ3%|2heS*A64b|Yv5Dc<}nBvaiseJUzjQhcG7o- z`*YEgJGh@{SfcSQV1j_>=U(V1dGxv_&Ak>H7(c|nXg{?kh%>UG!@)<@-6CA+G+&6N z&Ej%f%M3J^ZEIjeHIFm7}|iCDDWfqlseHXcSwL#me49rO4V}g@DwD{ z-bdItM-B4r_FOVhLqHO7C3pZBPrBkbi|?5U1}1Hc&0oTdCW2|1Y#_635|t9z9?VDr zU(~NOD6toJ zrFN3q4z0>Fv3e4#EtHkHq{_UGX_fTEXpf}my6<(um1?UK2yi2HOMyS-)~^Q8XQ=XNZ8v21%AxSfO0f`-$8}zW>YDv)k(3fCvPZA7i(1ZV%^c z-jmt<-cA1RFDGyy*jOx~3B1BN`K6rhw8swE%-IOTR&c9ArOjqL_ zT|jbVw9*m=>9Ku$DkJu{=G{a?MSJzs_a$t&YN9db=rDh z#f@3)q0_Iv;a@$lV$_^vwzevVZ5P2~Qu3@g{@UB(mY%I*P-Vw?MmppSf!aZo8+9KL z`2p(Ye>gCrOT~Yd(x#~(T0@%GsxVVoAtnoioA8!oZPM%|)&FztB5D+iXln8ZeW0WK(F5{aI`2-LiXsgR`W^E)iIklu_=J}j zu)$nQ6&vaQZGtuD5qV30s0acf$mv=$``ow|O@R76RJBN`{1HA6AHHK%ytz-aP@-Qm z`+^U^*}s+jUCglo0)T8n7v=;ECexLO)$gXz1#C@vcinHEr1zn9?{`=o!$2FuIgwHC zV@)UZz;_tUo=b%IKNh%Y^sG8Ui*5VZv_W2@m!;^vFADg-@iC1yN9<&e8W_W19`dEH zv>mbxd8gHGW-I-PsS8Ie(!+@n>gU{_y~Sr7 z>}d4achGQj!fQDzQPD-o*Ft547CcZRN4Qb>@A@3 zO0q6c2yVgM-Q7L7yA#~qU4y&3ySqbhcL>4Vf(0kIzOVnDdEL$Q^qW^}-Nj`sYS*Ri zsk*1C&e_{zlVr7au&JU+=~C?;zRivj31T44H;@9qp;<*)5fTaFd}6B0o!PeI>ES6P z28ivF00!B$A$3Ly`tG{kCcm)X7+D3G75NVH`{(aTy=+4H${U8_%^iMvsi)#=k|8mEcjpkx9`eV@dB* zXij9G3}Z4> zJ*CaXP^H?UatFWB+s3L!o;H}9p(H)Xk$=Iqe+h9)CdjBz<|kAsI0rqt)D`}b@8JFo z)Mk(*W(4aJbZHQoLi9_6j*|KibQZZC_dv~#tl6R+>B(lUy;|uQkxjga&p!EIeZd$o zZh8!WANYs}1jPHlSgn+et*g!NzTod4N+l07;AOotvF^>nYEVcj&snX2YWhSP1la0x*P;?W81vkhwXOT<{t0 zOMOD|A;A0WB&hRE(Ek4KLR}1JSg~} zS`heOQ^bTk;lrtymju~*V+loW&~m>nA_Gm`pEx&sx=`r1B%tW)52cWFk}tx)SbgOB zYJSa?Y(qlQA(_~eKykfnjgdZ|1Xu_)fN2sJCz;8pTkw=M4aIv{rf@RkVqJ#Xn6Z~8 zS81>&?9roB+|od1`hqLS1-D8WA`jpYRfpY^2q00`W`vccO2nFr8Qn8~v%GDQYF!RGAK7(f z<@~`hl(D%;4EI`&J;g9jQ&xHPXDsyx>zjsVPWC*`3Kh>ClAs&7mbMV$(cZ!#3e+}A z8u{EsNSf5dlJ#hlvgpw?RST|{^ri)RDfe%1&X3I05A{sF(-=@S5=*rDF+iZN&-^6T zK4(QX2IyASyZV&yr#v*f`ke6Sm!}LMtSHSo%*KO_md>&H=lAG0DqYEc@JR&UMg z_&p#4pElAsV{h_xG|3GWsS_3;Rxz#ADi?P(N)I_`5fwlv_zlfIB~F#7d^Swa0Udun z-6uJv-TjfC%1u?xEQvgnaM0o$U`fF+BG8?i96~D4a#=R4aRm{Jt8zxD0IvXLILU=S}PO% z3U9rcvZ7-mkNBxYQbd;P$t$%{bnfC1DCg~ zus~_hq;Yku*2J87!5211@pSY)lJOpgSgH1IOl*jvpD%b9X$UOQYmj6YCKI9c2ft4J zhg0UtGfKf<4&TyEon;_dCX0u_=rWgIL;;C1dlFSVzSb~vd)=@v8G$x-SP_(KAXM6i z)DDfsaB)Y*BI{IQ!(}7$3+nEQ%t*4`mK7Q4BXcD%ar16o=}s%KtSJsZIkQF!IWx_< z=L$&Ibp}^^ERL(mtq{4;iFeFVbjlh`Kr~Mp_#``g|lQ!Kb1YI%E~k zE&BCi3a97bTw7!P&B;4iN3_|8ezj2k`T>6K>M{6)+`^em_2|i1al+q&EQGoQQqBWI z{H1&n9)-!gb=Dv77ma$~b}z%!LZwY=8YbqpxUy!gHc(DGv0x_B1PKtOuo*&_l2kp5 zYl|*_1_<(p^<5`aVC=0OnyE~6PGyy?w=p~OxE9-p*Tj#TX@40XA8QTz8V|OnV17XL zxDq6o4ha8C|{g?;XWEhwT?I#=2~920N}@+;7>cBCv-UyMd0y zXZ#Ba>%Q@duo4q&1e1J>yF1?zw8y~Rf&4o7bOuGmdz^+WT!*#(WA&!-W3Jw)fo6@s zz?}>6%pqr}W<5HN$RM6_-JZQN^hs|fvU+Q_KHt-!GWk9e!VdBd7qp1iPpo8Kk*@7y zZJj)XxNPRGCYSUy%EQl349FP<#R+*(A_BT`Tf+h5^ooJByRX=W?GVlhS~p)R$DoX$ zeDTGaOq~@5khw!P)C)KkwXI-rB!y}@a1%+}0+?hWMCE2VrVJZU8##2hu(c4Zt?)!9 zw|!qP=H{Z6jL7b%WPin=b zshKDw`iz(TmpAw2Xv@%D)pP~40m1Zhh_|)|TyBuO_rwtKUzVqT+kUwN95nt zs^&7d6jK#UNlBA-Q=@j#0`{#ulZkgy4KX~n$LZUgWHf%YnlfR?1u^WEPiikZVeXel zTP0$}FIqP=8hH#kU(|I0I%kkx#d5?{cWopni@ z`Iws5Y;nSNdBfnTGaYSFNC@M3mB>*vPm9(fQWTK8E?ZwYTD$4YOoHSn%fqlt0?QHD zIfZ2PWAyn|{G>>M@-LD$+5>isd@VL*A95Y0LR@>$x*6aZ;1%6FrD%1>0sYdsxCg$& zM9(`0F%To18IvpVxw2a=AKvIySUtDd#c%CT%FlzLUKACdgY>Uh=wLl2m*YO~8%oiR z9YSSb&clNQjFhf+0OOj%(&$a}5S?MP29AR#GvGng?LVy&2OsHZPB5%`f?$$;Z3)o- ziP8^+l~udekNf?_&vvyKT50O0gW>CDcvdkbPp}ocsnHQga-e3BJ}X>2i|}0Fp;2ff zd7;Q*8dWWbF!W$f=vf>Vp<}FjB2Nor&xVjGlIf8Z3&SvH{FW5-_#szJ9l}=>!6rd_ z{5o6OZ1ASJc59rf!5KSXbnlPW5+m-Smy{rdF#HJX!=LOu@K^2(TjluZurZqLju1*n zvI-$b)fn*n&x4`JP*WWu@k4xU#u=CW$v$(M*wYHr-g|`RO<&x4#%4}t1NBQ9{cPjIe{qoh;VK)%dvtWhtAkhF&O+LSM7zI zqp$R@D3tq#oHoG!SBJB+s_wEDVEtnN>;In|&VQM`tGj{~D*v|)>2s#KP(^J+ zG=c8b%V=cPqbC`QuKOjFP?jZ4!+-OvnTz_flnwVx&JO)W1U?HQYy59P4nvMoy>XK$ zVY(h?oCj^wjvmu(r_;KdzCaWPtic>ZEQhUxYP(px0P?Ze+1TO2a7s8TXetwy0eNM6 zr9s+Yw@I6(Ru%fRnPKXGhttAyEFD(>X<01{jpti3>(6#RD8sE<5H@~EwyOIBh@>6YI%{Qsc zxEfH@2Ax$@7W*K9Ysy$tfN$!wHdGr9h8v--SXa6Gv2@bWZ?Lk%4zA7ydYHDQ!Y5t7 zR!zNp-7u94^Po3Q0scl-&0)BD3fE2MqDAno(Z0zcT};-N%UIj`D}Bp-p=rZRk&8#Q6N4;f zUQDrU&MX4>UMR?DA&y6QVBR+zIC<0QI5i^SR4b;GO_1@r8pu7eJA~IC=U}HrJW@i2 z1>&`^!4%2)IH!c3hyctcrh=;k-9OL3*l%tqSi?2MAO!A z#2iy}Z@lugc51ox0RzB$^XQCJl`@0bBTgU?+R-q#zd78db-GK6Er+)fc< zUqy89xT;hFhw#e8k&Wi4xdLE}9F;{gU-=J`5OA&V7EvD1#|+aE80#BIn8eUV4{iTC z6qwC-o_Ya8p$ae**#DQc*Y88&{T4yezX!p>i~<`*&6t;f{TOs4(^Ur62O528r@rf*RS-B{Dw*qK&}(#;!=)9zD_Q-B@$+vA#PT_BpR zAb%DUlNrGi=$hJ=eSqPc#ZK%Q;y4S6H=_PK1hnbTjh?PfX?6a=DC}<6u>9bJGcx zTdl6qY6KtH3(~0Kv{cV)8*c7sPBO9fvB7%k2D)3f;<-Aea8j_hEvzWysy$FcevsqE z%1aKLH6IlT9yJSrx&M&Wqz_$_H|A$=WR|SI*i?R=?xGEE1)4V2g6Vqu(QR^(o7F;N zhzmsXexx47c_w-3$vt?@`5SDfN`noykJ4P#RZU=em$|ubcqg8A1YEvqx$JD!WlFKx ztGd`dr$Ck;&od3ujAX80TLi!UzCAx^(|%fbwSSPWQG_0$Uir1o%c#|j&` z%Gt46HmROIhINdsMxxRu^peYx`UC3qlXVDLHE!}>-@%}5)k;KZ4YM~4UYr8J4{<37 z$wZ@Fgc@hfipGNmt|<-hB|`O6vv~zayYvHpC#Y6f%Vvzn1f6^(i8=IKD2=xRv|HrKyHSx1 zbG2Uzh;b|aPu{G*Kb`t7n-NKh+Q0E;@iu5Q9FYx?%!_wh&7l;8R_sI+LbAzgLTZX% z=Gi6~Ey*rTjGYwTqd#+cQ(gB0;`x!ztv(144V>^~a=T9Rrg)yM@jrKi*hR|mF)dwe z8}tiJ_LB+SHYk73WHiERSA(^oK7$EP0_0m6u$(}@B)AffDX-Yah^c8wdFGI4|N2Y@ zyEkr0YhL|<86zsm>HU$u}G3)&c?i)97mH3R}tP5&FCW_fK}tpOv- zKDJzOxzT=2Bch6qSRW)jz_(d4pIGFxSdrmi4}rZ&sV!3=$2-ctr#e+EXU+uS)(4gv z@hD}+q3?nY{ytYUe)j3wY~)2m%U~&;A6m#7Z?tL#*+svb28SED?dJ?F0ZBw%;~o5z zE;P;$#rT^Sv>FP!NT`cC*w#k2M5W3t=kN-3sXB{aq~l)9i2S5ZWIHGBmp@Y((BukQ z+)|P|wpG(C+l$M8mZMR}Kwr^iOp%cX)B)_01 z`4C3N_vO6M{%qY}F9V3*}Ww9A;u5XF_n9KAJJA zBbIVvU@Pr_7nZB=i8kt;@|vmmMeb1S=jCnuwj+lclWH-)-FZAFr~9apOI}4Z-03hp zW@$9dT}|FWxL~8fniW`H>S)uNvxSzEEx1hwYlYF4*7jZyu_YN(rWF@KaBms3Nc|D7 zZFd)Wdv}Z#C%{Rfz+@#@$Iq4GJuZ{Mn#DFXR8pN^1dRdDM_v{LN(}|3vP*Uk2P!%x zT;4$j?V|0A#5Ue;gV^!W;SjJ#BQZ59@<13mI;A(iD3kZx66G2M6N6F>M|4SI@*+Mb z;|4!mJ<}AaL8st|uWmFs`?A-b97Heme}d_Y6rZsN1LUq;L)VoSKxi1~P|cJ&@qFlv z?0w5iam8)1fZ)p3lNg2!##EOWc80BR8#8eK3ng-_gh@4xf~ zO_V3J&sDZ@^4q3K+u+^xg?oX%r%L`RUGCugNm?1YCXmMJOTfnZvdH!mR0As_ z8>h|*69zf0h&D)5SnJK)2OH5jhep$5yaGG_f;886iO-p_hdiYYj;8-QrFEjefi?NG5!jr>we-mB?6dM;$70PNorVE_L=+~dDLJjhbs{Oy$f^~}0O@JNqHS_Hx$ z^2sj|Sa1Z=kA_f#Y0xNGc$2OGbMX6bt^xJMj|_UxOE4sv$gW3r%-yzAVf({K`1XV0 zmnqIoPVN@nuFf||J;VyG$GF+NaUmfcA%&1|v8&WYy)nyp7%WLFG|c$pX3G$4SV_9> z@m$po?+E=;llFz#g_-OL&elGJSYZuDWQRWY0ZUB{kE^Cf~5)L_|y- zn}qC%q{Uigm_?J@c^{|--4vSRjW)qrJCcPUKl1RC;CMdt6WEsHg%4Gb@3hXICiQW9 zhNu$LxO!fxz)8V|UhqEAChg5V9D@ZP`3f*!FP;`t_a);DKIT9+39d5wPT6+0zraZr zEp{ev);3!&YZq6nb-*&|5g6-X#;{g0Sl#|mNAy#11{sGt`NmiGHN_wwLQpl6g&`bP z=+Sipw&JZ#NG*P_-vFb{MiW-4^9^bRdDtOiTj1KkZ29aiy!QhyZ`Q5B7rb(4ItZx+ z0u3?=O-vGK^sRI8ZH#0cjdm?j$`5LhdDI7``3)`|91`XfMHChw%hPi3d z1@x$L-aXU`&db!y;_JAyB4bcvBRRLkg80?cr{x=v$$>9YuTaw4!0XflDm(ZFWbqBH z5)P5iFBE#IjZpF8cM9xa6Z$9If1UB$AV_K<02bd4I5%VZU%cS|SOq32ZQ6bZn7J$^ z3XCIIOPQm>n!KKs@|_7ox;P6X;VRMu-mQyYurp=LelznU|HDoM8Q(p`y%^@S^|Da_ zsQLG7{JYF^uY=6hO<$ka4|YI{qG;S~4ojm27Q0Z{nt*d61P6NWqv0CJG>_dtJ(s>b zG4<2O@7x_2cf2cBPI>@JNWov^E7a`E>=jJaI!+Ss0C_D-RsEHs_g#I@FXO@R_8oBLaq-k5T~tE z{lQ_*CKKt(#|bkY(V|deY5-AHkTb|cKSf^h#tSq+0!7NV#C{I-v_NJq%#oEh9wDeVurS~id-D0cr*Ub*QiGk+VJR+JOP^vG^ zb4#|Yv?r)_G4VlY`nGAet?j-bTt9O>15)j3pMOBDMr5?B(yW8uF`!*;N$YNn5rH=J z`Ko<bDt0N7fUj2cLS%4ClszF*{CDYjK z(1i0B?*1Y+gC*32C{}zQ$qH_zABG+79n#j*QeYPjeDxA5a>i!HM00Vf0`!sDNJzo} zI!%E ztZV>>Tm1ivS*h4q{=?B$r;3acfd9t3VU$e2;S(gnB@CiMJShTXE>S2^QIQIYW{|@c z8_DP6pC&0QR*BtPzLx|lUdrwl5N=mHi@g!(^pEH?o@}291xrcrI-I7juRUjfeQj`m zdphL?a$i$L=x_D^DDCu(ihQDwL1~AeMh}ZwK`UwpD?sbEwM2|@7{Pa7z5c8^3@G5S zr`g$cd1tR)$0SwVUW?eYwZrVF&EI%GIZH8Ybr5xSp`ta8>z+p_v>jZ?VGq-{*AcBH zYAyXBy;(r)vX3xX|DK{@TB&lET->O)QN}h-Kn~y3O7@%1WtwyFMZHqt&R3B!i=xJ| z_Lzs_q6l0tYo8@NTzl$%)$~^eK|6=lpUl!ypx`JovX`)x)eq2JVZ9p5n)H7@`zQ= z%as~r054FNw?~dpSTjg{IyllBVIO1zx?u@5UPVmvX`Ku*z>sNKiOe$*>iISrG1$JE zJ-*nclIQJPU~m1&`9uZWv5jH9cZg_WnoSNo9np1A7Oe)O?S zDi=8JMm|-Ny=6^Y$#i*H`2iKsAR>)Q0uc(Tg9w9300ro&4-h_xg9oQ^FeC0nOKDr=Efj%S zTAH)YTO5l56)aIzPcL*Wb}jCycy|r9G@d)VdsitEoV%X0Gp9*_BR`3qbvmAN9%MV7 zadvy2rL;_U*x~fhxYMF@+exyPs5lM{7$35NlJOj}ijWKse6+{hVH-#w*I|@S-C>TS zZVOH&3zpK!R%fD-3m%7@2Pn8EhJ7a8BrlMOOlAy5NyQ*H^k$NM!K=aQ&gU2wF3CJj zfU+>jw;(G^8|9-cq;trYE5=}&7iRRBpArd1$)FIZk()B5pH)`M=a5uUDh5rYZbL0E zE6o15dCgN6k6DgsG9ryU&omwjBR!F{96Z5TxH90?_DwiyLPhu&Y#C#ny1RZ?m}ZkA zEex!NnL!&;tGLO%QQg%TQj_Abknm}}GV8ds2A#8oQyd}sfqs+LP6BFhrE%7_OS{5eI$ zr3oV6&yB=l#HII#v0rK@5l%yYogR-{)OwCM!}o33154D%Zk`TioMl`Wv_;T-M(!01 z_yKF7mDb%NQw+6C%B4G#g8G zQ68tzfuAY#$~t+Gnw}=Hkt8{DU0ew)Oi$XSVpA9q_k)i%kRo+DP1eKb;XY$q93MAV zmua_DpVfo=`OZi8u=+yCepV+>C;LWku(ZbX&%qK4QrG+2*uqw!wb*PO13$YskS{?uW=EGgRctq9p zfh-(ud-L*)bGUqLH`R9>$SQc@fS;}g-*IhW6t5EH6c+8-l5QF+;SggNPcJ)aCfAt3Zp;*%YAEe{;JG!E%2-h4Po{W`3l+1+(seGQ5I)8Z#mgc zP?6$;Nb}S91VqVDN>MJEu;@lpG#Jnbmx@dmv4mb5p6_=Z4&qzA7kRhGzlwxqB#pchs zO6W%hR)~13T8VJ&QA;&gjf$^KmWzP-lm`#8_0GLkPhjnf zyufn7EI(VB7`1cMJ4|Cf_l@?MLfXEjuU`*!9eD%DrGjJ(azqC1C>e9~oeh-XIJ5O!Vep)U( z($W6}N=KnoTx|?RuAaG0C&DB=%jY;&;xG@(!oFIkK9h;b3_3^}P#{cM^O(uY{K#=Y zH3bvg$C=9`5uREie2*48Sq42ZBrevN#+od6UI#)Vqvk+!GRz0#x@`laD_`JwNot_F ziIxItV7)dJ`%$VoZXK=5zXl2#B47`gDODs=RO(iooITD`#W5?_w=Oh9!|vU`kRnu0-0@5WPp^pMLll6ziysTcGL=@GS_3 zwT;ovj;Df{nQ@_2)HI87EFCdOLH@VC?ww7V zhiHebgsVi-%_MTzhwLETk=bOP*%)51on)R0qA6`0>W`+N*&w0GJmf8!R~LjmvdR;C`g)a8z-yRWV>t z!v^NNE{*|F~kpH6WDTa&YpZ5*zq&# zuybYDQ01s{SaE`J-I5j3ssGX1VKs86B6@;qg_S?hC(bdav4jIP4ARShYHbS>XfDgL zq_wm*gluUNI*5^DLBDRD#rC2EvcTyjp-9=d)i7SJxM&pMZ0YWs7-OCOG?kW|%RO;%h%NDQa7S z{Yq5RMCvfCN+-Rz)A>DC&f%2A>?)dHIYku8H?OTH=XTX6ID(x__b@gW=s%@9KfivW zRX+z+;=|9-*I5BsHG>(zI^nf{$qNih;jZ+Jq@Qt4FFQQv3 zdyx|_U zO5sxG5$yrOB@~9OVVqO+u>eDtC*A`k#Yn~5tpeAScebSKXikvu^L8S;QOM_AYcA=d zFCF5ogh;Y@TjDZlECsSh2No*d9DJIW#?hAOHYQ-R7t9I^yoKaX6LPX|eiHkKH<$;I zI};H-`H5aF%v$Q$sA5BVL)SC#N@K-(_{EHg>mDQoUoARtFW|tDbr&~Pl)SCckipMD zZDhHWi2m62j<^BdgN+Gi|GHk%Eog>?-=cf&m2u&4C>-+3Iqw`d%cm~@$l(z^6lxi% zg+7^QRS37P`N!bQw0j3|2u6CC+I7ctp{2=$2^fENZP|EVDzb#RisumeEsB-M&2h8b zH>PBds6aXHH7nEm5&at1)P2)9t(-)5BAN8Zb11@s!Dz4o7pb4XMMxb1Frv%_O5Fkc zq$Lf{zCZ{15Og40y`1Gg_b9}8lL_xT@HYGTyE1Ovx_^pAtHp4?;)!DM6)$fL>q>3! zgpM1FZP6Y3l^j8Kgv9-d-0#RawNnIg+#1q~9I@X9eyzvB;|Zm2*c@-U16HJVhgm+T zou;Mchc3YGDpB(9NH3Fx!8k@B1udNs;2F57aX2w~V|csIJy<~b`N%mrQGnqJ?~vi4 z$Ckt!lW91DjN|7F+W*s&p`)zQ|2!EHZf}?&z6P>o(;Kz`6ygUi>lnHhet{)Vl8+qw z5Ke5#bM~{pO(gG^I9`m!LiJ&Gr_uh*Ti4x85RQ;UANa88)1g4Dn$6XyFp}16&;*uV zr*6|9eKyk7w_J%}g%rw-!J8MqQl6+LJ@L}$$YxO{owAFaJ&_7gj_=%*oDy;d=K?4Q zoDs|5iE1DQd7^*mlEH*obc|Vb-(eK*ecLolqOmm)tHSk3kJUCblOz^sYpI7IMNv-I zU5IiJ(b|ZDo|h}VeDGc`<@w^(O>a)8(z|Zq;So^6)k2`wR{0ZQ|2x&Iq6_LmY8ugG zpg1$BgGax0+xL0Te3*!`h{B2t^>e{XJr7DECH&>c;A&=Os&>YP9dlels_bkLu+=7v zY2nmx(K!QL)g6cCW5gctlL6F2VPu;=(c*rxp>-3Ua9TG!wH=71aQt1W=kP>)J?z&= zlk0qu;NE2WB|798svxrj#gkZ=IwdT`c$pSv@bT)~)yJQc%Hc9+DE)OtgvCOU1|G)AM3Wy%?W-`sb8>~AGu#c0+g^}l8zjpn!Cz{7#iZRkFzuf2 z=tc-E>&Q{S&`;rrA6!uhFDVU&|714w%EH5hWCCg05FQImbXE}h)DXH9f!A>u8Y{VC zV`tMKm`$9jqPrpQ-m!98ev9G;y%v%>2bQhDx)E;Vq7y5GY;vI2Z;fZt^MpFgAoflE zs0VRKh3s3YroOTWJKf38m(oi5@{)^=Pu=&22@=9Rm?stP;g*=B*ls_uF~KA^CwVR< zB1sOkWcK@{gyqq1!%u; zQHoMDfUehALvh3bx{Np!BRWyb*G6#6gH>`3ytuD|>W(;d=gv5w!LT*7?<+%_ZJXYf z!?~f4?(3kKJ(O!6G@wDz1okQ;2<`Iu>|+V~M&dH9by0)?_t1e+!Xs)f1`K!Vg85DE}dw$^wC3 zRPnc3vP#gQHOIf$IYix=Ml#l*!af?F^F}UGXG;wJY>NDZK<*HR;*&2-X>WjLXbLw& z*b@r1%Xvb!!57*uoNqI$p!s{0mkG5xEA*TW&UF)ET*0iN+1MU=0{^)Lf9PG6hzK#HV zrf7aaL?7X=T4!8{=N8edb43vwSNY%{u{>H^itHC+CAfUE37}i9hVB_(qa7_N6{gE_ zW%uF5_KKSyG@b=1%M?2xJ!P7jqlOUua(|Am(MtiTM5Xyo12UuBFTsjiFuE zH0fPMkgE8;p{7XX2(jYB=avk8Q&T!DX}hQ8z2jcc@a=JVrmsF&p}j|bxiii08y+Z^ zOFbf2x|_#nJbD@vl3TAlufU16{dSiWQDRrsRkQX3x7hL9B>N|YpIuzpUu&Yt&nmom zypy^|S4TNOa=PMW^TG*vA4rOQV5iMd4)0A7fh!8^c$d$!n8>TB zF1Ft0ri@;ZX|YE#XW!xyvL1FTxyKP)if#EMc$Y11pzWs2P7a4;HyF?8TD7P3Eqo3s zTzDbc&oB3tIUQ4J=U2q8pKD3`MibJ1(3>qX@cGMk3LUGDzgl!r7MvKK95loFIS_Br?707I zd-nD&YrTQy4CV!}MQjMz>>~TmZQ}nsYcTp(a{6zaf&V&URy)?kQN#2xp`WOihLorC zBReA7tEZ9rMzR7#ne=TS5D1{&L^6LEm_?I7$8F?_CS)n|xk~fgRis%o?sNA|j=b*!SdOEK%aU;jc=trd!Ne2afp^ZGgUg%y`Dr&0M<~C@j6WD^P9)Kn zAPW+El|cg(ebdWKH=dduB?V<}Zu+^c*;ds6^vig+j>;WoDn4uxT(tb9Fg1${PA#R& z2P`k(8qo_8RNe6JC*uk%JJeKNSR&YHMEB`#zP$dnp?B;-LoI=OEtVI!TFB$)&|l8W z?tMTP3l4iMS?_^$(7E_gV(`O;kEwhr^-5T6GgR4pt?a)~r7g3#4$&RMc!rZpZ;K2tXR57pXn2k-|xMbXfX1-rEmhysisVdLH zgK}BPiVTM-mDU0gfudFwOYl*bHr+VpYS78nu%=1{$&^=Hy4XI+D(>hS&Ve1`GQHXK zOVFCsu+gX!(qjl|YLm}U%qbvF@JyIUDTlHG5%Bu^@kRe^j}&M)U>OgNhV!`Y6r64h+EVdg1@8GyPGd zkN*B}qZ{fq#*WqW3T^th6hoZv@S2s&9Myq&2uexXZy)*|q|Y2q?1CBTtH5^&UjFgu z#cvTHsQ7N&W^Vi+EjS_rpz)UOxiZI(BK-B>@OvOQ$yqx5avaso?!kP@^r5;H5!!P$ zCzfv2XD%$CMF(w{5i;7;?1lQzFFe6Q*3vi;jz`E1_gaz~)O?D4770{s?`_j4Jmh#3gmDRFvrW?r246BEZwjv;VfIVC2YVPPvXXol-Fq5 zK~O<=9fUJBL>)EAleChlN~S^ElGvj^+1}2j=yP?8xFlL9R%s;h z2v1!QUrJt#;p)Pd(`mGEW?{VWSwBs923W1pKR$QF$ymd7T?sVbfFY;V)i>LOA7*$N zAb_$x$|!xe{M!w`KUP;vZq5}@t~4QJ5_b)mYA(qFLaL6y#YaJuew2!{PwNQ8C>4~V z=efnEsOkQfKd4+NTBB!CEKr}}xXBmf#j+m#2y``KA8%|}2-joXpi2}Zl- zkHp_Ru+l4DBa@Hx{9#L}msmM*kqn|x`UN8)FKHV$5*hqI4mSz~A9Bp^a^WBZOi!A| zo>QG=X$xUDTx_|Sjf~EH62G8vv{M(i`Pk>FBgC>?>xt=E91rKYSHY@P5B-t0>W#Q9 zGQ`FsjFZ5!6dREQp$Of6!6aVAJyZZ7uh3sPl0f2_$h})Bx?LwOg7ah_t(eNnNns8T zCC9rmZ6Ns_FKD7C zKHXgjK=EBG=TJk`N)kcN;18xnTfM5Q(q0XhN=b2M~Pf`62I=6X>JzQ_Q{OIjj6j9C|`$ireF+CzXMWwLo z?8`0CdKI?ZD{lM3H^%jEnDIrM#O0n~+P*U3ebADN*hUkSx77j*bhW0!4hS&x)lb*n_m)$ctff97nz~@}8M!AQMDV z;`Pi`$v|bBs%cS5)b6)c^v0h-XHnA`EXZ7JFeQ@-Ymn_No$MoaV!tj(LJz1@+g;PT zEtB}WPU&!7p-@JN=U6I`Lm@SD{#b9=w3|LVr~GJE)3rl-BckS^76)n9t~$qx&I`;~ z{N_A9o~mRuZI8q+=c==%;uw`O9+BEphM1l6X`@o^wsj;vzpQb91f;Ol( zd<*8i1L3|2=ClGhXBGhj?9luV4#e;AYQMV?QA*l!bDvOn*K5wi{EQ#uLG@7sjTOpE z?}3Rz&BRq1H3E8D^j#If+fR#6k+w@Ntac*cQ%gZ5=1hGPFJ(XLX^>pz&8Dq-P6Oh0 z0TQ)<*!9%D1eSV=@>FqRe*w$1ezO1n^QL~0?SeYk0&X_lY;aaYqssch-q_70~$tYgy=n^Ya`P*sU#+# zrQ95$^Mfu`!0JTWB?oay^)FMRR=8Ys8k`e|+TykK_o*BMc|v+qTL?oX@{G8HZ8$0| z96Al4Ur-&jbhH~SSxr<(=OovWn?+9J!S7UyfWX#+E*lb28k2Zc-S7P8`|-*Ope+)) zsm#%MJ;>am=U^*T(QyhCc9TnTOYGRBxMGclDcgK6rED13l|LnSs>IT*!j<&pK#jU= z;T$C(NeIDvpgLvMYTMy7(^6U<3d;gCR#0HGoV3|wY#0(~F7LlTLEqI;5CcuBS)c9G zu8!N*(q@}3xNLOeB-GE;hKFF8FjVC7OOx+EX!c(Vum2DzmMV++G&|i)HGhHe3k!`T zZ{`jAoH8-#Mn;DaepN0e_$-pz<->WhdC~Tm0u8%vP;O#n^!FZ3a8#d!u8KbG^7&3{ ztvp`}DSiw%>96AFbX+3eqBu@R9W?3XjXo-@059+GCGHRsSw4mOh@3R!c*m(e==xI` zD9?&<(~b<2UO(M~wBi_?2CB~v+J>IzpCW`cWqytMF};I6@G+Js55LdukphSJ6Pds6 zx7$*tpROmQ(YZQQH-{w80zc(@ z@ed1O@MBe@a7pTdFvwOEhF&BY830}(a+|dn!(bAwoGv*z2zGN|_qXJO``Ssk^D9=B z&aObamu_xJtbS{@?)uBFF!Hcg!W;+DvOARGMOft9J2Fu%mmxtfKu9kPAf%V;Z^np& zt%b3n)Bi$;oE0x6*Y^n}Xc`Pu*o$AjKmVi$G#$fvmslZ^I-dmNPKZ01(K-Yc1nNyv zjg0O$8Qfiza>ga$U7E9_OwP?~z#`I)ixT7>{FUjToc`flES~1CJwVP5TZ2|-J45Nj~!PpgVt5A z{J2-dbEs+Wb14J91lcrNDg_f8Iyg(K-`ty;dCe{g1_wr2RNeH5PTXo7F5^}SAEq5n z#T=3@O5d-MCL%9@M$p1l)u(5p2|qGPK=y7v-1&|}fi73t-VeA4k|<4BOnW(7AS)%;=bdqR-N z%@N831~f96e@(wlX0~or!c4G89sA90C*Vxy((-K(IG%@D%T~2>=|ufd=Hj~@YauvqwiL!cgiYn| z)MKSlAtyOL(SOQTF@=((+BdBGXpBnj7%)c7*abZgdPZVb+;!dfg{?a;joyhCY?3CQ zyUYymlP+Hqx}4AQMDy((yDa=$zZyV42?($h{y%l~fARSP0zUqk%YW}ZgFhrBBmhDH zaQ#s*0JjFt=2k|u4#tMY=5|hhRt1ovrJ9XHJjTsyekpcnvGTya= z2B`VlW64Vae?a-|?oa3dEBm_=PUCN1pKiY;Q9^rk3tE! z{eP>;2*^r^iYO`5$%wv3_^rmj8wLa|{;6aE?thah_@^2G{-HmW-hb8jm$1P;Ww3A6od` zUwaSd?kAm}2Y?v^T)&ZI|526!=Kc?Gfaf)JFm`m52B^Io+x%OA;ypa2M`3>lpew^* zf6s;Z1AY|qZ{YzH+*Zzx04^C(b1P#3Lqk9dGWs_9rvI&htlLpg4?u?p13LUSMZiDG z0>R%lAm*SCP)}6>Fjb1%S{qB-+FCl>{e9PvZ4aY80Bo)U&=G(bvOkp!fUW#Z*ZdBx z1~5E;QtNNF_xHGuI~e=r0JK%WMf4|BAfPq6zr~gKx7GbU9``Cak1xQw*b(024blHS zo{giEzLnK~v*BOHH&%3jX~l>d2#DY>&ldzp@%x+q8^8ec8{XeP-9eLe z{$J28rT!L8+Sc^HzU@GBexQ25pjQQWVH|$}%aZ+DFnNG>i-4n}v9$p}F_%Qz)==L{ z7+|mt<_6Ax@Vvh_+V^tze>7Ai|Nq^}-*>}%o!>t&fzO6ZBt23g4r?*WLL8)z|!gQsH?I_!|Jg%KoqXrnK`% z*#H3k$!LFz{d`~fz3$E*mEkP@qw>F{PyV|*_#XbfmdYRSsaF3L{(o6Yyl?2e;=vyc zeYXFPhW_;Y|3&}cJ^Xv>{y*R^9sUXaowxiR_B~_$AFv8e{{;KzZHV`n?^%ogz|8ab zC(PdyGydDm_?{p5|Ec8cRTBuJD7=ktkw-{nV;#0k5o;S?!9D>&LLkM0AP6Feg`f{0 zDQpB`k<`JrvB<<-J;OKd%+1!z`DQP}{M_XnsTQvW)#kKd4xjO+0(FK~P*t8f?34gT zNeb{dG5{jMk|Z%xPNd?)Kr$uFk;z0bG4oFYGnNlV6q8Vd`WhQhkz5p#m^vZSc48n^ z)8XlE1_e=c^$WG1no(|j8Tc`PgwP}{$Z2MV1V$=SXvP)gXKtqW)?5PUcJu&?e*#h! zqs>gH(jDQk$9cz8;-w$cc*dE1}qLepfsBCXA@(bAJ66ft0aCq$Wrcq)WXX{0nm+#w=uBj1o9rLyA i;x|p)^~-yfPOPa3(|vBayXKz \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/SpringBootTakaoBot/gradlew.bat b/SpringBootTakaoBot/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/SpringBootTakaoBot/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/SpringBootTakaoBot/settings.gradle b/SpringBootTakaoBot/settings.gradle new file mode 100644 index 0000000..063ca14 --- /dev/null +++ b/SpringBootTakaoBot/settings.gradle @@ -0,0 +1,6 @@ +pluginManagement { + repositories { + gradlePluginPortal() + } +} +rootProject.name = 'SpringBootTakaoBot' diff --git a/SpringBootTakaoBot/src/main/META-INF/MANIFEST.MF b/SpringBootTakaoBot/src/main/META-INF/MANIFEST.MF new file mode 100644 index 0000000..42677c6 --- /dev/null +++ b/SpringBootTakaoBot/src/main/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: it.discordbot.StartBotKt + diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/StartBot.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/StartBot.kt new file mode 100644 index 0000000..633892b --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/StartBot.kt @@ -0,0 +1,13 @@ +package it.discordbot + +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication +import org.springframework.scheduling.annotation.EnableScheduling + +@SpringBootApplication +@EnableScheduling +class StartBot + +fun main(args: Array) { + runApplication(*args) +} diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/TestCommand.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/TestCommand.kt new file mode 100644 index 0000000..3878b77 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/TestCommand.kt @@ -0,0 +1,25 @@ +package it.discordbot + +import it.discordbot.database.interfaces.BDONewsInterface +import net.dv8tion.jda.bot.entities.ApplicationInfo +import net.dv8tion.jda.core.events.message.MessageReceivedEvent +import net.dv8tion.jda.core.hooks.ListenerAdapter +import net.dv8tion.jda.core.requests.RestAction +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component + +@Component +class TestCommand : ListenerAdapter() { + + @Autowired + lateinit var bdoNewsInterface:BDONewsInterface + + override fun onMessageReceived(event: MessageReceivedEvent?) { + if(event!!.author.isBot) return + + if (event.message.contentRaw == "!test") { + + } + + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSLink.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSLink.kt new file mode 100644 index 0000000..562bd61 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSLink.kt @@ -0,0 +1,30 @@ +package it.discordbot.beans + +import javax.persistence.Column +import javax.persistence.Entity +import javax.persistence.Id +import javax.persistence.Table + +@Entity +@Table(name = "`RSSLink`") +class RSSLink { + @Id + @Column(name = "`id`") + var id: Long = 0 + /** + * Lista link ultime news di BDO + */ + @Column(name = "`LastNewsBDO`") + var lastNewsBDO: String? = null + + /** + * Link ultima patch di BDO + */ + @Column(name = "`LastPatchBDO`") + var lastPatchBDO: String? = null + /** + * Link ultimo feed di atm + */ + @Column(name = "`LastATMAlert`") + var lastAtmAlert: String? = null +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSMessage.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSMessage.kt new file mode 100644 index 0000000..e2e329b --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSMessage.kt @@ -0,0 +1,5 @@ +package it.discordbot.beans + +import org.jsoup.nodes.Document + +data class RSSMessage(val title:String,val link:String,val doc: Document) \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt new file mode 100644 index 0000000..f053634 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt @@ -0,0 +1,61 @@ +package it.discordbot.beans + +import org.apache.commons.text.StringEscapeUtils +import javax.persistence.Column +import javax.persistence.Entity +import javax.persistence.Id +import javax.persistence.Table + +@Entity +@Table(name = "`ServersDiscord`") +class ServerDiscord { + /** + * Id del server + */ + @Id + @Column(name = "`SERVER_ID`") + var serverId: String? = null + + /** + * Nome del server + */ + @Column(name = "`NAME_SERVER`") + var nameServer: String? = null + + /** + * Simbolo di comando + */ + + @Column(name = "`SIMBOL_COMMAND`") + var simbolCommand: String? = "" + get() = StringEscapeUtils.unescapeJava(field) + set(value) { + field = StringEscapeUtils.escapeJava(value) + } + + + /** + * ID Canale per invio news di BDO + */ + @Column(name = "`BDONewsIDChannel`") + var bdoNewsIDChannel: String? = null + + /** + * ID Canale per invio patch di BDO + */ + @Column(name = "`BDOPatchIDChannel`") + var bdoPatchIDChannel: String? = null + + /** + * ID Canale per invio alert boss di BDO + */ + @Column(name = "`BDOBossIDChannel`") + var bdoBossIDChannel: String? = null + + /** + * ID Canale per invio degli alert dell'ATM + */ + @Column(name = "`ATMAlertIDChannel`") + var atmAlertIDChannel: String? = null + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt new file mode 100644 index 0000000..e6f65ab --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt @@ -0,0 +1,17 @@ +package it.discordbot.beans + + +data class ServerToChannel(val serverID: String, val channelID: String) { + override fun equals(other: Any?): Boolean { + return if (other != null) { + if (other is ServerToChannel) { + other.serverID == this.serverID + } else { + false + } + } else { + false + } + + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Boss.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Boss.kt new file mode 100644 index 0000000..6e3c447 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Boss.kt @@ -0,0 +1,3 @@ +package it.discordbot.beans.boss + +data class Boss(val ora: String, val nomeBoss: Array) \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt new file mode 100644 index 0000000..95df846 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt @@ -0,0 +1,3 @@ +package it.discordbot.beans.boss + + data class Giorno(val giorno: String, val bosses: ArrayList) \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt new file mode 100644 index 0000000..2af0487 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt @@ -0,0 +1,130 @@ +package it.discordbot.command.BDO + +import it.discordbot.command.checkAdminPermission +import it.discordbot.command.checkCommand +import it.discordbot.command.rejectCommand +import it.discordbot.database.interfaces.BDOBossInterface +import it.discordbot.database.interfaces.BDONewsInterface +import it.discordbot.database.interfaces.BDOPatchInterface +import it.discordbot.database.interfaces.ServerManagementInterface +import net.dv8tion.jda.core.MessageBuilder +import net.dv8tion.jda.core.events.message.MessageReceivedEvent +import net.dv8tion.jda.core.hooks.ListenerAdapter +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Service + +@Scope("singleton") +@Service +class BDOCommand : ListenerAdapter() { + + @Autowired + lateinit var serverManagementInterface: ServerManagementInterface + + @Autowired + lateinit var bdoNewsInterface: BDONewsInterface + + @Autowired + lateinit var bdoPatchInterface: BDOPatchInterface + + @Autowired + lateinit var bdoBossInterface: BDOBossInterface + + companion object { + + const val BDO_BOSS_START_COMMAND = "BDOBossStart" + + const val BDO_BOSS_START_COMMAND_DESCRIPTION = "Questo comando permette di iscriversi agli allarmi dei boss di BDO. \n" + "Il comando deve essere lanciato sul canale su cui si desidera ricevere i boss" + + const val BDO_BOSS_STOP_COMMAND = "BDOBossStop" + + const val BDO_BOSS_STOP_COMMAND_DESCRIPTION = "Questo comando permette disiscriversi agli allarmi dei boss di BDO. \n" + "Il comando può essere lanciato su qualunque canale" + + const val BDO_NEWS_START_COMMAND = "BDONewsStart" + + const val BDO_NEWS_START_COMMAND_DESCRIPTION = "Questo comando permette di iscriversi al feed delle news di BDO. \n" + "Il comando deve essere lanciato sul canale su cui si desidera ricevere le news" + + const val BDO_NEWS_STOP_COMMAND = "BDONewsStop" + + const val BDO_NEWS_STOP_COMMAND_DESCRIPTION = "Questo comando permette disiscriversi al feed delle news di BDO. \n" + "Il comando può essere lanciato su qualunque canale" + + const val BDO_PATCH_START_COMMAND = "BDOPatchStart" + + const val BDO_PATCH_START_COMMAND_DESCRIPTION = "Questo comando permette di iscriversi al feed delle patch di BDO. \n" + "Il comando deve essere lanciato sul canale su cui si desidera ricevere le patch" + + const val BDO_PATCH_STOP_COMMAND = "BDOPatchStop" + + const val BDO_PATCH_STOP_COMMAND_DESCRIPTION = "Comando per disiscriversi al feed delle patch di BDO. \n" + "Il comando può essere lanciato su qualunque canale" + + } + + override fun onMessageReceived(event: MessageReceivedEvent?) { + if (event!!.author.isBot) return + + val symbolCommand = serverManagementInterface.getSimbolCommand(event.guild.id) + + if (checkCommand(event, symbolCommand, BDOCommand.BDO_BOSS_START_COMMAND)) { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + bdoBossInterface.setBDOBossChannel(event.guild.id, event.textChannel.id) + sendMessageAddChannel(event, "Invio degli allarmi dei boss di BDO configurato sul canale: ") + } + } else if (checkCommand(event, symbolCommand, BDOCommand.BDO_BOSS_STOP_COMMAND)) { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + val removedChannelId = bdoBossInterface.removeBDOBossChannel(event.guild.id) + if (removedChannelId != null) + sendMessageRemoveChannel(event, "Invio degli allarmi dei boss di BDO rimosso dal canale: ", removedChannelId) + } + } else if (checkCommand(event, symbolCommand, BDOCommand.BDO_NEWS_START_COMMAND)) { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + bdoNewsInterface.setBDONewsChannel(event.guild.id, event.textChannel.id) + sendMessageAddChannel(event, "Invio delle news di BDO configurato sul canale: ") + } + } else if (checkCommand(event, symbolCommand, BDOCommand.BDO_NEWS_STOP_COMMAND)) { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + val removedChannelId = bdoNewsInterface.removeBDONewsChannel(event.guild.id) + if (removedChannelId != null) + sendMessageRemoveChannel(event, "Invio delle news di BDO rimosso dal canale: ", removedChannelId) + } + } else if (checkCommand(event, symbolCommand, BDOCommand.BDO_PATCH_START_COMMAND)) { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + bdoPatchInterface.setBDOPatchChannel(event.guild.id, event.textChannel.id) + sendMessageAddChannel(event, "Invio delle patch di BDO configurato sul canale: ") + } + } else if (checkCommand(event, symbolCommand, BDOCommand.BDO_PATCH_STOP_COMMAND)) { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + val removedChannelId = bdoPatchInterface.removeBDOPatchChannel(event.guild.id) + if (removedChannelId != null) + sendMessageRemoveChannel(event, "Invio delle patch di BDO rimosso dal canale: ", removedChannelId) + } + } + + } + + private fun sendMessageAddChannel(event: MessageReceivedEvent, message: String) { + MessageBuilder().apply { + append(message) + appendCodeBlock(event.textChannel.name, "") + }.sendTo(event.textChannel).queue() + } + + private fun sendMessageRemoveChannel(event: MessageReceivedEvent, message: String, channelID: String) { + MessageBuilder().apply { + append(message) + appendCodeBlock(event.jda.getTextChannelById(channelID).name, "") + }.sendTo(event.textChannel).queue() + } + + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt new file mode 100644 index 0000000..d634d59 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt @@ -0,0 +1,54 @@ +package it.discordbot.command.BDO.RSS + +import it.discordbot.beans.RSSMessage +import it.discordbot.beans.ServerToChannel +import it.discordbot.core.JDAController +import it.discordbot.database.interfaces.BDONewsInterface +import net.dv8tion.jda.core.entities.MessageEmbed +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.stereotype.Service +import java.util.* + +@Service +class BDONewsRSSScheduler { + + @Autowired + lateinit var bdorssReader: BDORSSReader + + @Autowired + lateinit var bdoNewsInterface: BDONewsInterface + + + @Scheduled(fixedRate = 1800000, initialDelay = 1800000) + fun taskFeedRSSBDONews() { + val rssNewsMessage = bdorssReader.readRSS("https://community.blackdesertonline.com/index.php?forums/news-announcements.181/index.rss") + + var newsBDOList = bdoNewsInterface.getBDONewsList() + if (newsBDOList.size != 0) { + if (newsBDOList.indexOf(rssNewsMessage.link) == -1) { + procedurePublish(rssNewsMessage, newsBDOList) + } + } else { + newsBDOList = ArrayList() + procedurePublish(rssNewsMessage, newsBDOList) + } + } + + private fun procedurePublish(rssNewsMessage: RSSMessage, newsBDOList: ArrayList) { + val newsMessage = bdorssReader.prepareRSStoEmbeddedMessage(rssNewsMessage) //ottieni il messaggio embedded + val listNewsChannel = bdoNewsInterface.getBDONewsChannels() //ottieni la delle ultime news già pubblicate + publishMessage(newsMessage, listNewsChannel) //publish del messaggio + newsBDOList.add(rssNewsMessage.link) //aggiunta dell'ultima news alla lista + bdoNewsInterface.setBDONewsList(newsBDOList) //salvataggio su db + } + + private fun publishMessage(newsMessage: MessageEmbed, servers: ArrayList) { + for (obj in servers) { + JDAController.jda.getGuildById(obj.serverID) + .getTextChannelById(obj.channelID) + .sendMessage(newsMessage).queue() + } + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt new file mode 100644 index 0000000..611c2ae --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt @@ -0,0 +1,64 @@ +package it.discordbot.command.BDO.RSS + +import it.discordbot.beans.ServerToChannel +import it.discordbot.core.JDAController +import it.discordbot.database.interfaces.BDOPatchInterface +import net.dv8tion.jda.core.entities.MessageEmbed +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.stereotype.Service +import java.util.* + +@Service +class BDOPatchRSSScheduler { + + @Autowired + lateinit var bdorssReader: BDORSSReader + + @Autowired + lateinit var bdoPatchInterface: BDOPatchInterface + + + @Scheduled(fixedRate = 1800000, initialDelay = 1800000) + fun taskFeedRSSBDOPatch() { + /*val rssNewsMessage = bdorssReader.readRSS("https://community.blackdesertonline.com/index.php?forums/news-announcements.181/index.rss") + + var newsBDOList = bdoNewsInterface.getBDONewsList() + if (newsBDOList.indexOf(rssNewsMessage.link) == -1) { + procedurePublish(rssNewsMessage, newsBDOList) + }else{ + newsBDOList = ArrayList() + procedurePublish(rssNewsMessage, newsBDOList) + }*/ + + + val rssPatchMessage = bdorssReader.readRSS("https://community.blackdesertonline.com/index.php?forums/patch-notes.5/index.rss") + val lastPatch = bdoPatchInterface.getBDOPatchList() + + val message = bdorssReader.prepareRSStoEmbeddedMessage(rssPatchMessage) + val listPatchChannel = bdoPatchInterface.getBDOPatchChannels() + if (rssPatchMessage.link != lastPatch) { + publishMessage(message, listPatchChannel) + bdoPatchInterface.setLastPatch(rssPatchMessage.link) + } + + + } + + /*private fun procedurePublish(rssNewsMessage: RSSMessage, newsBDOList: ArrayList) { + val newsMessage = bdorssReader.prepareRSStoEmbeddedMessage(rssNewsMessage) //ottieni il messaggio embedded + val listNews = bdoNewsInterface.getBDONewsChannels() //ottieni la delle ultime news già pubblicate + publishMessage(newsMessage, listNews) //publish del messaggio + newsBDOList.add(rssNewsMessage.link) //aggiunta dell'ultima news alla lista + bdoNewsInterface.setBDONewsList(newsBDOList) //salvataggio su db + }*/ + + private fun publishMessage(patchMessage: MessageEmbed, servers: ArrayList) { + for (obj in servers) { + JDAController.jda.getGuildById(obj.serverID) + .getTextChannelById(obj.channelID) + .sendMessage(patchMessage).queue() + } + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt new file mode 100644 index 0000000..669fd45 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt @@ -0,0 +1,64 @@ +package it.discordbot.command.BDO.RSS + +import com.rometools.rome.io.SyndFeedInput +import com.rometools.rome.io.XmlReader +import it.discordbot.beans.RSSMessage +import net.dv8tion.jda.core.EmbedBuilder +import net.dv8tion.jda.core.entities.MessageEmbed +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component +import java.awt.Color +import java.net.URL + +@Scope("singleton") +@Component +class BDORSSReader { + + /** + * Metodo per leggere un feed RSS + * @param url Url da cui bisogna leggere il feed + * @return Ultimo feed registrato + */ + fun readRSS(url: String): RSSMessage { + + var title: String + var link: String + var doc: Document + + SyndFeedInput().apply { + build(XmlReader(URL(url))).apply { + entries.first().apply { + title = getTitle() + link = getLink() + doc = Jsoup.parse(contents.first().value) + } + } + } + return RSSMessage(title, link, doc) + } + + fun prepareRSStoEmbeddedMessage(message: RSSMessage): MessageEmbed { + val body = Jsoup.parse(message.doc.toString().replace("(?i)]*>", "br2n")) + .text() + .replace("br2n".toRegex(), "\n") + if (!message.doc.select("img").isEmpty()) { + //esite 1 immagine + val imageUrl = message.doc.select("img")[0].attr("src") + return EmbedBuilder().apply { + setTitle(message.title, message.link) + setDescription(body) + setColor(Color(131, 196, 250)) + setImage(imageUrl) + }.build() + } else { + return EmbedBuilder().apply { + setTitle(message.title, message.link) + setDescription(body) + setColor(Color(131, 196, 250)) + }.build() + } + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt new file mode 100644 index 0000000..5bb7a56 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt @@ -0,0 +1,31 @@ +package it.discordbot.command.BDO.boss + +import it.discordbot.database.interfaces.BDOBossInterface +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.stereotype.Service +import java.time.LocalDateTime +import java.time.format.TextStyle +import java.util.* + +@Scope("singleton") +@Service +class BDOBossScheduler { + + @Autowired + lateinit var bdoBossInterface: BDOBossInterface + + @Autowired + lateinit var bossUtil: BossUtil + + @Scheduled(cron = "0 0/5 * * * *") + fun bossJob() { + val time = LocalDateTime.now() + val list = bdoBossInterface.getBDOBossList() + bossUtil.getDayBosses(time.dayOfWeek.getDisplayName(TextStyle.FULL, Locale.ENGLISH), list).apply { + bossUtil.processHour(time.hour, time.minute, this) + } + + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt new file mode 100644 index 0000000..ca21b3c --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt @@ -0,0 +1,135 @@ +package it.discordbot.command.BDO.boss + +import it.discordbot.beans.boss.Boss +import it.discordbot.beans.boss.Giorno +import it.discordbot.core.JDAController +import it.discordbot.database.interfaces.BDOBossInterface +import net.dv8tion.jda.core.MessageBuilder +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component +import java.time.DayOfWeek +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter + +@Scope("singleton") +@Component +class BossUtil { + + @Autowired + lateinit var bdoBossInterface: BDOBossInterface + + fun getDayBosses(giorno: String, list: ArrayList): Giorno? { + val g = giorno.toUpperCase() + + for (bossListDay in list) { + if (bossListDay.giorno == g) { + return bossListDay + } + } + return null + } + + fun getHourBoss(ora: Int, minuto: Int, list: ArrayList?): Boss? { + val time = StringBuilder().apply { + append(ora.toString()) + append(":") + append(minuto.toString()) + }.toString() + + if (list != null) { + for (boss in list) { + if (boss.ora == time) { + return boss + } + } + } + return null + + } + + fun processHour(ora: Int, minuto: Int, giorno: Giorno?) { + + when (ora) { + 1, 2, 4, 5, 8, 9, 11, 12, 15, 16, 18, 19 -> processMinute4500(ora, minuto, giorno) + 0, 22, 23 -> processMinute0015(ora, minuto, giorno) + else -> return + } + } + + + private fun processMinute4500(ora: Int, minuto: Int, giorno: Giorno?) { + if (giorno?.giorno.equals(DayOfWeek.WEDNESDAY.name) && (ora == 11 || ora == 12)) return + + when (minuto) { + 45 -> getHourBoss(ora + 1, 0, giorno?.bosses).apply { + publish(this?.nomeBoss, "15") + } + + 50 -> getHourBoss(ora + 1, 0, giorno?.bosses).apply { + publish(this?.nomeBoss, "10") + } + + 55 -> getHourBoss(ora + 1, 0, giorno?.bosses).apply { + publish(this?.nomeBoss, "5") + } + + 0 -> getHourBoss(ora + 1, 0, giorno?.bosses).apply { + publish(this?.nomeBoss, "0") + } + } + } + + private fun processMinute0015(ora: Int, minuto: Int, giorno: Giorno?) { + if (giorno?.giorno.equals(DayOfWeek.SATURDAY.name) && ora == 22) return + + when (minuto) { + 0 -> getHourBoss(ora, 15, giorno?.bosses).apply { + publish(this?.nomeBoss, "15") + } + + 5 -> getHourBoss(ora, 15, giorno?.bosses).apply { + publish(this?.nomeBoss, "10") + } + + 10 -> getHourBoss(ora, 15, giorno?.bosses).apply { + publish(this?.nomeBoss, "5") + } + + 15 -> getHourBoss(ora, 15, giorno?.bosses).apply { + publish(this?.nomeBoss, "0") + } + } + } + + private fun publish(bosses: Array?, orarioMancante: String) { + if (bosses != null) { + val listServerChannel = bdoBossInterface.getBDOBossChannels() + + val oraAttuale = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm")) + + val message = MessageBuilder().apply { + append(oraAttuale) + append(" -> ") + for (boss in bosses) { + append(boss) + append(" ") + } + if (orarioMancante == "0") { + append("sta spawnando") + } else { + append("in arrivo tra: ") + append(orarioMancante) + append(" minuti") + } + }.build() + + for (serverChannel in listServerChannel){ + JDAController.jda.getGuildById(serverChannel.serverID) + .getTextChannelById(serverChannel.channelID) + .sendMessage(message).queue() + } + + } + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/ControlCommand.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/ControlCommand.kt new file mode 100644 index 0000000..d68dd6e --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/ControlCommand.kt @@ -0,0 +1,34 @@ +package it.discordbot.command + +import it.discordbot.database.interfaces.ServerManagementInterface +import net.dv8tion.jda.core.Permission +import net.dv8tion.jda.core.entities.ChannelType +import net.dv8tion.jda.core.events.message.MessageReceivedEvent +import org.jetbrains.annotations.NotNull + +fun checkCommand(@NotNull event: MessageReceivedEvent, + @NotNull simbolCommand: String, + @NotNull commandName: String): Boolean { + + val completeCommand = simbolCommand + commandName.toLowerCase() + + return if (!event.isFromType(ChannelType.PRIVATE)) { + if (event.message.contentRaw == completeCommand || + event.message.isMentioned(event.jda.selfUser) && + event.message.contentRaw.contains(commandName)) { + true + } else { + false + } + } else { + false + } +} + +fun checkAdminPermission(event: MessageReceivedEvent): Boolean { + return event.guild.getMember(event.author).hasPermission(Permission.ADMINISTRATOR) +} + +fun rejectCommand(event: MessageReceivedEvent) { + event.textChannel.sendMessage(event.author.name + " non sei autorizzato all'uso di questo comando").queue() +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt new file mode 100644 index 0000000..400e649 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt @@ -0,0 +1,150 @@ +package it.discordbot.command.generalCommand + +import it.discordbot.command.BDO.BDOCommand +import it.discordbot.command.checkAdminPermission +import it.discordbot.command.checkCommand +import it.discordbot.command.rejectCommand +import it.discordbot.core.JDAController +import it.discordbot.database.interfaces.ServerManagementInterface +import net.dv8tion.jda.core.EmbedBuilder +import net.dv8tion.jda.core.MessageBuilder +import net.dv8tion.jda.core.entities.ChannelType +import net.dv8tion.jda.core.entities.MessageEmbed +import net.dv8tion.jda.core.events.message.MessageReceivedEvent +import net.dv8tion.jda.core.hooks.ListenerAdapter +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Service +import java.awt.Color +import java.util.* + + +@Scope(value = "singleton") +@Service +class GeneralCommand : ListenerAdapter() { + + @Autowired + lateinit var serverManagementInterface: ServerManagementInterface + + companion object { + + const val CONFIGURATION_COMMAND = "configurationCommand" + + const val CONFIGURATION_COMMAND_DESCRIPTION = "Questo comando permette la configurazione del prefisso per i comandi \n" + "Questo comando è riservato al solo utilizzo da parte del proprietario del server." + + const val HELP_COMMAND = "help" + + const val INFO_COMMAND = "info" + + const val INFO_COMMAND_DESCRIPTION = "Info del bot." + + + } + + + override fun onMessageReceived(event: MessageReceivedEvent?) { + + if (event!!.author.isBot) return + if (event.isFromType(ChannelType.PRIVATE)) return + + val symbolCommand = serverManagementInterface.getSimbolCommand(event.guild.id) + + if (checkCommand(event, symbolCommand, CONFIGURATION_COMMAND)) { + getConfigurationCommand(event) + } + + if (checkCommand(event, symbolCommand, HELP_COMMAND)) { + event.author.openPrivateChannel().queue { + it.sendMessage(getHelp(event.guild.id)).queue() + } + } + + if (checkCommand(event, symbolCommand, INFO_COMMAND)) { + event.author.openPrivateChannel().queue { + it.sendMessage(getInfo()).queue() + } + } + + } + + private fun getHelp(serverID: String): MessageEmbed { + + val symbolCommand = serverManagementInterface.getSimbolCommand(serverID) + + return EmbedBuilder().apply { + setTitle("Lista Comandi") + setColor(Color(132, 197, 251)) + setDescription("Questi comandi possono essere usati menzionando il bot e scrivendo il comando senza simbolo," + + "oppure usando i comandi direttamente come segue:") + addField(symbolCommand + GeneralCommand.INFO_COMMAND, GeneralCommand.INFO_COMMAND_DESCRIPTION, false) + addField(symbolCommand + GeneralCommand.CONFIGURATION_COMMAND, GeneralCommand.CONFIGURATION_COMMAND_DESCRIPTION, false) + addField(symbolCommand + BDOCommand.BDO_NEWS_START_COMMAND, BDOCommand.BDO_NEWS_START_COMMAND_DESCRIPTION, false) + addField(symbolCommand + BDOCommand.BDO_NEWS_STOP_COMMAND, BDOCommand.BDO_NEWS_STOP_COMMAND_DESCRIPTION, false) + addField(symbolCommand + BDOCommand.BDO_PATCH_START_COMMAND, BDOCommand.BDO_PATCH_START_COMMAND_DESCRIPTION, false) + addField(symbolCommand + BDOCommand.BDO_PATCH_STOP_COMMAND, BDOCommand.BDO_PATCH_STOP_COMMAND_DESCRIPTION, false) + addField(symbolCommand + BDOCommand.BDO_BOSS_START_COMMAND, BDOCommand.BDO_BOSS_START_COMMAND_DESCRIPTION, false) + addField(symbolCommand + BDOCommand.BDO_BOSS_STOP_COMMAND, BDOCommand.BDO_BOSS_STOP_COMMAND_DESCRIPTION, false) + }.build() + } + + private fun getInfo(): MessageEmbed { + + val info = "Ciao, sono samuele794#8585 lo sviluppatore di questo bot, scritto Java 8 con l'utilizzo " + + "della libreria di base JDA (Java Discord Api). \n\n" + + "Il personaggio Takao di Arpeggio Of Blue Steel (\u84bc\u304d\u92fc\u306e\u30a2\u30eb\u30da\u30b8\u30aa, Aoki Hagane no Arpeggio) " + + "è stato creato da Ark Performance. \nNon sono il possessore di nessuna immagine " + + "utilizzata all'interno del bot. \n\n" + + "Se sei uno sviluppatore Java e vuoi contribuire al bot sei ben accetto. \n" + + "Link GitHub: https://github.com/samuele794/TakaoBot \n\n" + + "Usando questo bot accetti il fatto che conserverò l'uso dei comandi per fini della manutenzione del bot \n\n" + + "Link utili: \n" + + "- Sito web: https://samuele794.github.io/TakaoBot/" + + val avatarUrl = JDAController.jda.getUserById("186582756841488385").avatarUrl + + return EmbedBuilder().apply { + setImage("https://samuele794.github.io/TakaoBot/images/Copertina.png") + setThumbnail(avatarUrl) + setDescription(info) + setColor(Color(131, 196, 250)) + }.build() + } + + //configurationCommand + private fun getConfigurationCommand(event: MessageReceivedEvent) { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + val tokenizer = StringTokenizer(event.message.contentRaw) + if (event.message.isMentioned(event.jda.selfUser)) { + if (tokenizer.countTokens() == 3) { + configureSymbol(event) + } else { + event.textChannel.sendMessage("Quantità di parametri non conformi").queue() + } + } else { + if (tokenizer.countTokens() == 2) { + configureSymbol(event) + } else { + event.textChannel.sendMessage("Quantità di parametri non conformi").queue() + } + } + } + } + + private fun configureSymbol(event: MessageReceivedEvent) { + if (!(event.message.contentRaw.contains("\"") or event.message.contentRaw.contains("\\") or + event.message.contentRaw.contains("'"))) { + + val listMessage = event.message.contentRaw.split(" ") + val newCommand = listMessage[listMessage.size - 1] + serverManagementInterface.setSimbolCommand(event.guild.id, newCommand) + + MessageBuilder().append("Simbolo di comando configurato. Nuovo simbolo di comando: ") + .appendCodeBlock(serverManagementInterface.getSimbolCommand(event.guild.id), "").sendTo(event.textChannel).queue() + } else { + MessageBuilder().append("Simbolo di comando non conforme").sendTo(event.textChannel).queue() + } + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt new file mode 100644 index 0000000..1ef686e --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt @@ -0,0 +1,32 @@ +package it.discordbot.command.generalCommand + +import it.discordbot.core.TakaoLog +import it.discordbot.database.interfaces.ServerManagementInterface +import net.dv8tion.jda.core.events.guild.GuildJoinEvent +import net.dv8tion.jda.core.events.guild.GuildLeaveEvent +import net.dv8tion.jda.core.events.guild.update.GuildUpdateNameEvent +import net.dv8tion.jda.core.hooks.ListenerAdapter +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Service + +@Scope("singleton") +@Service +class JoinListener : ListenerAdapter() { + + @Autowired + lateinit var serverManagementInterface: ServerManagementInterface + + override fun onGuildJoin(event: GuildJoinEvent?) { + serverManagementInterface.newServer(event!!.guild.id, event.guild.name) + TakaoLog.logInfo("REGISTRAZIONE SERVER \nID = " + event.guild.id + "\nNOME = " + event.guild.name) + } + + override fun onGuildLeave(event: GuildLeaveEvent?) { + serverManagementInterface.deleteServer(event!!.guild.id) + } + + override fun onGuildUpdateName(event: GuildUpdateNameEvent) { + event.newName + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt new file mode 100644 index 0000000..068f4c1 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt @@ -0,0 +1,70 @@ +package it.discordbot.command.music + +import it.discordbot.command.checkCommand +import it.discordbot.command.music.config.MusicManager +import it.discordbot.database.interfaces.ServerManagementInterface +import net.dv8tion.jda.core.events.message.MessageReceivedEvent +import net.dv8tion.jda.core.hooks.ListenerAdapter +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Service + +@Scope("singleton") +@Service +class MusicCommand : ListenerAdapter() { + + @Autowired + lateinit var serverManagementInterface: ServerManagementInterface + + @Autowired + lateinit var musicManager: MusicManager + + override fun onMessageReceived(event: MessageReceivedEvent?) { + if (event!!.author.isBot) return + + val symbolCommand = serverManagementInterface.getSimbolCommand(event.guild.id) + + if (checkCommand(event, symbolCommand, "leave")) { + musicManager.leave(event) + + } else if (checkCommand(event, symbolCommand, "play")) { + musicManager.play(event) + + } else if (checkCommand(event, symbolCommand, "playPlaylist") + || checkCommand(event, symbolCommand, "pp")) { + musicManager.playPlaylist(event) + + } else if (checkCommand(event, symbolCommand, "pausa") || + checkCommand(event, symbolCommand, "pause") || + checkCommand(event, symbolCommand, "resume") || + checkCommand(event, symbolCommand, "riprendi")) { + musicManager.pauseResume(event) + + } else if (checkCommand(event, symbolCommand, "stop")) { + musicManager.stop(event) + + } else if (checkCommand(event, symbolCommand, "restart")) { + musicManager.restart(event) + + } else if (checkCommand(event, symbolCommand, "repeat") || + checkCommand(event, symbolCommand, "ripeti")) { + musicManager.reset(event) + + } else if (checkCommand(event, symbolCommand, "nowplaying") || + checkCommand(event, symbolCommand, "np")) { + musicManager.nowPlay(event) + + } else if (checkCommand(event, symbolCommand, "queue") || + checkCommand(event, symbolCommand, "np")) { + musicManager.nowPlay(event) + + } else if (checkCommand(event, symbolCommand, "shuffle")) { + musicManager.shuffleQueue(event) + + } else if (checkCommand(event, symbolCommand, "clear") || + checkCommand(event, symbolCommand, "pulisci")) { + musicManager.clearQueue(event) + + } + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt new file mode 100644 index 0000000..ece1df5 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt @@ -0,0 +1,35 @@ +package it.discordbot.command.music.config + +import com.sedmelluq.discord.lavaplayer.player.AudioPlayer +import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame +import net.dv8tion.jda.core.audio.AudioSendHandler +import org.springframework.context.annotation.Bean +import org.springframework.stereotype.Component + + +class AudioPlayerSendHandler(val audioPlayer: AudioPlayer) : AudioSendHandler { + private var lastFrame: AudioFrame? = null + + override fun canProvide(): Boolean { + if (lastFrame == null) { + lastFrame = audioPlayer.provide() + } + + return lastFrame != null + } + + override fun provide20MsAudio(): ByteArray? { + if (lastFrame == null) { + lastFrame = audioPlayer.provide() + } + + val data = if (lastFrame != null) lastFrame!!.data else null + lastFrame = null + + return data + } + + override fun isOpus(): Boolean { + return true + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt new file mode 100644 index 0000000..6b80260 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt @@ -0,0 +1,22 @@ +package it.discordbot.command.music.config + +import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager +import com.sedmelluq.discord.lavaplayer.player.AudioPlayer +import org.springframework.stereotype.Component + +class GuildMusicManager(val manager: AudioPlayerManager) { + + var player: AudioPlayer + + var scheduler: TrackScheduler + + var sendHandler: AudioPlayerSendHandler + + init { + player = manager.createPlayer() + scheduler = TrackScheduler(player) + sendHandler = AudioPlayerSendHandler(player) + player.addListener(scheduler) + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt new file mode 100644 index 0000000..a3a6a1e --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt @@ -0,0 +1,443 @@ +package it.discordbot.command.music.config + +import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler +import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager +import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager +import com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager +import com.sedmelluq.discord.lavaplayer.source.local.LocalAudioSourceManager +import com.sedmelluq.discord.lavaplayer.source.soundcloud.SoundCloudAudioSourceManager +import com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager +import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager +import com.sedmelluq.discord.lavaplayer.tools.FriendlyException +import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist +import com.sedmelluq.discord.lavaplayer.track.AudioTrack +import net.dv8tion.jda.core.Permission +import net.dv8tion.jda.core.entities.MessageChannel +import net.dv8tion.jda.core.entities.VoiceChannel +import net.dv8tion.jda.core.events.message.MessageReceivedEvent +import net.dv8tion.jda.core.exceptions.PermissionException +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component +import java.util.* +import java.util.function.Consumer + +@Scope("singleton") +@Component +class MusicManager { + + private val playerManager: AudioPlayerManager + private val DEFAULT_VOLUME = 25 //(0 - 150, where 100 is default max volume) + private val musicManagers: MutableMap + + init { + playerManager = DefaultAudioPlayerManager() + playerManager.registerSourceManager(YoutubeAudioSourceManager()) + playerManager.registerSourceManager(SoundCloudAudioSourceManager()) +// playerManager.registerSourceManager(new BandcampAudioSourceManager()); +// playerManager.registerSourceManager(new VimeoAudioSourceManager()); + playerManager.registerSourceManager(TwitchStreamAudioSourceManager()) + playerManager.registerSourceManager(HttpAudioSourceManager()) + playerManager.registerSourceManager(LocalAudioSourceManager()) + + musicManagers = HashMap() + } + + /** + * Parsing del messaggio per ottenere l'url + * + * @param event + * @return String url della canzone + */ + private fun getUrl(event: MessageReceivedEvent): String { + val listMessage = Arrays.asList(*event.message.contentRaw.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) + return listMessage[listMessage.size - 1] + } + + private fun getTimestamp(milliseconds: Long): String { + val seconds = (milliseconds / 1000).toInt() % 60 + val minutes = (milliseconds / (1000 * 60) % 60).toInt() + val hours = (milliseconds / (1000 * 60 * 60) % 24).toInt() + + return if (hours > 0) + String.format("%02d:%02d:%02d", hours, minutes, seconds) + else + String.format("%02d:%02d", minutes, seconds) + } + + /** + * Metodo per eseguire il join nel canale + * + * @param event + */ + private fun join(event: MessageReceivedEvent) { + + val guild = event.guild + val guildMusicManager = getMusicManager(guild.id) + + val voiceChannel: VoiceChannel + if (event.member.voiceState.inVoiceChannel()) { + voiceChannel = event.member.voiceState.channel + guild.audioManager.sendingHandler = guildMusicManager.sendHandler + + try { + guild.audioManager.openAudioConnection(voiceChannel) + } catch (e: PermissionException) { + if (e.permission == Permission.VOICE_CONNECT) { + event.channel.sendMessage("Accesso al canale negato").queue() + } + +// TakaoLog.logError("Problemi accesso al canale " + event.channel.name + "del server" + +// event.guild.name) + } + + } else { + event.channel.sendMessage("Entra in un canale vocale, per favore").queue() + } + + } + + /** + * Metodo per far uscire il bot dalla lobby, bloccherà la queue + * e la svuoterà + * + * @param event + */ + internal fun leave(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + if (!guildMusicManager.scheduler.queue.isEmpty()) { + guildMusicManager.scheduler.queue.clear() + } + + guildMusicManager.player.stopTrack() + guildMusicManager.player.isPaused = false + guildMusicManager.player.destroy() + event.guild.audioManager.sendingHandler = null + event.guild.audioManager.closeAudioConnection() + } + + /** + * Metodo per riprodurre l'url audio passato come parametro + * @param event + */ + internal fun play(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + val guild = event.guild + if (guild.audioManager.sendingHandler == null) { + this.join(event) + } + + if (event.message.isMentioned(event.jda.selfUser)) { + + if (StringTokenizer(event.message.contentRaw).countTokens() == 3) { + //menzionato e parametri a 3 + + loadAndPlay(guildMusicManager, event.channel, getUrl(event), false) + } else { + event.channel.sendMessage("Quantità di parametri non conformi").queue() + } + } else { + if (StringTokenizer(event.message.contentRaw).countTokens() == 2) { + + loadAndPlay(guildMusicManager, event.channel, getUrl(event), false) + } else { + event.channel.sendMessage("Quantità di parametri non conformi").queue() + } + } + } + + /** + * Metodo per riprodurre una playlist dall'url passato come parametro + * @param event + */ + internal fun playPlaylist(event: MessageReceivedEvent) { + val guildMusicManager = getMusicManager(event.guild.id) + val guild = event.guild + if (guild.audioManager.sendingHandler == null) { + this.join(event) + } + + loadAndPlay(guildMusicManager, event.channel, getUrl(event), true) + } + + /** + * Metodo per saltare la traccia attualmente in riproduzione + * @param event + */ + internal fun skip(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + guildMusicManager.scheduler.nextTrack() + event.channel.sendMessage("Canzone saltata").queue() + } + + + /** + * Metodo per mettere in pausa o riprendere la traccia attualmente + * in riproduzione + * @param event + */ + internal fun pauseResume(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + val player = guildMusicManager.player + + if (player.playingTrack == null) { + event.channel.sendMessage("Non è possibile mettere in pausa o riprendere il nulla, coglione.").queue() + return + } + + player.isPaused = !player.isPaused + if (player.isPaused) + event.channel.sendMessage("Riproduzione in pausa").queue() + else + event.channel.sendMessage("Ripresa riproduzione").queue() + } + + /** + * Metodo per stoppare la riproduzione e pulire la coda + * @param event + */ + internal fun stop(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + + guildMusicManager.scheduler.queue.clear() + guildMusicManager.player.stopTrack() + guildMusicManager.player.isPaused = false + event.channel.sendMessage("Riproduzione stoppata e playlist svuotata").queue() + + } + + + /** + * Metodo per cambiare il volume, attualmente non in uso. + * Bisogno di calcolo computazionale extra per il cambio del volume. + * @param event + */ + private fun changeVolume(event: MessageReceivedEvent) { + /* if (command.length == 1) { + event.getChannel().sendMessage("Current player volume: **" + player.getVolume() + "**").queue(); + } else { + try { + int newVolume = Math.max(10, Math.min(100, Integer.parseInt(command[1]))); + int oldVolume = player.getVolume(); + player.setVolume(newVolume); + event.getChannel().sendMessage("Player volume changed from `" + oldVolume + "` to `" + newVolume + "`").queue(); + } catch (NumberFormatException e) { + event.getChannel().sendMessage("`" + command[1] + "` is not a valid integer. (10 - 100)").queue(); + } + }*/ + } + + /** + * Metodo per riavviare la traccia attualmente in riproduzione + * @param event + */ + internal fun restart(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + + var track = guildMusicManager.player.playingTrack + if (track == null) + track = guildMusicManager.scheduler.lastTrack + + if (track != null) { + event.channel.sendMessage("Riavvio traccia: " + track.info.title).queue() + guildMusicManager.player.playTrack(track.makeClone()) + } + // else { + // //Nessuna traccia è stata pre + // event.getChannel().sendMessage("No track has been previously started, so the player cannot replay a track!").queue(); + // } + } + + /** + * Metodo per ripetere la traccia attualmente in riproduzione + * @param event + */ + internal fun repeat(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + guildMusicManager.scheduler.setRepeating(!guildMusicManager.scheduler.isRepeating()) + event.channel.sendMessage("Riproduzione impostata su: **" + (if (guildMusicManager.scheduler.isRepeating()) "ripeti" else "non ripetere") + "**").queue() + + } + + /** + * Metodo per resettare il bot in caso di problemi. + * Pulisce la coda, e resetta i canali audio + * @param event + */ + internal fun reset(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + + synchronized(musicManagers) { + guildMusicManager.scheduler.queue.clear() + guildMusicManager.player.destroy() + event.guild.audioManager.sendingHandler = null + musicManagers.remove(event.guild.id) + } + + event.guild.audioManager.sendingHandler = guildMusicManager.sendHandler + event.channel.sendMessage("Riproduttore resettato").queue() + } + + /** + * Metodo per ottenere la traccia attualmente in riproduzione + * @param event + */ + internal fun nowPlay(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + + val currentTrack = guildMusicManager.player.getPlayingTrack() + if (currentTrack != null) { + val title = currentTrack.info.title + val position = getTimestamp(currentTrack.position) + val duration = getTimestamp(currentTrack.duration) + + val nowplaying = String.format("**In Riprodzione:** %s\n**Time:** [%s / %s]", + title, position, duration) + + event.channel.sendMessage(nowplaying).queue() + } else + event.channel.sendMessage("Non sto riproducendo nulla!").queue() + } + + /** + * Metodo per ottenere la lista della coda + * @param event + */ + internal fun getListQueue(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + val queue = guildMusicManager.scheduler.queue + + synchronized(queue) { + if (queue.isEmpty()) { + event.channel.sendMessage("La coda è vuota").queue() + } else { + var trackCount = 0 + var queueLength: Long = 0 + val sb = StringBuilder() + sb.append("Coda attuale: ").append(queue.size).append("\n") + for (track in queue) { + queueLength += track.duration + if (trackCount < 10) { + sb.append("`[").append(getTimestamp(track.duration)).append("]` ") + sb.append(track.info.title).append("\n") + trackCount++ + } + } + sb.append("\n").append("Tempo totale di coda: ").append(getTimestamp(queueLength)) + + event.channel.sendMessage(sb.toString()).queue() + } + } + } + + /** + * Metodo per randomizzare la coda + * @param event + */ + internal fun shuffleQueue(event: MessageReceivedEvent) { + + val guildMusicManager = getMusicManager(event.guild.id) + + if (guildMusicManager.scheduler.queue.isEmpty()) { + event.channel.sendMessage("La coda è attualmente vuota!").queue() + return + } + + guildMusicManager.scheduler.shuffle() + event.channel.sendMessage("Coda mischiata").queue() + } + + internal fun clearQueue(event: MessageReceivedEvent) { + val guildMusicManager = getMusicManager(event.guild.id) + + if (!guildMusicManager.scheduler.queue.isEmpty()) { + guildMusicManager.scheduler.queue.clear() + event.channel.sendMessage("Coda Pulita").queue() + } else { + event.channel.sendMessage("La coda è già vuota").queue() + } + + } + + /** + * Metodo per caricare una traccia o una playlist nella coda + * @param mng + * @param channel + * @param url + * @param addPlaylist + */ + private fun loadAndPlay(mng: GuildMusicManager, channel: MessageChannel, url: String, addPlaylist: Boolean) { + val trackUrl: String + + //Strip <>'s that prevent discord from embedding link resources + if (url.startsWith("<") && url.endsWith(">")) + trackUrl = url.substring(1, url.length - 1) + else + trackUrl = url + + playerManager.loadItemOrdered(mng, trackUrl, object : AudioLoadResultHandler { + override fun trackLoaded(track: AudioTrack) { + var msg = "Aggiunta alla coda: " + track.info.title + if (mng.player.playingTrack == null) + msg += "\n inizio riproduzione" + + mng.scheduler.queue(track) + channel.sendMessage(msg).queue() + } + + override fun playlistLoaded(playlist: AudioPlaylist) { + var firstTrack: AudioTrack? = playlist.selectedTrack + val tracks = playlist.tracks + + + if (firstTrack == null) { + firstTrack = playlist.tracks[0] + } + + if (addPlaylist) { + channel.sendMessage("Aggiunte **" + playlist.tracks.size + "** tracce alla coda").queue() +// tracks.forEach(Consumer { mng.scheduler.queue() }) + tracks.forEach { _ -> Consumer {mng.scheduler.queue} } + } else { + channel.sendMessage("Aggiunto alla coda " + firstTrack!!.info.title).queue() + mng.scheduler.queue(firstTrack) + } + } + + override fun noMatches() { + channel.sendMessage("Non ho abbastanza forza di vedere dentro a $trackUrl").queue() + } + + override fun loadFailed(exception: FriendlyException) { + channel.sendMessage("Non è nel mio potere: " + exception.message).queue() + } + }) + } + + private fun getMusicManager(guildId: String): GuildMusicManager { + val mng: GuildMusicManager? = musicManagers[guildId] + + if (mng == null) { + val musicMan: GuildMusicManager + synchronized(musicManagers) { + musicMan = GuildMusicManager(playerManager) + musicMan.player.volume = DEFAULT_VOLUME + musicManagers.put(guildId, musicMan) + } + return musicMan + } else { + return mng + } + } + + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt new file mode 100644 index 0000000..41b219a --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt @@ -0,0 +1,62 @@ +package it.discordbot.command.music.config + +import com.sedmelluq.discord.lavaplayer.player.AudioPlayer +import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter +import com.sedmelluq.discord.lavaplayer.track.AudioTrack +import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason +import org.springframework.stereotype.Component +import java.util.* + +class TrackScheduler(val player: AudioPlayer) : AudioEventAdapter() { + private var repeating = false + val queue: Queue = LinkedList() + var lastTrack: AudioTrack? = null + + /** + * Add the next track to queue or play right away if nothing is in the queue. + * + * @param track The track to play or add to queue. + */ + fun queue(track:AudioTrack){ + // Calling startTrack with the noInterrupt set to true will start the track only if nothing is currently playing. If + // something is playing, it returns false and does nothing. In that case the player was already playing so this + // track goes to the queue instead. + if (!player.startTrack(track, true)){ + queue.offer(track) + } + } + + /** + * Start the next track, stopping the current one if it is playing. + */ + fun nextTrack() { + // Start the next track, regardless of if something is already playing or not. In case queue was empty, we are + // giving null to startTrack, which is a valid argument and will simply stop the player. + player.startTrack(queue.poll(), false) + } + + override fun onTrackEnd(player: AudioPlayer?, track: AudioTrack?, endReason: AudioTrackEndReason) { + this.lastTrack = track + // Only start the next track if the end reason is suitable for it (FINISHED or LOAD_FAILED) + if (endReason.mayStartNext) { + if (repeating) + player!!.startTrack(lastTrack!!.makeClone(), false) + else + nextTrack() + } + + } + + fun isRepeating(): Boolean { + return repeating + } + + fun setRepeating(repeating: Boolean) { + this.repeating = repeating + } + + fun shuffle() { + Collections.shuffle(queue as List<*>) + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt new file mode 100644 index 0000000..5795f15 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt @@ -0,0 +1,66 @@ +package it.discordbot.command.tpl.atmAlert + +import it.discordbot.command.checkAdminPermission +import it.discordbot.command.checkCommand +import it.discordbot.command.rejectCommand +import it.discordbot.database.interfaces.ATMInterface +import it.discordbot.database.interfaces.ServerManagementInterface +import net.dv8tion.jda.core.MessageBuilder +import net.dv8tion.jda.core.events.message.MessageReceivedEvent +import net.dv8tion.jda.core.hooks.ListenerAdapter +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Service + +@Scope("singleton") +@Service +class ATMCommand : ListenerAdapter() { + + @Autowired + lateinit var serverManagementInterface: ServerManagementInterface + + @Autowired + lateinit var atmInterface: ATMInterface + + companion object { + const val ATM_START_COMMAND = "ATMAlertStart" + + const val ATM_START_COMMAND_DESCRIPTION = "Questo comando permette di iscriversi agli avvisi dell'ATM Milano. \n" + "Il comando deve essere lanciato sul canale su cui si desidera ricevere gli avvisi" + + const val ATM_STOP_COMMAND = "ATMAlertStop" + + const val ATM_STOP_COMMAND_DESCRIPTION = "Questo comando permette disiscriversi agli avvisi dell'ATM Milano. \n" + "Il comando può essere lanciato su qualunque canale" + + } + + override fun onMessageReceived(event: MessageReceivedEvent?) { + if (event!!.author.isBot) return + + val symbolCommand = serverManagementInterface.getSimbolCommand(event.guild.id) + + if (checkCommand(event, symbolCommand, ATM_START_COMMAND)) { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + atmInterface.setATMAlertChannel(event.guild.id, event.textChannel.id) + MessageBuilder().apply { + append("Invio degli avvisi dell'ATM configurato sul canale: ") + appendCodeBlock(event.textChannel.name, "") + }.sendTo(event.textChannel).queue() + } + } else if (checkCommand(event, symbolCommand, ATM_STOP_COMMAND)) { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + val removedChannelID = atmInterface.removeATMAlertChannel(event.guild.id) + MessageBuilder().apply { + append("Invio degli avvisi dell'ATM rimosso dal canale: ") + appendCodeBlock(event.jda.getTextChannelById(removedChannelID).name, "") + }.sendTo(event.channel).queue() + } + + } + + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt new file mode 100644 index 0000000..cfa93ea --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt @@ -0,0 +1,75 @@ +package it.discordbot.command.tpl.atmAlert + +import com.rometools.rome.io.SyndFeedInput +import com.rometools.rome.io.XmlReader +import it.discordbot.beans.RSSMessage +import net.dv8tion.jda.core.EmbedBuilder +import net.dv8tion.jda.core.entities.MessageEmbed +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component +import java.awt.Color +import java.net.URL +import java.util.regex.Pattern + +@Scope("singleton") +@Component +class ATMRSSReader { + + fun readRSS(url: String): RSSMessage { + + var title: String + var link: String + var doc: Document + + SyndFeedInput().apply { + build(XmlReader(URL(url))).let { + it.entries.last().apply { + title = getTitle() + link = getLink() + doc = Jsoup.parse(description.value) + } + } + } + return RSSMessage(title, link, doc) + } + + fun prepareRSStoEmbeddedMessage(message: RSSMessage): MessageEmbed { + var regex = Pattern.compile( + "|

|
", + Pattern.CASE_INSENSITIVE or Pattern.UNICODE_CASE or Pattern.COMMENTS) + var regexMatcher = regex.matcher(message.doc.toString()) + var mess = regexMatcher.replaceAll("br2n") + + regex = Pattern.compile( + "

|

", + Pattern.CASE_INSENSITIVE or Pattern.UNICODE_CASE or Pattern.COMMENTS) + regexMatcher = regex.matcher(mess) + mess = regexMatcher.replaceAll("") + + regex = Pattern.compile( + "|", + Pattern.CASE_INSENSITIVE or Pattern.UNICODE_CASE or Pattern.COMMENTS) + regexMatcher = regex.matcher(mess) + mess = regexMatcher.replaceAll("**") + + mess = Jsoup.parse(mess).text().replace("br2n".toRegex(), "\n") + + if (mess.length >= 2048) { + mess = StringBuilder().append(mess.subSequence(0, 2000).toString()).append("\n\n Continua nel link...").toString() + } + + return EmbedBuilder().apply { + setTitle(message.title, message.link) + setThumbnail(ATM_LOGO_RSS) + setDescription(mess) + setColor(Color(244, 131, 37)) + }.build() + + } + + companion object { + private const val ATM_LOGO_RSS = "https://i.imgur.com/2cMpNuI.png" + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt new file mode 100644 index 0000000..18bac76 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt @@ -0,0 +1,55 @@ +package it.discordbot.command.tpl.atmAlert + +import it.discordbot.beans.RSSMessage +import it.discordbot.core.JDAController +import it.discordbot.database.interfaces.ATMInterface +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.stereotype.Service + +@Scope("singleton") +@Service +class ATMRSSScheduler { + + companion object { + const val ATM_RSS_LINK = "https://www.atm.it/_layouts/atm/apps/PublishingRSS.aspx?web=388a6572-890f-4e0f-a3c7-a3dd463f7252&c=News%20Infomobilita" + } + + @Autowired + lateinit var atmrssReader: ATMRSSReader + + @Autowired + lateinit var atmInterface: ATMInterface + + @Scheduled(fixedRate = 1800000, initialDelay = 1800000) + fun taskFeedRSSATM() { + val message = atmrssReader.readRSS(ATM_RSS_LINK) + + val lastATMAlert = atmInterface.getLastATMAlert() + + if (lastATMAlert != null) { + if (lastATMAlert != message.link) { + publish(message) + atmInterface.setLastATMAlert(message.link) + } + } else { + publish(message) + atmInterface.setLastATMAlert(message.link) + } + + } + + private fun publish(message: RSSMessage) { + val serverList = atmInterface.getATMAlertChannels() + val messageEmbed = atmrssReader.prepareRSStoEmbeddedMessage(message) + for (server in serverList) { + JDAController.jda.getGuildById(server.serverID) + .getTextChannelById(server.channelID) + .sendMessage(messageEmbed) + .queue() + } + + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt new file mode 100644 index 0000000..2e7dda2 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt @@ -0,0 +1,125 @@ +package it.discordbot.command.tpl.atmAlert + +import it.discordbot.core.JDAController +import it.discordbot.core.TakaoLog +import it.discordbot.core.TwitterManager +import it.discordbot.database.interfaces.ATMInterface +import net.dv8tion.jda.core.EmbedBuilder +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Service +import twitter4j.* +import java.awt.Color +import javax.annotation.PostConstruct +import kotlin.concurrent.thread + +@Scope("singleton") +@Service +class ATMTwitterScheduler { + + @Autowired + lateinit var twitterManager: TwitterManager + + @Autowired + lateinit var atmInterface: ATMInterface + + companion object { + private const val QUERY_PARAM = "exclude:retweets exclude:replies" + private const val TWITTER_URL = "https://twitter.com/atm_informa/status/" + private const val ATM_TWITTER_ID = 988355810L + private const val TWITTER_IMAGE = "https://i.imgur.com/vkm6lHX.png" + } + + @PostConstruct + fun initATMTwitterScheduler(){ + val listener = object : StatusListener { + override fun onStatus(status: Status) { + if (status.user.id == ATM_TWITTER_ID) { + + if (!status.isRetweet) { + TakaoLog.logInfo("ATMUSERID = " + status.user.screenName + " " + status.user.id + "\nMESSAGE = " + status.text) + thread(start = true) { + val statusCopy = status + + val tweetID: Long + val tweetMessage: String + var mediaUrl: String? = null + val profileImageUrl: String + + statusCopy.apply { + tweetID = id + tweetMessage = text + profileImageUrl = user.profileImageURL + if (mediaEntities.isNotEmpty()) { + mediaUrl = mediaEntities[0].mediaURL + } + } + + publish(tweetID, tweetMessage, mediaUrl, profileImageUrl) + + } + } + } + + } + + override fun onDeletionNotice(statusDeletionNotice: StatusDeletionNotice) { + + } + + override fun onTrackLimitationNotice(numberOfLimitedStatuses: Int) { + + } + + override fun onScrubGeo(userId: Long, upToStatusId: Long) { + + } + + override fun onStallWarning(warning: StallWarning) { + + } + + override fun onException(ex: Exception) { + + } + } + var query = FilterQuery().track(QUERY_PARAM) + + query.follow(ATM_TWITTER_ID) + + twitterManager.apply { + setTwitterStreamListener(listener) + setTwitterStreamFilter(query) + } + } + + + private fun publish(tweetID: Long, twitterMessage: String, mediaUrl: String?, profileImageUrl: String) { + val tweetUrl = TWITTER_URL + tweetID + if (twitterMessage.contains("#tram") || + twitterMessage.contains("#bus") || + twitterMessage.contains("#M1") || + twitterMessage.contains("#M2") || + twitterMessage.contains("#M3") || + twitterMessage.contains("#M5") || + twitterMessage.contains("\ud83d\udea6")) { + val message = EmbedBuilder().apply { + setAuthor("ATM (@atm_informa)", tweetUrl, profileImageUrl) + setDescription(twitterMessage) + setColor(Color(244, 131, 37)) + setFooter("Ricevuto da Twitter", TWITTER_IMAGE) + if (mediaUrl != null) { + setImage(mediaUrl) + } + }.build() + + val serverList = atmInterface.getATMAlertChannels() + for (server in serverList) { + JDAController.jda.getGuildById(server.serverID) + .getTextChannelById(server.channelID) + .sendMessage(message) + .queue() + } + } + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/JDAController.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/JDAController.kt new file mode 100644 index 0000000..76b279b --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/JDAController.kt @@ -0,0 +1,60 @@ +package it.discordbot.core + +import it.discordbot.TestCommand +import it.discordbot.command.BDO.BDOCommand +import it.discordbot.command.generalCommand.GeneralCommand +import it.discordbot.command.generalCommand.JoinListener +import it.discordbot.command.music.MusicCommand +import it.discordbot.command.tpl.atmAlert.ATMCommand +import net.dv8tion.jda.core.JDA +import net.dv8tion.jda.core.JDABuilder +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component +import javax.annotation.PostConstruct + +@Scope(value = "singleton") +@Component +class JDAController { + + @Value("\${discordBot.jdaToken}") + private lateinit var jdaToken: String + + companion object { + lateinit var jda: JDA + } + + @Autowired + lateinit var testCommand: TestCommand + + @Autowired + lateinit var generalCommand: GeneralCommand + + @Autowired + lateinit var bdoCommand: BDOCommand + + @Autowired + lateinit var atmCommand: ATMCommand + + @Autowired + lateinit var musicCommand: MusicCommand + + @Autowired + lateinit var joinListener: JoinListener + + + @PostConstruct + fun init() { + jda = JDABuilder(jdaToken).build().apply { + addEventListener(joinListener) + addEventListener(testCommand) + addEventListener(generalCommand) + addEventListener(bdoCommand) + addEventListener(atmCommand) + addEventListener(musicCommand) + } + TakaoLog.logInfo("BOT AVVIATO") + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TakaoLog.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TakaoLog.kt new file mode 100644 index 0000000..7903ae6 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TakaoLog.kt @@ -0,0 +1,23 @@ +package it.discordbot.core + +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +@Component +class TakaoLog { + companion object { + private var logger = LoggerFactory.getLogger(TakaoLog::class.java) + + fun logDebug(message:String){ + logger.debug(message) + } + + fun logInfo(message: String){ + logger.info(message) + } + + fun logError(message: String){ + logger.error(message) + } + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TwitterManager.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TwitterManager.kt new file mode 100644 index 0000000..c8226f3 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TwitterManager.kt @@ -0,0 +1,59 @@ +package it.discordbot.core + +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component +import twitter4j.FilterQuery +import twitter4j.StatusListener +import twitter4j.TwitterStream +import twitter4j.TwitterStreamFactory +import twitter4j.conf.ConfigurationBuilder +import javax.annotation.PostConstruct + +@Scope("singleton") +@Component +class TwitterManager { + + @Value("\${oauth.consumerKey}") + lateinit var twitterConsumerKey: String + + @Value("\${oauth.consumerSecret}") + lateinit var twitterConsumerSecret: String + + @Value("\${oauth.accessToken}") + lateinit var twitterAccessToken: String + + @Value("\${oauth.accessTokenSecret}") + lateinit var twitterAccessTokenSecret: String + + private lateinit var twitterStreamFactory: TwitterStreamFactory + private lateinit var twitterStream: TwitterStream + + @PostConstruct + fun initTwitter(){ + val configuration = ConfigurationBuilder().apply { + setOAuthConsumerKey(twitterConsumerKey) + setOAuthConsumerSecret(twitterConsumerSecret) + setOAuthAccessToken(twitterAccessToken) + setOAuthAccessTokenSecret(twitterAccessTokenSecret) + }.build() + + twitterStreamFactory = TwitterStreamFactory(configuration) + twitterStream = twitterStreamFactory.instance + } + + fun setTwitterStreamListener(listener: StatusListener):TwitterManager{ + twitterStream.addListener(listener) + return this + } + + fun setTwitterStreamFilter(filterQuery: FilterQuery): TwitterManager { + twitterStream.filter(filterQuery) + return this + } + + fun getTwitterStream(): TwitterStream { + return twitterStream + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt new file mode 100644 index 0000000..2a31c49 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt @@ -0,0 +1,51 @@ +package it.discordbot.database.interfaces + +import it.discordbot.beans.ServerToChannel +import it.discordbot.database.repository.RSSLinkRepository +import it.discordbot.database.repository.ServerDiscordRepository +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component + +@Scope("singleton") +@Component +class ATMInterface { + + @Autowired + lateinit var serverDiscordRepository: ServerDiscordRepository + + @Autowired + lateinit var rssLinkRepository: RSSLinkRepository + + fun setATMAlertChannel(serverID: String, channelID: String) { + val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) + serverDiscord.atmAlertIDChannel = channelID + serverDiscordRepository.save(serverDiscord) + } + + fun removeATMAlertChannel(serverID: String): String? { + val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) + val atmChannelRemoveID = serverDiscord.atmAlertIDChannel + serverDiscord.atmAlertIDChannel = null + serverDiscordRepository.save(serverDiscord) + return atmChannelRemoveID + } + + fun getATMAlertChannels(): ArrayList { + return serverDiscordRepository.getAllATMAlertChannels() + } + + fun setLastATMAlert(url: String) { + rssLinkRepository.getFirstById().apply { + lastAtmAlert = url + rssLinkRepository.save(this) + } + } + + fun getLastATMAlert(): String? { + rssLinkRepository.getFirstById().apply { + return lastAtmAlert + } + } + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt new file mode 100644 index 0000000..525a796 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt @@ -0,0 +1,43 @@ +package it.discordbot.database.interfaces + +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import it.discordbot.beans.ServerToChannel +import it.discordbot.beans.boss.Giorno +import it.discordbot.database.repository.ServerDiscordRepository +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.core.io.ClassPathResource +import org.springframework.stereotype.Controller +@Scope("singleton") +@Controller +class BDOBossInterface { + + @Autowired + lateinit var serverDiscordRepository: ServerDiscordRepository + + fun setBDOBossChannel(serverID:String , channelID: String){ + val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) + serverDiscord.bdoBossIDChannel = channelID + serverDiscordRepository.save(serverDiscord) + } + + fun removeBDOBossChannel(serverID: String): String? { + val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) + val bossChannelRemoveID = serverDiscord.bdoBossIDChannel + serverDiscord.bdoBossIDChannel = null + serverDiscordRepository.save(serverDiscord) + return bossChannelRemoveID + } + + fun getBDOBossChannels(): ArrayList{ + return serverDiscordRepository.getAllBDOBossChannels() + } + + fun getBDOBossList():ArrayList{ + val inputStreamBoss = ClassPathResource("jsonboss.json").inputStream + val list = jacksonObjectMapper().readValue>(inputStreamBoss) + inputStreamBoss.close() + return list + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt new file mode 100644 index 0000000..6c075fb --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt @@ -0,0 +1,58 @@ +package it.discordbot.database.interfaces + +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import it.discordbot.beans.ServerToChannel +import it.discordbot.database.repository.RSSLinkRepository +import it.discordbot.database.repository.ServerDiscordRepository +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component + +@Scope("singleton") +@Component +class BDONewsInterface { + + @Autowired + lateinit var serverDiscordRepository: ServerDiscordRepository + + @Autowired + lateinit var rssLinkRepository: RSSLinkRepository + + fun setBDONewsChannel(serverID:String , channelID: String){ + val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) + serverDiscord.bdoNewsIDChannel = channelID + serverDiscordRepository.save(serverDiscord) + } + + fun removeBDONewsChannel(serverID: String): String? { + val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) + val newsChannelRemoveID = serverDiscord.bdoNewsIDChannel + serverDiscord.bdoNewsIDChannel = null + serverDiscordRepository.save(serverDiscord) + return newsChannelRemoveID + } + + fun getBDONewsChannels(): ArrayList{ + return serverDiscordRepository.getAllBDONewsChannels() + } + + fun getBDONewsList(): ArrayList{ + + val bdoRSSNews = rssLinkRepository.getFirstById().lastNewsBDO + + if (bdoRSSNews == null){ + return ArrayList() + }else{ + return jacksonObjectMapper().readValue(bdoRSSNews) + } + + } + + fun setBDONewsList(list: ArrayList){ + rssLinkRepository.getFirstById().apply { + lastNewsBDO = jacksonObjectMapper().writeValueAsString(list) + rssLinkRepository.save(this) + } + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt new file mode 100644 index 0000000..151e108 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt @@ -0,0 +1,56 @@ +package it.discordbot.database.interfaces + +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import it.discordbot.beans.ServerToChannel +import it.discordbot.database.repository.RSSLinkRepository +import it.discordbot.database.repository.ServerDiscordRepository +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component +import org.springframework.stereotype.Controller + +@Scope("singleton") +@Component +class BDOPatchInterface { + + @Autowired + lateinit var serverDiscordRepository: ServerDiscordRepository + + @Autowired + lateinit var rssLinkRepository: RSSLinkRepository + + fun setBDOPatchChannel(serverID:String , channelID: String){ + val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) + serverDiscord.bdoPatchIDChannel = channelID + serverDiscordRepository.save(serverDiscord) + } + + fun removeBDOPatchChannel(serverID: String): String? { + val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) + val patchChannelRemoveID = serverDiscord.bdoPatchIDChannel + serverDiscord.bdoPatchIDChannel = null + serverDiscordRepository.save(serverDiscord) + return patchChannelRemoveID + } + + fun getBDOPatchChannels(): ArrayList{ + return serverDiscordRepository.getAllBDOPatchChannels() + } + + /*fun getBDOPatchList(): ArrayList{ + return jacksonObjectMapper().readValue(rssLinkRepository.getFirstById().lastPatchBDO) + }*/ + + fun getBDOPatchList(): String?{ + return rssLinkRepository.getFirstById().lastPatchBDO + } + + fun setLastPatch(linkPatch:String){ + val rssLink = rssLinkRepository.getFirstById() + rssLink.lastPatchBDO = linkPatch + rssLinkRepository.save(rssLink) + } + + +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt new file mode 100644 index 0000000..1e6727b --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt @@ -0,0 +1,40 @@ +package it.discordbot.database.interfaces + +import it.discordbot.beans.ServerDiscord +import it.discordbot.database.repository.ServerDiscordRepository +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component + +@Scope("singleton") +@Component +class ServerManagementInterface { + + @Autowired + lateinit private var serverDiscordRepository: ServerDiscordRepository + + + fun getSimbolCommand(serverID: String): String { + val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) + return serverDiscord.simbolCommand!! + } + + fun setSimbolCommand(serverID: String, simbolCommand: String) { + val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) + serverDiscord.simbolCommand = simbolCommand + serverDiscordRepository.save(serverDiscord) + } + + fun newServer(serverID: String, serverName:String){ + val serverDiscord = ServerDiscord() + serverDiscord.let { + it.serverId = serverID + it.nameServer = serverName + } + serverDiscordRepository.save(serverDiscord) + } + + fun deleteServer(serverID: String){ + serverDiscordRepository.deleteById(serverID) + } +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt new file mode 100644 index 0000000..495316a --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt @@ -0,0 +1,9 @@ +package it.discordbot.database.repository + +import it.discordbot.beans.RSSLink +import org.springframework.data.repository.CrudRepository + +interface RSSLinkRepository: CrudRepository { + + fun getFirstById(id: Long = 1): RSSLink +} \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt new file mode 100644 index 0000000..70d5c51 --- /dev/null +++ b/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt @@ -0,0 +1,33 @@ +package it.discordbot.database.repository + +import it.discordbot.beans.ServerDiscord +import it.discordbot.beans.ServerToChannel +import org.springframework.data.jpa.repository.Query +import org.springframework.data.repository.CrudRepository +import org.springframework.stereotype.Repository +import javax.persistence.ColumnResult +import javax.persistence.ConstructorResult +import javax.persistence.SqlResultSetMapping + +@Repository +interface ServerDiscordRepository : CrudRepository { + + fun findServerDiscordByServerId(serverID: String): ServerDiscord + + @Query("SELECT new it.discordbot.beans.ServerToChannel(serv.serverId, serv.bdoNewsIDChannel) " + + "from ServerDiscord serv where serv.bdoNewsIDChannel is not null") + fun getAllBDONewsChannels(): ArrayList + + + @Query("SELECT new it.discordbot.beans.ServerToChannel(serv.serverId, serv.bdoPatchIDChannel) " + + "from ServerDiscord serv where serv.bdoPatchIDChannel is not null") + fun getAllBDOPatchChannels(): ArrayList + + @Query("SELECT new it.discordbot.beans.ServerToChannel(serv.serverId, serv.bdoBossIDChannel) " + + "from ServerDiscord serv where serv.bdoBossIDChannel is not null") + fun getAllBDOBossChannels(): ArrayList + + @Query("SELECT new it.discordbot.beans.ServerToChannel(serv.serverId, serv.atmAlertIDChannel) " + + "from ServerDiscord serv where serv.atmAlertIDChannel is not null") + fun getAllATMAlertChannels(): ArrayList +} diff --git a/SpringBootTakaoBot/src/main/resources/application.properties b/SpringBootTakaoBot/src/main/resources/application.properties new file mode 100644 index 0000000..1075f20 --- /dev/null +++ b/SpringBootTakaoBot/src/main/resources/application.properties @@ -0,0 +1,11 @@ +############################################## +###### SPRING BOOT CONFIGURATION PROPERTIES ############ +############################################## +spring.profiles.active=dev +#prod +logging.level.root=INFO +logging.level.org.springframework.web=DEBUG +logging.level.org.hibernate=ERROR + +#logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n +#logging.file=./TakaoLog/log-.log diff --git a/SpringBootTakaoBot/src/main/resources/jsonboss.json b/SpringBootTakaoBot/src/main/resources/jsonboss.json new file mode 100644 index 0000000..96829ae --- /dev/null +++ b/SpringBootTakaoBot/src/main/resources/jsonboss.json @@ -0,0 +1,387 @@ +[ + { + "giorno": "MONDAY", + "bosses": [ + { + "nomeBoss": [ + "Kutum", + "Karanda" + ], + "ora": "0:15" + }, + { + "nomeBoss": [ + "Karanda" + ], + "ora": "2:0" + }, + { + "nomeBoss": [ + "Kzarka" + ], + "ora": "5:0" + }, + { + "nomeBoss": [ + "Kzarka" + ], + "ora": "9:0" + }, + { + "nomeBoss": [ + "Offin" + ], + "ora": "12:0" + }, + { + "nomeBoss": [ + "Kutum" + ], + "ora": "16:0" + }, + { + "nomeBoss": [ + "Nouver" + ], + "ora": "19:0" + }, + { + "nomeBoss": [ + "Kzarka" + ], + "ora": "22:15" + } + ] + }, + { + "giorno": "TUESDAY", + "bosses": [ + { + "nomeBoss": [ + "Karanda" + ], + "ora": "0:15" + }, + { + "nomeBoss": [ + "Kutum" + ], + "ora": "2:0" + }, + { + "nomeBoss": [ + "Kzarka" + ], + "ora": "5:0" + }, + { + "nomeBoss": [ + "Nouver" + ], + "ora": "9:0" + }, + { + "nomeBoss": [ + "Kutum" + ], + "ora": "12:0" + }, + { + "nomeBoss": [ + "Nouver" + ], + "ora": "16:0" + }, + { + "nomeBoss": [ + "Karanda" + ], + "ora": "19:0" + }, + { + "nomeBoss": [ + "Garmoth" + ], + "ora": "22:15" + } + ] + }, + { + "giorno": "WEDNESDAY", + "bosses": [ + { + "nomeBoss": [ + "Kutum", + "Kzarka" + ], + "ora": "0:15" + }, + { + "nomeBoss": [ + "Karanda" + ], + "ora": "2:0" + }, + { + "nomeBoss": [ + "Kzarka" + ], + "ora": "5:0" + }, + { + "nomeBoss": [ + "Karanda" + ], + "ora": "9:0" + }, + { + "nomeBoss": [ + "Manutenzione" + ], + "ora": "12:0" + }, + { + "nomeBoss": [ + "Kutum" + ], + "ora": "16:0" + }, + { + "nomeBoss": [ + "Offin" + ], + "ora": "19:0" + }, + { + "nomeBoss": [ + "Karanda", + "Kzarka" + ], + "ora": "22:15" + }, + { + "nomeBoss": [ + "Quint/Muraka" + ], + "ora": "23:15" + } + ] + }, + { + "giorno": "THURSDAY", + "bosses": [ + { + "nomeBoss": [ + "Nouver" + ], + "ora": "0:15" + }, + { + "nomeBoss": [ + "Kutum" + ], + "ora": "2:0" + }, + { + "nomeBoss": [ + "Nouver" + ], + "ora": "05:0" + }, + { + "nomeBoss": [ + "Kutum" + ], + "ora": "9:0" + }, + { + "nomeBoss": [ + "Nouver" + ], + "ora": "12:0" + }, + { + "nomeBoss": [ + "Kzarka" + ], + "ora": "16:0" + }, + { + "nomeBoss": [ + "Kutum" + ], + "ora": "19:0" + }, + { + "nomeBoss": [ + "Garmoth" + ], + "ora": "22:15" + } + ] + }, + { + "giorno": "FRIDAY", + "bosses": [ + { + "nomeBoss": [ + "Karanda", + "Kzarka" + ], + "ora": "0:15" + }, + { + "nomeBoss": [ + "Nouver" + ], + "ora": "2:0" + }, + { + "nomeBoss": [ + "Karanda" + ], + "ora": "5:0" + }, + { + "nomeBoss": [ + "Kutum" + ], + "ora": "9:0" + }, + { + "nomeBoss": [ + "Karanda" + ], + "ora": "12:0" + }, + { + "nomeBoss": [ + "Nouver" + ], + "ora": "16:0" + }, + { + "nomeBoss": [ + "Kzarka" + ], + "ora": "19:0" + }, + { + "nomeBoss": [ + "Kutum", + "Kzarka" + ], + "ora": "22:15" + } + ] + }, + { + "giorno": "SATURDAY", + "bosses": [ + { + "nomeBoss": [ + "Karanda" + ], + "ora": "0:15" + }, + { + "nomeBoss": [ + "Offin" + ], + "ora": "2:0" + }, + { + "nomeBoss": [ + "Nouver" + ], + "ora": "5:0" + }, + { + "nomeBoss": [ + "Kutum" + ], + "ora": "09:0" + }, + { + "nomeBoss": [ + "Nouver" + ], + "ora": "12:0" + }, + { + "nomeBoss": [ + "Quint/Muraka" + ], + "ora": "16:0" + }, + { + "nomeBoss": [ + "Karanda", + "Kzarka" + ], + "ora": "19:0" + }, + { + "nomeBoss": [ + "Conquest War" + ], + "ora": "22:15" + } + ] + }, + { + "giorno": "SUNDAY", + "bosses": [ + { + "nomeBoss": [ + "Nouver", + "Kutum" + ], + "ora": "0:15" + }, + { + "nomeBoss": [ + "Kzarka" + ], + "ora": "2:0" + }, + { + "nomeBoss": [ + "Kutum" + ], + "ora": "5:0" + }, + { + "nomeBoss": [ + "Nouver" + ], + "ora": "9:0" + }, + { + "nomeBoss": [ + "Kzarka" + ], + "ora": "12:0" + }, + { + "nomeBoss": [ + "Vell" + ], + "ora": "16:0" + }, + { + "nomeBoss": [ + "Garmoth" + ], + "ora": "19:0" + }, + { + "nomeBoss": [ + "Kzarka", + "Nouver" + ], + "ora": "22:15" + } + ] + } +] \ No newline at end of file diff --git a/SpringBootTakaoBot/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt b/SpringBootTakaoBot/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt new file mode 100644 index 0000000..d40ac82 --- /dev/null +++ b/SpringBootTakaoBot/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt @@ -0,0 +1,31 @@ +package it.discordbot.test + +import it.discordbot.database.interfaces.BDONewsInterface +import it.discordbot.database.interfaces.ServerManagementInterface +import org.junit.Test +import org.junit.runner.RunWith +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.junit4.SpringRunner + +@RunWith(SpringRunner::class) +@SpringBootTest +class DemoApplicationTests { + + @Autowired + private lateinit var managmentServerDiscord: ServerManagementInterface + + @Autowired + private lateinit var bdoNewsInterface: BDONewsInterface + + @Test + fun testGetSimbol() { + assert(managmentServerDiscord.getSimbolCommand("324517087416549377") == "(") + } + + @Test + fun testBDONews() { + bdoNewsInterface.getBDONewsList() + } + +} diff --git a/build.gradle b/build.gradle index 5a82753..f3f83b5 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ mainClassName = 'starter.start' group 'it.github.samuele794.discordbotTakao' version '1.2.0' -def jdaVersion = '3.8.2_459' +def jdaVersion = '3.8.2_459' repositories { diff --git a/src/main/java/beans/ServersDiscord.java b/src/main/java/beans/ServersDiscord.java index 6d84624..11c1b36 100644 --- a/src/main/java/beans/ServersDiscord.java +++ b/src/main/java/beans/ServersDiscord.java @@ -60,11 +60,6 @@ public class ServersDiscord { public ServersDiscord() { } - public ServersDiscord(String serverId, String bdoNewsIDChannel) { - this.serverId = serverId; - this.bdoNewsIDChannel = bdoNewsIDChannel; - } - public String getServerId() { return serverId; } diff --git a/src/main/java/interfaces/TwitterManager.java b/src/main/java/interfaces/TwitterManager.java index e7a8294..72d8d56 100644 --- a/src/main/java/interfaces/TwitterManager.java +++ b/src/main/java/interfaces/TwitterManager.java @@ -14,7 +14,7 @@ import java.net.URISyntaxException; import java.util.Properties; -public class TwitterManager { +public class TwitterManager { private TwitterStreamFactory twitterStreamFactory = null; private TwitterStream twitterStream = null; From 24674f491b2c24b7b6919b327de495bef06501da Mon Sep 17 00:00:00 2001 From: samuele794 Date: Tue, 14 May 2019 16:31:33 +0200 Subject: [PATCH 02/12] Rimosso Vecchio Progetto TakaoBot, sostituito con il nuovo Rinominato Progetto Rimosso sorgente lavaplayer --- .gitignore | 10 +- SpringBootTakaoBot/.gitignore | 30 - SpringBootTakaoBot/build.gradle | 100 --- .../gradle/wrapper/gradle-wrapper.jar | Bin 56177 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - SpringBootTakaoBot/gradlew | 172 ----- SpringBootTakaoBot/gradlew.bat | 84 --- SpringBootTakaoBot/settings.gradle | 6 - .../src/main/META-INF/MANIFEST.MF | 3 - .../src/main/resources/jsonboss.json | 387 ----------- build.gradle | 141 ++-- gradle/wrapper/gradle-wrapper.properties | 3 +- settings.gradle | 8 +- src/main/META-INF/MANIFEST.MF | 2 +- src/main/java/beans/BDOBossBean/Boss.java | 67 -- src/main/java/beans/BDOBossBean/Giorno.java | 50 -- src/main/java/beans/RSSMessage.java | 75 --- src/main/java/beans/Rsslink.java | 73 --- src/main/java/beans/ServerToChannel.java | 74 --- src/main/java/beans/ServersDiscord.java | 118 ---- .../discord/lavaplayer/container/Formats.java | 15 - .../lavaplayer/container/MediaContainer.java | 52 -- .../container/MediaContainerDescriptor.java | 19 - .../container/MediaContainerDetection.java | 170 ----- .../MediaContainerDetectionResult.java | 112 ---- .../container/MediaContainerHints.java | 42 -- .../container/MediaContainerProbe.java | 48 -- .../container/MediaContainerRegistry.java | 27 - .../container/adts/AdtsAudioTrack.java | 41 -- .../container/adts/AdtsContainerProbe.java | 53 -- .../container/adts/AdtsPacketHeader.java | 53 -- .../container/adts/AdtsStreamProvider.java | 144 ----- .../container/adts/AdtsStreamReader.java | 165 ----- .../container/common/AacPacketRouter.java | 93 --- .../container/common/OpusPacketRouter.java | 205 ------ .../container/flac/FlacAudioTrack.java | 40 -- .../container/flac/FlacContainerProbe.java | 61 -- .../container/flac/FlacFileLoader.java | 64 -- .../container/flac/FlacMetadataHeader.java | 41 -- .../container/flac/FlacMetadataReader.java | 107 ---- .../container/flac/FlacSeekPoint.java | 41 -- .../container/flac/FlacStreamInfo.java | 83 --- .../container/flac/FlacTrackInfo.java | 52 -- .../container/flac/FlacTrackInfoBuilder.java | 61 -- .../container/flac/FlacTrackProvider.java | 114 ---- .../flac/frame/FlacFrameHeaderReader.java | 136 ---- .../container/flac/frame/FlacFrameInfo.java | 46 -- .../container/flac/frame/FlacFrameReader.java | 150 ----- .../flac/frame/FlacSubFrameReader.java | 197 ------ .../matroska/MatroskaAacTrackConsumer.java | 79 --- .../matroska/MatroskaAudioTrack.java | 102 --- .../matroska/MatroskaContainerProbe.java | 78 --- .../matroska/MatroskaOpusTrackConsumer.java | 54 -- .../matroska/MatroskaStreamingFile.java | 398 ------------ .../matroska/MatroskaTrackConsumer.java | 48 -- .../matroska/MatroskaVorbisTrackConsumer.java | 161 ----- .../matroska/format/MatroskaBlock.java | 40 -- .../matroska/format/MatroskaCuePoint.java | 24 - .../matroska/format/MatroskaEbmlReader.java | 169 ----- .../matroska/format/MatroskaElement.java | 103 --- .../matroska/format/MatroskaElementType.java | 142 ---- .../matroska/format/MatroskaFileReader.java | 216 ------- .../matroska/format/MatroskaFileTrack.java | 207 ------ .../matroska/format/MutableMatroskaBlock.java | 160 ----- .../format/MutableMatroskaElement.java | 30 - .../container/mp3/Mp3AudioTrack.java | 41 -- .../container/mp3/Mp3ConstantRateSeeker.java | 83 --- .../container/mp3/Mp3ContainerProbe.java | 70 -- .../container/mp3/Mp3FrameReader.java | 154 ----- .../lavaplayer/container/mp3/Mp3Seeker.java | 28 - .../container/mp3/Mp3StreamSeeker.java | 25 - .../container/mp3/Mp3TrackProvider.java | 395 ------------ .../container/mp3/Mp3XingSeeker.java | 86 --- .../container/mpeg/MpegAacTrackConsumer.java | 93 --- .../container/mpeg/MpegAudioTrack.java | 92 --- .../container/mpeg/MpegContainerProbe.java | 86 --- .../container/mpeg/MpegFileLoader.java | 232 ------- .../container/mpeg/MpegNoopTrackConsumer.java | 47 -- .../container/mpeg/MpegTrackConsumer.java | 47 -- .../container/mpeg/MpegTrackInfo.java | 88 --- .../mpeg/reader/MpegFileTrackProvider.java | 35 - .../mpeg/reader/MpegParseStopChecker.java | 14 - .../container/mpeg/reader/MpegReader.java | 281 -------- .../mpeg/reader/MpegSectionHandler.java | 14 - .../mpeg/reader/MpegSectionInfo.java | 30 - .../reader/MpegVersionedSectionHandler.java | 14 - .../mpeg/reader/MpegVersionedSectionInfo.java | 27 - .../MpegFragmentedFileTrackProvider.java | 235 ------- .../reader/fragmented/MpegGlobalSeekInfo.java | 42 -- .../reader/fragmented/MpegSegmentEntry.java | 30 - .../fragmented/MpegTrackFragmentHeader.java | 141 ---- .../MpegStandardFileTrackProvider.java | 335 ---------- .../container/mpegts/MpegAdtsAudioTrack.java | 30 - .../mpegts/MpegAdtsContainerProbe.java | 76 --- .../mpegts/MpegTsElementaryInputStream.java | 332 ---------- .../mpegts/PesPacketInputStream.java | 106 --- .../container/ogg/OggAudioTrack.java | 67 -- .../container/ogg/OggCodecHandler.java | 15 - .../container/ogg/OggContainerProbe.java | 68 -- .../lavaplayer/container/ogg/OggMetadata.java | 50 -- .../container/ogg/OggPacketInputStream.java | 336 ---------- .../container/ogg/OggPageHeader.java | 70 -- .../container/ogg/OggPageScanner.java | 98 --- .../container/ogg/OggStreamSizeInfo.java | 51 -- .../container/ogg/OggTrackHandler.java | 37 -- .../container/ogg/OggTrackLoader.java | 72 --- .../ogg/flac/OggFlacCodecHandler.java | 84 --- .../ogg/flac/OggFlacTrackHandler.java | 83 --- .../ogg/opus/OggOpusCodecHandler.java | 98 --- .../ogg/opus/OggOpusTrackHandler.java | 70 -- .../ogg/vorbis/OggVorbisCodecHandler.java | 65 -- .../ogg/vorbis/OggVorbisTrackHandler.java | 109 ---- .../ogg/vorbis/VorbisCommentParser.java | 62 -- .../HlsStreamSegmentUrlProvider.java | 64 -- .../container/playlists/HlsStreamTrack.java | 38 -- .../playlists/M3uPlaylistContainerProbe.java | 119 ---- .../PlainPlaylistContainerProbe.java | 68 -- .../playlists/PlsPlaylistContainerProbe.java | 87 --- .../container/wav/WavAudioTrack.java | 39 -- .../container/wav/WavContainerProbe.java | 60 -- .../lavaplayer/container/wav/WavFileInfo.java | 62 -- .../container/wav/WavFileLoader.java | 131 ---- .../container/wav/WavTrackProvider.java | 127 ---- .../lavaplayer/filter/AudioFilter.java | 27 - .../lavaplayer/filter/AudioFilterChain.java | 35 - .../lavaplayer/filter/AudioPipeline.java | 45 -- .../filter/AudioPipelineFactory.java | 66 -- .../lavaplayer/filter/AudioPostProcessor.java | 23 - .../filter/BufferingPostProcessor.java | 48 -- .../filter/ChannelCountPcmAudioFilter.java | 149 ----- .../filter/CompositeAudioFilter.java | 48 -- .../lavaplayer/filter/FilterChainBuilder.java | 86 --- .../filter/FinalPcmAudioFilter.java | 166 ----- .../filter/FloatPcmAudioFilter.java | 14 - .../lavaplayer/filter/PcmFilterFactory.java | 25 - .../discord/lavaplayer/filter/PcmFormat.java | 24 - .../filter/ResamplingPcmAudioFilter.java | 85 --- .../filter/ShortPcmAudioFilter.java | 22 - .../filter/SplitShortPcmAudioFilter.java | 14 - .../filter/UniversalPcmAudioFilter.java | 8 - .../filter/UserProvidedAudioFilters.java | 93 --- .../converter/ConverterAudioFilter.java | 29 - .../filter/converter/ToFloatAudioFilter.java | 91 --- .../filter/converter/ToShortAudioFilter.java | 72 --- .../converter/ToSplitShortAudioFilter.java | 82 --- .../filter/equalizer/Equalizer.java | 174 ----- .../equalizer/EqualizerConfiguration.java | 44 -- .../filter/equalizer/EqualizerFactory.java | 32 - .../volume/AudioFrameVolumeChanger.java | 106 --- .../filter/volume/PcmVolumeProcessor.java | 86 --- .../filter/volume/VolumePostProcessor.java | 43 -- .../lavaplayer/format/AudioDataFormat.java | 103 --- .../format/AudioDataFormatTools.java | 31 - .../format/AudioPlayerInputStream.java | 130 ---- .../format/OpusAudioDataFormat.java | 71 -- .../format/Pcm16AudioDataFormat.java | 70 -- .../format/StandardAudioDataFormats.java | 27 - .../format/transcoder/AudioChunkDecoder.java | 19 - .../format/transcoder/AudioChunkEncoder.java | 26 - .../format/transcoder/OpusChunkDecoder.java | 38 -- .../format/transcoder/OpusChunkEncoder.java | 56 -- .../format/transcoder/PcmChunkDecoder.java | 48 -- .../format/transcoder/PcmChunkEncoder.java | 64 -- .../natives/ConnectorNativeLibLoader.java | 24 - .../lavaplayer/natives/aac/AacDecoder.java | 256 -------- .../natives/aac/AacDecoderLibrary.java | 29 - .../lavaplayer/natives/mp3/Mp3Decoder.java | 257 -------- .../natives/mp3/Mp3DecoderLibrary.java | 23 - .../lavaplayer/natives/opus/OpusDecoder.java | 114 ---- .../natives/opus/OpusDecoderLibrary.java | 23 - .../lavaplayer/natives/opus/OpusEncoder.java | 61 -- .../natives/opus/OpusEncoderLibrary.java | 25 - .../samplerate/SampleRateConverter.java | 94 --- .../natives/samplerate/SampleRateLibrary.java | 22 - .../natives/statistics/CpuStatistics.java | 106 --- .../statistics/CpuStatisticsLibrary.java | 28 - .../natives/vorbis/VorbisDecoder.java | 101 --- .../natives/vorbis/VorbisDecoderLibrary.java | 29 - .../lavaplayer/player/AudioConfiguration.java | 92 --- .../player/AudioLoadResultHandler.java | 36 -- .../lavaplayer/player/AudioPlayer.java | 77 --- .../player/AudioPlayerLifecycleManager.java | 69 -- .../lavaplayer/player/AudioPlayerManager.java | 178 ----- .../lavaplayer/player/AudioPlayerOptions.java | 34 - .../lavaplayer/player/DefaultAudioPlayer.java | 371 ----------- .../player/DefaultAudioPlayerManager.java | 484 -------------- .../player/FunctionalResultHandler.java | 62 -- .../lavaplayer/player/event/AudioEvent.java | 20 - .../player/event/AudioEventAdapter.java | 77 --- .../player/event/AudioEventListener.java | 11 - .../player/event/PlayerPauseEvent.java | 15 - .../player/event/PlayerResumeEvent.java | 15 - .../player/event/TrackEndEvent.java | 30 - .../player/event/TrackExceptionEvent.java | 30 - .../player/event/TrackStartEvent.java | 23 - .../player/event/TrackStuckEvent.java | 30 - .../player/hook/AudioOutputHook.java | 16 - .../player/hook/AudioOutputHookFactory.java | 11 - .../remote/AbandonedTrackManager.java | 198 ------ .../remote/RemoteAudioTrackExecutor.java | 277 -------- .../discord/lavaplayer/remote/RemoteNode.java | 143 ----- .../lavaplayer/remote/RemoteNodeManager.java | 192 ------ .../remote/RemoteNodeProcessor.java | 575 ----------------- .../lavaplayer/remote/RemoteNodeRegistry.java | 28 - .../remote/message/NodeStatisticsCodec.java | 33 - .../remote/message/NodeStatisticsMessage.java | 36 -- .../remote/message/RemoteMessage.java | 7 - .../remote/message/RemoteMessageCodec.java | 42 -- .../remote/message/RemoteMessageMapper.java | 99 --- .../remote/message/RemoteMessageType.java | 23 - .../remote/message/TrackExceptionCodec.java | 33 - .../remote/message/TrackExceptionMessage.java | 26 - .../remote/message/TrackFrameDataCodec.java | 59 -- .../remote/message/TrackFrameDataMessage.java | 47 -- .../message/TrackFrameRequestCodec.java | 33 - .../message/TrackFrameRequestMessage.java | 37 -- .../message/TrackStartRequestCodec.java | 117 ---- .../message/TrackStartRequestMessage.java | 53 -- .../message/TrackStartResponseCodec.java | 38 -- .../message/TrackStartResponseMessage.java | 31 - .../remote/message/TrackStoppedCodec.java | 30 - .../remote/message/TrackStoppedMessage.java | 19 - .../remote/message/UnknownMessage.java | 11 - .../lavaplayer/source/AudioSourceManager.java | 72 --- .../source/AudioSourceManagers.java | 60 -- .../source/ProbingAudioSourceManager.java | 69 -- .../bandcamp/BandcampAudioSourceManager.java | 204 ------ .../source/bandcamp/BandcampAudioTrack.java | 77 --- .../source/beam/BeamAudioSourceManager.java | 142 ---- .../source/beam/BeamAudioTrack.java | 68 -- .../source/beam/BeamSegmentUrlProvider.java | 71 -- .../source/http/HttpAudioSourceManager.java | 164 ----- .../source/http/HttpAudioTrack.java | 67 -- .../source/local/LocalAudioSourceManager.java | 89 --- .../source/local/LocalAudioTrack.java | 59 -- .../local/LocalSeekableInputStream.java | 112 ---- .../source/nico/NicoAudioSourceManager.java | 187 ------ .../source/nico/NicoAudioTrack.java | 97 --- .../SoundCloudAudioSourceManager.java | 606 ------------------ .../soundcloud/SoundCloudAudioTrack.java | 76 --- .../source/stream/ExtendedM3uParser.java | 98 --- .../source/stream/M3uStreamAudioTrack.java | 40 -- .../stream/M3uStreamSegmentUrlProvider.java | 239 ------- .../TwitchStreamAudioSourceManager.java | 191 ------ .../source/twitch/TwitchStreamAudioTrack.java | 68 -- .../TwitchStreamSegmentUrlProvider.java | 145 ----- .../source/vimeo/VimeoAudioSourceManager.java | 145 ----- .../source/vimeo/VimeoAudioTrack.java | 103 --- .../youtube/YoutubeAudioSourceManager.java | 566 ---------------- .../source/youtube/YoutubeAudioTrack.java | 289 --------- .../youtube/YoutubeCipherOperation.java | 24 - .../youtube/YoutubeCipherOperationType.java | 11 - .../source/youtube/YoutubeFormatInfo.java | 57 -- .../source/youtube/YoutubeMixProvider.java | 146 ----- .../youtube/YoutubeMpegStreamAudioTrack.java | 151 ----- .../youtube/YoutubePersistentHttpStream.java | 47 -- .../source/youtube/YoutubeSearchProvider.java | 117 ---- .../youtube/YoutubeSignatureCipher.java | 55 -- .../YoutubeSignatureCipherManager.java | 255 -------- .../source/youtube/YoutubeTrackFormat.java | 92 --- .../lavaplayer/tools/DataFormatTools.java | 142 ---- .../lavaplayer/tools/DecodedException.java | 28 - .../lavaplayer/tools/ExceptionTools.java | 219 ------- .../lavaplayer/tools/FriendlyException.java | 43 -- .../tools/GarbageCollectionMonitor.java | 143 ----- .../discord/lavaplayer/tools/JsonBrowser.java | 168 ----- .../lavaplayer/tools/OrderedExecutor.java | 102 --- .../lavaplayer/tools/PlayerLibrary.java | 30 - .../lavaplayer/tools/RingBufferMath.java | 51 -- .../io/AbstractHttpInterfaceManager.java | 90 --- .../lavaplayer/tools/io/BitBufferReader.java | 43 -- .../lavaplayer/tools/io/BitStreamReader.java | 130 ---- .../lavaplayer/tools/io/BitStreamWriter.java | 64 -- .../tools/io/ByteBufferInputStream.java | 44 -- .../tools/io/ByteBufferOutputStream.java | 29 - .../tools/io/ChainedInputStream.java | 112 ---- .../tools/io/DetachedByteChannel.java | 40 -- .../tools/io/DirectBufferStreamBroker.java | 111 ---- .../lavaplayer/tools/io/EmptyInputStream.java | 20 - .../tools/io/ExtendedBufferedInputStream.java | 40 -- .../tools/io/GreedyInputStream.java | 51 -- .../lavaplayer/tools/io/HttpClientTools.java | 391 ----------- .../lavaplayer/tools/io/HttpConfigurable.java | 22 - .../lavaplayer/tools/io/HttpInterface.java | 99 --- .../tools/io/HttpInterfaceManager.java | 13 - .../lavaplayer/tools/io/MessageInput.java | 70 -- .../lavaplayer/tools/io/MessageOutput.java | 62 -- .../tools/io/PersistentHttpStream.java | 301 --------- .../io/ResettableBoundedInputStream.java | 89 --- .../io/SavedHeadSeekableInputStream.java | 141 ---- .../tools/io/SeekableInputStream.java | 105 --- .../tools/io/SimpleHttpInterfaceManager.java | 23 - .../lavaplayer/tools/io/StreamTools.java | 35 - .../io/ThreadLocalHttpInterfaceManager.java | 46 -- .../tools/io/TrustManagerBuilder.java | 139 ---- .../discord/lavaplayer/track/AudioItem.java | 7 - .../lavaplayer/track/AudioPlaylist.java | 28 - .../lavaplayer/track/AudioReference.java | 68 -- .../discord/lavaplayer/track/AudioTrack.java | 85 --- .../lavaplayer/track/AudioTrackEndReason.java | 41 -- .../lavaplayer/track/AudioTrackInfo.java | 48 -- .../lavaplayer/track/AudioTrackState.java | 13 - .../lavaplayer/track/BaseAudioTrack.java | 164 ----- .../lavaplayer/track/BasicAudioPlaylist.java | 46 -- .../lavaplayer/track/DecodedTrackHolder.java | 19 - .../lavaplayer/track/DelegatedAudioTrack.java | 44 -- .../lavaplayer/track/InternalAudioTrack.java | 37 -- .../discord/lavaplayer/track/TrackMarker.java | 27 - .../lavaplayer/track/TrackMarkerHandler.java | 46 -- .../lavaplayer/track/TrackMarkerTracker.java | 84 --- .../lavaplayer/track/TrackStateListener.java | 26 - .../track/info/AudioTrackInfoBuilder.java | 143 ----- .../track/info/AudioTrackInfoProvider.java | 31 - .../playback/AbstractAudioFrameBuffer.java | 76 --- .../playback/AbstractMutableAudioFrame.java | 56 -- .../playback/AllocatingAudioFrameBuffer.java | 205 ------ .../lavaplayer/track/playback/AudioFrame.java | 48 -- .../track/playback/AudioFrameBuffer.java | 63 -- .../playback/AudioFrameBufferFactory.java | 19 - .../track/playback/AudioFrameConsumer.java | 21 - .../track/playback/AudioFrameProvider.java | 41 -- .../playback/AudioFrameProviderTools.java | 24 - .../track/playback/AudioFrameRebuilder.java | 14 - .../playback/AudioProcessingContext.java | 47 -- .../track/playback/AudioTrackExecutor.java | 56 -- .../track/playback/ImmutableAudioFrame.java | 78 --- .../playback/LocalAudioTrackExecutor.java | 470 -------------- .../track/playback/MutableAudioFrame.java | 57 -- .../NonAllocatingAudioFrameBuffer.java | 320 --------- .../PrimordialAudioTrackExecutor.java | 105 --- .../playback/ReferenceMutableAudioFrame.java | 59 -- .../track/playback/TerminatorAudioFrame.java | 45 -- .../natives/NativeLibraryBinaryProvider.java | 14 - .../common/natives/NativeLibraryLoader.java | 210 ------ .../natives/NativeLibraryProperties.java | 50 -- .../common/natives/NativeResourceHolder.java | 52 -- .../ResourceNativeLibraryBinaryProvider.java | 29 - .../SystemNativeLibraryProperties.java | 53 -- .../architecture/ArchitectureType.java | 8 - .../DefaultArchitectureTypes.java | 64 -- .../DefaultOperatingSystemTypes.java | 49 -- .../architecture/OperatingSystemType.java | 18 - .../natives/architecture/SystemType.java | 78 --- .../common/tools/DaemonThreadFactory.java | 88 --- .../lava/common/tools/ExecutorTools.java | 121 ---- .../java/command/pattern/ControlCommand.java | 74 --- .../java/command/real/BDO/BDOReceiver.java | 157 ----- .../real/BDO/RSS/BDONewsStartCommand.java | 43 -- .../real/BDO/RSS/BDONewsStopCommand.java | 47 -- .../real/BDO/RSS/BDOPatchStartCommand.java | 40 -- .../real/BDO/RSS/BDOPatchStopCommand.java | 47 -- .../command/real/BDO/RSS/BDORSSReader.java | 72 --- .../command/real/BDO/RSS/BDORSScheduler.java | 68 -- .../real/BDO/boss/BDOBossStartCommand.java | 37 -- .../real/BDO/boss/BDOBossStopCommand.java | 45 -- .../java/command/real/BDO/boss/BossJob.java | 29 - .../command/real/BDO/boss/BossRetriver.java | 214 ------- src/main/java/command/real/JoinListener.java | 27 - .../configuration/ConfigurationCommand.java | 77 --- .../configuration/ConfigurationReceiver.java | 154 ----- .../real/configuration/HelpCommand.java | 58 -- .../real/configuration/InfoCommand.java | 62 -- .../real/sound/AudioPlayerSendHandler.java | 49 -- .../command/real/sound/GuildMusicManager.java | 34 - .../java/command/real/sound/MusicManager.java | 445 ------------- .../real/sound/PlayerControlCommand.java | 86 --- .../command/real/sound/TrackScheduler.java | 82 --- .../real/tpl/atmAlert/ATMAlertReceiver.java | 64 -- .../tpl/atmAlert/ATMAlertStartCommand.java | 37 -- .../tpl/atmAlert/ATMAlertStopCommand.java | 45 -- .../real/tpl/atmAlert/ATMRSSReader.java | 83 --- .../real/tpl/atmAlert/AtmScheduler.java | 148 ----- .../java/interfaces/DiscordScheduler.java | 50 -- .../interfaces/DiscordTokenInterfaces.java | 42 -- .../java/interfaces/PostgreSQLInterface.java | 474 -------------- .../java/interfaces/PropertyInterfaces.java | 37 -- .../java/interfaces/SQLiteInterfaces.java | 563 ---------------- src/main/java/interfaces/TakaoLog.java | 21 - src/main/java/interfaces/TwitterManager.java | 74 --- src/main/java/starter/Start.java | 59 -- .../main/kotlin/it/discordbot/StartBot.kt | 0 .../main/kotlin/it/discordbot/TestCommand.kt | 0 .../kotlin/it/discordbot/beans/RSSLink.kt | 0 .../kotlin/it/discordbot/beans/RSSMessage.kt | 0 .../it/discordbot/beans/ServerDiscord.kt | 0 .../it/discordbot/beans/ServerToChannel.kt | 0 .../kotlin/it/discordbot/beans/boss/Boss.kt | 0 .../kotlin/it/discordbot/beans/boss/Giorno.kt | 0 .../it/discordbot/command/BDO/BDOCommand.kt | 0 .../command/BDO/RSS/BDONewsRSSScheduler.kt | 0 .../command/BDO/RSS/BDOPatchRSSScheduler.kt | 0 .../command/BDO/RSS/BDORSSReader.kt | 0 .../command/BDO/boss/BDOBossScheduler.kt | 0 .../discordbot/command/BDO/boss/BossUtil.kt | 0 .../it/discordbot/command/ControlCommand.kt | 0 .../command/generalCommand/GeneralCommand.kt | 0 .../command/generalCommand/JoinListener.kt | 0 .../discordbot/command/music/MusicCommand.kt | 4 + .../music/config/AudioPlayerSendHandler.kt | 0 .../command/music/config/GuildMusicManager.kt | 0 .../command/music/config/MusicManager.kt | 0 .../command/music/config/TrackScheduler.kt | 0 .../command/tpl/atmAlert/ATMCommand.kt | 0 .../command/tpl/atmAlert/ATMRSSReader.kt | 0 .../command/tpl/atmAlert/ATMRSSScheduler.kt | 0 .../tpl/atmAlert/ATMTwitterScheduler.kt | 0 .../it/discordbot/core/JDAController.kt | 0 .../kotlin/it/discordbot/core/TakaoLog.kt | 0 .../it/discordbot/core/TwitterManager.kt | 0 .../database/interfaces/ATMInterface.kt | 0 .../database/interfaces/BDOBossInterface.kt | 0 .../database/interfaces/BDONewsInterface.kt | 0 .../database/interfaces/BDOPatchInterface.kt | 0 .../interfaces/ServerManagementInterface.kt | 0 .../database/repository/RSSLinkRepository.kt | 0 .../repository/ServerDiscordRepository.kt | 0 src/main/main.iml | 14 - .../main/resources/application.properties | 2 +- src/main/resources/logback.xml | 47 -- src/test/java/testing/PrivateMessage.java | 38 -- src/test/java/testing/StartTest.java | 44 -- src/test/java/testing/TestCommand.java | 45 -- .../discordbot/test/DemoApplicationTests.kt | 0 423 files changed, 85 insertions(+), 34513 deletions(-) delete mode 100644 SpringBootTakaoBot/.gitignore delete mode 100644 SpringBootTakaoBot/build.gradle delete mode 100644 SpringBootTakaoBot/gradle/wrapper/gradle-wrapper.jar delete mode 100644 SpringBootTakaoBot/gradle/wrapper/gradle-wrapper.properties delete mode 100644 SpringBootTakaoBot/gradlew delete mode 100644 SpringBootTakaoBot/gradlew.bat delete mode 100644 SpringBootTakaoBot/settings.gradle delete mode 100644 SpringBootTakaoBot/src/main/META-INF/MANIFEST.MF delete mode 100644 SpringBootTakaoBot/src/main/resources/jsonboss.json delete mode 100644 src/main/java/beans/BDOBossBean/Boss.java delete mode 100644 src/main/java/beans/BDOBossBean/Giorno.java delete mode 100644 src/main/java/beans/RSSMessage.java delete mode 100644 src/main/java/beans/Rsslink.java delete mode 100644 src/main/java/beans/ServerToChannel.java delete mode 100644 src/main/java/beans/ServersDiscord.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/Formats.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDescriptor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDetection.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDetectionResult.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerHints.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerRegistry.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsPacketHeader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsStreamProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsStreamReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/common/AacPacketRouter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/common/OpusPacketRouter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacFileLoader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacMetadataHeader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacMetadataReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacSeekPoint.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacStreamInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackInfoBuilder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameHeaderReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacSubFrameReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaAacTrackConsumer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaOpusTrackConsumer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaStreamingFile.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaTrackConsumer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaVorbisTrackConsumer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaBlock.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaCuePoint.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaEbmlReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElement.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElementType.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaFileReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaFileTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MutableMatroskaBlock.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MutableMatroskaElement.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3AudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3ConstantRateSeeker.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3ContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3FrameReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3Seeker.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3StreamSeeker.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3TrackProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3XingSeeker.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegAacTrackConsumer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegFileLoader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegNoopTrackConsumer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegTrackConsumer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegTrackInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegFileTrackProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegParseStopChecker.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegSectionHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegSectionInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegVersionedSectionHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegVersionedSectionInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegFragmentedFileTrackProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegGlobalSeekInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegSegmentEntry.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegTrackFragmentHeader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/standard/MpegStandardFileTrackProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegAdtsAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegAdtsContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegTsElementaryInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/PesPacketInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggCodecHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggMetadata.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPacketInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPageHeader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPageScanner.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggStreamSizeInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggTrackHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggTrackLoader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/flac/OggFlacCodecHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/flac/OggFlacTrackHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/opus/OggOpusCodecHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/opus/OggOpusTrackHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/OggVorbisCodecHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/OggVorbisTrackHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/VorbisCommentParser.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/HlsStreamSegmentUrlProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/HlsStreamTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/M3uPlaylistContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/PlainPlaylistContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/PlsPlaylistContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavContainerProbe.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavFileInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavFileLoader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavTrackProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioFilterChain.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPipeline.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPipelineFactory.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPostProcessor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/BufferingPostProcessor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/ChannelCountPcmAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/CompositeAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/FilterChainBuilder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/FinalPcmAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/FloatPcmAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/PcmFilterFactory.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/PcmFormat.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/ResamplingPcmAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/ShortPcmAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/SplitShortPcmAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/UniversalPcmAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/UserProvidedAudioFilters.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ConverterAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToFloatAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToShortAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToSplitShortAudioFilter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/Equalizer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/EqualizerConfiguration.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/EqualizerFactory.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/AudioFrameVolumeChanger.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/PcmVolumeProcessor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/VolumePostProcessor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioDataFormat.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioDataFormatTools.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioPlayerInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/OpusAudioDataFormat.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/Pcm16AudioDataFormat.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/StandardAudioDataFormats.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/AudioChunkDecoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/AudioChunkEncoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/OpusChunkDecoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/OpusChunkEncoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/PcmChunkDecoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/PcmChunkEncoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/ConnectorNativeLibLoader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/aac/AacDecoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/aac/AacDecoderLibrary.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/mp3/Mp3Decoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/mp3/Mp3DecoderLibrary.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusDecoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusDecoderLibrary.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusEncoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusEncoderLibrary.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/samplerate/SampleRateConverter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/samplerate/SampleRateLibrary.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/statistics/CpuStatistics.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/statistics/CpuStatisticsLibrary.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/vorbis/VorbisDecoder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/natives/vorbis/VorbisDecoderLibrary.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioConfiguration.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioLoadResultHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerLifecycleManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerOptions.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/DefaultAudioPlayer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/DefaultAudioPlayerManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/FunctionalResultHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEvent.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEventAdapter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEventListener.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/event/PlayerPauseEvent.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/event/PlayerResumeEvent.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackEndEvent.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackExceptionEvent.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackStartEvent.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackStuckEvent.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/hook/AudioOutputHook.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/player/hook/AudioOutputHookFactory.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/AbandonedTrackManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteAudioTrackExecutor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNode.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeProcessor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeRegistry.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/NodeStatisticsCodec.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/NodeStatisticsMessage.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessage.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageCodec.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageMapper.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageType.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackExceptionCodec.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackExceptionMessage.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameDataCodec.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameDataMessage.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameRequestCodec.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameRequestMessage.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartRequestCodec.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartRequestMessage.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartResponseCodec.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartResponseMessage.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStoppedCodec.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStoppedMessage.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/UnknownMessage.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/AudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/AudioSourceManagers.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/ProbingAudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/bandcamp/BandcampAudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/bandcamp/BandcampAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamAudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamSegmentUrlProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/http/HttpAudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/http/HttpAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalAudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalSeekableInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/nico/NicoAudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/nico/NicoAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/soundcloud/SoundCloudAudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/soundcloud/SoundCloudAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/ExtendedM3uParser.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/M3uStreamAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/M3uStreamSegmentUrlProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamAudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamSegmentUrlProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/vimeo/VimeoAudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/vimeo/VimeoAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeAudioSourceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeCipherOperation.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeCipherOperationType.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeFormatInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeMixProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeMpegStreamAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubePersistentHttpStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSearchProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSignatureCipher.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSignatureCipherManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeTrackFormat.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/DataFormatTools.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/DecodedException.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/ExceptionTools.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/FriendlyException.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/GarbageCollectionMonitor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/JsonBrowser.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/OrderedExecutor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/PlayerLibrary.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/RingBufferMath.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/AbstractHttpInterfaceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitBufferReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitStreamReader.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitStreamWriter.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ByteBufferInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ByteBufferOutputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ChainedInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/DetachedByteChannel.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/DirectBufferStreamBroker.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/EmptyInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ExtendedBufferedInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/GreedyInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpClientTools.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpConfigurable.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpInterface.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpInterfaceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/MessageInput.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/MessageOutput.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/PersistentHttpStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ResettableBoundedInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SavedHeadSeekableInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SeekableInputStream.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SimpleHttpInterfaceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/StreamTools.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ThreadLocalHttpInterfaceManager.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/TrustManagerBuilder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioItem.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioPlaylist.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioReference.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackEndReason.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackInfo.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackState.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/BaseAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/BasicAudioPlaylist.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/DecodedTrackHolder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/DelegatedAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/InternalAudioTrack.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarker.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarkerHandler.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarkerTracker.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackStateListener.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/info/AudioTrackInfoBuilder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/info/AudioTrackInfoProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AbstractAudioFrameBuffer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AbstractMutableAudioFrame.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AllocatingAudioFrameBuffer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrame.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameBuffer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameBufferFactory.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameConsumer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameProvider.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameProviderTools.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameRebuilder.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioProcessingContext.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioTrackExecutor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/ImmutableAudioFrame.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/LocalAudioTrackExecutor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/MutableAudioFrame.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/NonAllocatingAudioFrameBuffer.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/PrimordialAudioTrackExecutor.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/ReferenceMutableAudioFrame.java delete mode 100644 src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/TerminatorAudioFrame.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryBinaryProvider.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryLoader.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryProperties.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/NativeResourceHolder.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/ResourceNativeLibraryBinaryProvider.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/SystemNativeLibraryProperties.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/architecture/ArchitectureType.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/architecture/DefaultArchitectureTypes.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/architecture/DefaultOperatingSystemTypes.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/architecture/OperatingSystemType.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/natives/architecture/SystemType.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/tools/DaemonThreadFactory.java delete mode 100644 src/main/java/com/sedmelluq/lava/common/tools/ExecutorTools.java delete mode 100644 src/main/java/command/pattern/ControlCommand.java delete mode 100644 src/main/java/command/real/BDO/BDOReceiver.java delete mode 100644 src/main/java/command/real/BDO/RSS/BDONewsStartCommand.java delete mode 100644 src/main/java/command/real/BDO/RSS/BDONewsStopCommand.java delete mode 100644 src/main/java/command/real/BDO/RSS/BDOPatchStartCommand.java delete mode 100644 src/main/java/command/real/BDO/RSS/BDOPatchStopCommand.java delete mode 100644 src/main/java/command/real/BDO/RSS/BDORSSReader.java delete mode 100644 src/main/java/command/real/BDO/RSS/BDORSScheduler.java delete mode 100644 src/main/java/command/real/BDO/boss/BDOBossStartCommand.java delete mode 100644 src/main/java/command/real/BDO/boss/BDOBossStopCommand.java delete mode 100644 src/main/java/command/real/BDO/boss/BossJob.java delete mode 100644 src/main/java/command/real/BDO/boss/BossRetriver.java delete mode 100644 src/main/java/command/real/JoinListener.java delete mode 100644 src/main/java/command/real/configuration/ConfigurationCommand.java delete mode 100644 src/main/java/command/real/configuration/ConfigurationReceiver.java delete mode 100644 src/main/java/command/real/configuration/HelpCommand.java delete mode 100644 src/main/java/command/real/configuration/InfoCommand.java delete mode 100644 src/main/java/command/real/sound/AudioPlayerSendHandler.java delete mode 100644 src/main/java/command/real/sound/GuildMusicManager.java delete mode 100644 src/main/java/command/real/sound/MusicManager.java delete mode 100644 src/main/java/command/real/sound/PlayerControlCommand.java delete mode 100644 src/main/java/command/real/sound/TrackScheduler.java delete mode 100644 src/main/java/command/real/tpl/atmAlert/ATMAlertReceiver.java delete mode 100644 src/main/java/command/real/tpl/atmAlert/ATMAlertStartCommand.java delete mode 100644 src/main/java/command/real/tpl/atmAlert/ATMAlertStopCommand.java delete mode 100644 src/main/java/command/real/tpl/atmAlert/ATMRSSReader.java delete mode 100644 src/main/java/command/real/tpl/atmAlert/AtmScheduler.java delete mode 100644 src/main/java/interfaces/DiscordScheduler.java delete mode 100644 src/main/java/interfaces/DiscordTokenInterfaces.java delete mode 100644 src/main/java/interfaces/PostgreSQLInterface.java delete mode 100644 src/main/java/interfaces/PropertyInterfaces.java delete mode 100644 src/main/java/interfaces/SQLiteInterfaces.java delete mode 100644 src/main/java/interfaces/TakaoLog.java delete mode 100644 src/main/java/interfaces/TwitterManager.java delete mode 100644 src/main/java/starter/Start.java rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/StartBot.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/TestCommand.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/beans/RSSLink.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/beans/RSSMessage.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/beans/ServerDiscord.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/beans/ServerToChannel.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/beans/boss/Boss.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/beans/boss/Giorno.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/ControlCommand.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/music/MusicCommand.kt (94%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/music/config/MusicManager.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/core/JDAController.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/core/TakaoLog.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/core/TwitterManager.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt (100%) rename {SpringBootTakaoBot/src => src}/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt (100%) delete mode 100644 src/main/main.iml rename {SpringBootTakaoBot/src => src}/main/resources/application.properties (93%) delete mode 100644 src/main/resources/logback.xml delete mode 100644 src/test/java/testing/PrivateMessage.java delete mode 100644 src/test/java/testing/StartTest.java delete mode 100644 src/test/java/testing/TestCommand.java rename {SpringBootTakaoBot/src => src}/test/kotlin/it/discordbot/test/DemoApplicationTests.kt (100%) diff --git a/.gitignore b/.gitignore index dd8eebf..160d30d 100644 --- a/.gitignore +++ b/.gitignore @@ -52,13 +52,7 @@ hs_err_pid* .gradle /build/ -tokenDiscord.txt -*.db .idea/ gradle/wrapper/gradle-wrapper.jar -src/main/bin/logback.xml -src/main/bin/jsonboss.json -src/main/resources/twitter4j.properties -src/main/resources/hibernate.cfg.xml -SpringBootTakaoBot/src/main/resources/application-dev.properties -SpringBootTakaoBot/src/main/resources/application-prod.properties +src/main/resources/application-dev.properties +src/main/resources/application-prod.properties diff --git a/SpringBootTakaoBot/.gitignore b/SpringBootTakaoBot/.gitignore deleted file mode 100644 index 63177e3..0000000 --- a/SpringBootTakaoBot/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -HELP.md -.gradle -/build/ -!gradle/wrapper/gradle-wrapper.jar - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr -/out/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ diff --git a/SpringBootTakaoBot/build.gradle b/SpringBootTakaoBot/build.gradle deleted file mode 100644 index 54c80a8..0000000 --- a/SpringBootTakaoBot/build.gradle +++ /dev/null @@ -1,100 +0,0 @@ -plugins { - id 'org.springframework.boot' version '2.1.4.RELEASE' - id 'org.jetbrains.kotlin.jvm' version '1.3.31' - id 'org.jetbrains.kotlin.plugin.spring' version '1.3.31' - id 'java' - id 'application' - id 'com.github.johnrengelman.shadow' version '4.0.4' -} - -apply plugin: 'io.spring.dependency-management' - -group = 'it.discordbot' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' - -repositories { - mavenCentral() - jcenter() -} - -jar { - enabled = true -} - -springBoot { - buildInfo() -} - -bootJar { - classifier = 'boot' - manifest { - attributes 'Start-Class': 'it.discordbot.StartBotKt' - - } - launchScript() -} - - -dependencies { - - - - implementation 'org.springframework.boot:spring-boot-starter' - implementation 'org.jetbrains.kotlin:kotlin-reflect' - annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" - implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - - //SPRING LIBRARY - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web - implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.4.RELEASE' - implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.+" - - - - implementation 'net.dv8tion:JDA:3.8.3_463' - - //RSS + HTML PARSER - // https://mvnrepository.com/artifact/com.rometools/rome - implementation group: 'com.rometools', name: 'rome', version: '1.12.0' - // jsoup HTML parser library @ https://jsoup.org/ - implementation 'org.jsoup:jsoup:1.11.3' - - //ESCAPE UTIL - // https://mvnrepository.com/artifact/commons-io/commons-io - implementation "org.apache.commons:commons-text:1.3" - - //POSTGRESQL DRIVER - // https://mvnrepository.com/artifact/org.postgresql/postgresql - implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.5' - - //TwitterAPI - // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-core - implementation group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7' - // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-stream - implementation group: 'org.twitter4j', name: 'twitter4j-stream', version: '4.0.7' - // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-async - implementation group: 'org.twitter4j', name: 'twitter4j-async', version: '4.0.7' - - //MUSIC PLAYER - implementation 'com.sedmelluq:lavaplayer:1.3.17' - -} - -compileKotlin { - kotlinOptions { - freeCompilerArgs = ['-Xjsr305=strict'] - jvmTarget = '1.8' - } -} - -compileTestKotlin { - kotlinOptions { - freeCompilerArgs = ['-Xjsr305=strict'] - jvmTarget = '1.8' - } -} - -compileJava.options.encoding = 'UTF-8' diff --git a/SpringBootTakaoBot/gradle/wrapper/gradle-wrapper.jar b/SpringBootTakaoBot/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 94336fcae912db8a11d55634156fa011f4686124..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56177 zcmagFV{~WVwk?_pE4FRhwr$(CRk3Z`c2coz+fFL^#m=jD_df5v|GoR1_hGCxKaAPt z?5)i;2YO!$(jcHHKtMl#0s#RD{xu*V;Q#dm0)qVemK9YIq?MEtqXz*}_=h7rUxk;@ zUkCNS_ILXK>nJNICn+YXtU@O%b}u_MDI-lwHxDaKOEoh!+oZ&>#JqQWH$^)pIW0R) zElKkO>LS!6^{7~jvK^hY^r+ZqY@j9c3=``N^WF*I^y7b9^Y1eM&*nh?j_sYy|BrqB ze|@0;?PKm_XkugfKe{6S)79O{(80mf>HnBQ#34(~1_lH~4+R87`=6%>+1tA~yZoIm zYiMbw>|*HTV(LU^Y-8x`9HXY~z9@$9g*K^XB=U0vl0(2qg20WAtt2@$xbznx$sQ<{ za5-cN#nT4jm=e{bj#uy8d$;dF3%#$cK8}{$`MLEw^&9;gXiiG?9(MN0QMDR#6Z5?< zGxwc7yuUZl9+2NpqF`phD>1E+?C4hlFGsd;XAjPBFq0uCzMuGXpbg8|rqN&xm~|8FNJG}`RKnZg45_9^T=D3C+BKkzDBTQ5f5NVs=-m9GYb_yg>yI~N z0*$o@HIrw2F#?E!Q<|P|4xTid-M&g$W@w)-o92)dG-oJ3iY_kQl!<648r8pJ~dk@K5;JAztVD-R2@5QsN81< zBR&WBUmt~pxa3IT&?&COh8s%j+K7_~L4V@3sZa3;>*oXvLvzipOR9^fcE=2D>phM^ zvv=|`F^N89g;#Aoa=I=v7GWvM=Fk-s)+y~JwK@4LugDb99J*Gj2r}PUwiq3$wI3T? z$Fa_@$waHnWgk?evWmc^YCUkVOZ1yzvRMc-$tf&FYc@FfY;a;&s&5246dJ&Tqv8xR zhT6&#qzP86Qq&7b*npvK#XBnZ({8EVhH57jay$X6=mEmQ2$GzInz#n+#o<`hHp zoBDSv&BD7%zxj(!Kl)1|P^V{%w`UBw7#%WoYIGfnPmF!JJf65-IYz76!R4?CM+OtM z7oSzSn@U-1gXfaoz9PEz(mf`xuMJ@(W-dpaB4+b(bn!YP*7ba#ST?r z;mOda0fr40t1SX&d4+6<-qeCdm+8(}u!9~db63LUBj@fmO%XHcaw)VRp7#d8BjOjD zOjLB{uU5hu*ty3s+Z_6ZFmHC>{^2}$nJFHvurpdoc`^C#F|0NE=Jj9Q&EPouZdXOB zj<5{T7`zqQj6!NI>DPqZ873hK4Xiflz3}>KZ@5Y;?0O-+kpd@pM^s!ZbDV_R!VE;J z4U9w~$y98zFT`I8=$iI3Z>@#g%EPG<0wjGBNE2^j=f0Q2;Sb~k?!z7W^MeG9N!eFV z1xYJ>kv&1bu7)T+**L=evIl@ZZ^I9u0*;Fj*Js-?R~pef6{9)Bp)kY)<3Sx#EF=&Z zgCq?3a|;w@JN@3%m#VHR>Li~JGjm!{Q*mS2;wa?XpA0Y`fV!1@twpJJLZw_ zpe(lnL$65kHnC*!oz)06cR%I(U?wiSxl-R9IkvSHM7c{?A-?fQ3_jvj3=&vE^(Mq! zx#o!;5dMA2jr4v#&;Q&&jeYUl{yQvyRpi^jiu&xlWC>JK5tvu5{(12Wp?~MJ7@5G6 zJr>!3|F=Ze0Hl;HbPi91KJ-P0TQw6M;X0H-rOBW*D0QdQZc2SFFj@;9go1Z&^4sQL=|s#bi6*{2+D&M&na)7^jE!`QRF@>ND$+2NWl7z4%u@^YA|4h zO-wt1UfK~oczniW<87e4sJf2L90Sp8g|aq#tmP;MS(Oy``;%4;6d^H)aly9vR?kal zW1$^Q46s;|tSOuR6;OQt>uisEn;;mi0G&yQ|AoN@$FAJ=d=KQG7+0N4df@*CVS&Ff zj^+Ocqk@yYho_*ci-oD3i>0xli~YZ2O^ULvJ(3^_FG%vRsimW8{fd;WwQgnOQk?|@ z8K|+5kW7*l@?sgKjKQ>97)(&IzR5vS&zcyr|1bUt4~TLkDXs0W4);Ht&odp)=Kf!A zPau81Jgo_0{h>jDAt@+!8ydq}P?wZ6SkI|3uv@K&VdjR51Gu3_O$1O6&Y|tot7k z`tSLXH1lVvG&rRFfT`NaFt=BgIcykY65hul3hE~It|Zh0Fa4Z?RAExWF=3EroklV`JFe?bjw|%I;N3u#_3at$%`y9ZzUl1Y=Q}W#@6S{@3s@!*%fy-2Xe;nq3ztpVEm_%q&E32wfDO-f3 z>p(AtkpD2eI}`I}0n^qfVpB#PLqR3gqSz>QDSOE7(tN9YQglhMRd7A^?iF+t5- zx(-L+r)T9>S%lN8A}26&I~(0|vW-o3 z$n;7gHsXj@bX)M{VDmBIH#l9A>$r4LxOBZ^3Qc3h?mrLMCFF@s3mgzo94-(L;s1QV z{`CpvXhIsGta^U=S++21#RO|O(qd@9tO=F%W7s%ikkAE?1fvOpjyw^>6o)L=@^DAR z=WviEvx#GSk;n-tbIWaU*=D1Z8HULEkXSlqw*J{}mh~#O_4<9j-5i5^>}?N!Erq=d zna_Unvip8>^C|Ch+)3XBYLKJ@WAL*Md@hDwz47_7@-@=RPnfm0Ld}12$oj_zo8M^P z4LCyI4cP7bOAyc(f`4&l9aSd3+H@YM1H{)--ztm`?=P+oO(4M!Payw*UX{sRg=zha zmrI~8@LiSZ-O7_2;1}-?VW97Df2HZm6qCnUvL4jF-aUQTkE{rPcmvw6BH#;oT7v_A zkQe$7chsJkZ^%7=fIpeo(vqH1F<;z~+o*$yio6bULB0EB}G zjIxX}6)YrZJ%~PANu+)Qie$^h@|;*B!7mUc>xqG1pd~ZOqMI1lzxQ^Ea>5E+Z8;6Inn;RwQZICdr-dBuaL@qfEv+FgC+1v{EYJhQ#LSaDw5VAqfL;jHS39n9FV zkUqE(gi<~E)L8CbO2%cl&*i>crLK}N8x6*-*s6zD#k1Hk3rp0e$QeXrCn;ADiqAEb zj*|vNd^ot09Wz%Hb7u5)>LSaCvv@q4wsGbyjA4y7U{#mQrz5y^ExmQjlcbpz+vqWz znL&o|u$1!{%EQGlIfUfrqKBG#ti#@zK;ERH7`b!B(0$xEjL;vEX#jHrfK5h+H)IeZe- zb7wQR_Q_G*WH(JjZ8EVfOqD{VUw0xC$TZ_s&K$=vWjt8h4WsQkXva^(ugfzpQ-u@C zU6x~J!he`dq6oENJG9Nec~N*Q;kiHURO+o#=h>&&XlRjHi(`c5UasAkxHvW&u%+H? zYuP4(0{TDFd(>C1qv6TJiOa5wn@sO_Uh?HaHZP=uH7bT`aUHv+$l5jmV#q8Pcfee$ zn6U}k)@CsesYMaa&0=O}XoDmBi{|Z;9s1MTu4~)YoekxMS~>zLapgGsE5Jg%Zj9X0 z&~6s#R}0WC@ZU9PG$w)YrADo%52rDX)|PoF*0nL{tMTTs_gfLc(jkGOqvvC&G?nz8 zLITsc&IiI!#Z^o}G$M4_niI3H$m1{rYGjEaNuAq*;64P25*dX zTS*dkTrzjoXR19%^$;@G3P~-rMnUS1d<* z(r)8+V!fo-3x?x(>(=|c?H2pU9vg|ijd>m^(phdfi!%y_PK?yhgvAb$4IKHIa%RcH zU3@0{m_7>wQ63SY3J2`glg!sN=ZSXGUPtw$-A=)p7Ls`)Fq~GBy*N!r?MPRSp4hwy zssj6^BfREg@js;H#v}!G`P$%5LF5o7GzoYN$p^u(wUc$W$Y?{i%*QD^cH<#vJQZvP zevy`$&Lt9ZT1FH_+o6VLkPdo`Cn7FKPasMcR=SI^ny=q(rH7mX0`rAlsVv9S6_TY# z-Jc&_p041Z$uZUTLB!*pLRn>kqa2B{IZoRRx#cXAW(epbZedV@yG1y{#trSDZdSkG z-~muhMP4nSTi<=cR0>%8b3*9HH3hr|l{x z{m3qgh?db*3#m6AD<*}XBxZ5`p7))Gsc)O)jy!YHzLYXZAgDH*ZOg`wYRQfr3DbI7 z%e|J3nH%m^bpOJa z2{VeU$B}`BFRu_DdKm*6|sA>)-a!sa0ZPcXTIhpA$N#C65szy2(vxkgFub(8i_HoQMWkxbns9@~I zh&g;kS`96_a%M8>S)I>j7XsgF>jmXmOUq}FrRiyNPh-k6$$rq6rz?2{Zwn#mT2%$V z0Yc(5d9G%Py6DAfzB9s`2m47eQ7L1yR$8KS0F#B)VPDPPQ>r_U~@ zSc`s+yRlZ&LPgjpW;vy>Iv*Zz5iv`{Ezg^rPQj{Z#63}Ek4r158)bg5VmPW-B+9RU zy!RNL$+AW#9pi>%af{iq7usOsyF^-*ZD(o?bCp5v(TJGTS0P;v&obm1<=AN9Gj1P4;}RO!ivCDYdF`xN)NNq)ny8{Kimq!0Xjo z;k-goG{a@^D$`S&>>$d3oF$D$TWhgrLV5jg<(psV7=t43C>N|#>WY)oTz;R@84qi+ zXBX=lBPLHeyX5kQ(r`41R7U&4vJhs4@4Q0)Hw|S;fmbfu6h5)%(QMbwCHKjFN@Pz4 zdZa(ce(d@V4XTtzWiXT`RdqkYZ$gK?QK#&F%_n1^35F5JE`w|V1zwyr_{z4RFRyia zeS{Bi3GRS<8*JnyThZ)8D67nkw>=$A>h#@|qQJ)|3IFg7;ih z_Jt?lz#vQ^m6!F&G{;)0Slzu5Y!+g;TCDceP4tuRfu$*2ay`)K<3z^GPTh`z%2>;m zOE~rxHkku~n7GWRb_X5qjlG(A*fTccm(4)@fzp|)z#kNT(cHV!J#oywSH0w;)jp&_ zLZ4Fgnet_=kt3Jovc`s4-{65D>JW?2XDMJByVLRRFliXJpq;lxhsBd}Sm6x=-h1!XFo-fF{Rs7%xS|J#feu1pb^oY;! z%jnRPw2M0+Ux$ugC4Qm2P!Wwi1u$Q!DkrG}e)uSqRH>W}M0DG5G^9b6F;xs4z93A9 zhParChorwS@Ci+p_k9sjm3ca}1W<$ft@Me*eq;xb!|+({8H49C&4B?DW?7t_`Kabq zb_L&ANFQfONqA(HvkFnmJsEESmSo!3*(qE2Nc9<|e5A9q5?IQgLd01GVHTn(TGn=Z zu>qkhY*1OUA00{jS+CCM{;e{Gm&-mgZ;zqOU>Nn_{PIaN^)Fybd_nSNnm%06HQd-( zWe)E0_f@yN=v`$AT?-bSz|s)6Y~T*c4)3s680iBud)<~-Rs=9NC+sn9W+yOcrVfm9 zoJcIo9I)p`l)@xa4qJj#S^Z}@o-pefqwzT}qFm`>MrYrNBg4>Gb(1>+sJ_h9L< zKb5x9ha%2oMzu^ma(dIFQ%Jt@e(`iZ*^U0;5f6reTPcAW>*;BJMX_dRG|4ZaJ+rhz z3)95}5zEpv&Z!bY* z*0R?IX20l}_72O4nEE&(U|xi;FbVxl`fQ?Mmfo_~Fs2hOF|x-8W$<_eIrEBx@r@1d zQLKaFnBn>QsrD^vHUpvsG`BxEV$)j8X-1}~wb}>>_n@`f5S|duRD2Q4@O&e>p>mtR zdM9%8l6y-zcZbU93MUw*tbtm{mi!~c5MS{AS@U`Z$P^a*t#v2<8sq<5^ZxCrm^+y| zJIh!)yO`SjSNGmErXMO$07dkMdeI71Wb#RLPGB=tH2$Zk(z_&nX*e;n@t1ZKUw&L9 z%Z3|zSSM%p>N^0mexNVtv_L+6sFKc!^l(l}J7ZcF4RSOXKr?ov8yQ%`k@sZ1o2UPC zP(hXJKsS@w@b_nhcn#9@2xvuvPQ6|$nPGto5fbfTwrGv1W+U1+%D`FHWL6i44s&d^ zG=a-pERGPm-20sMTEP2{f8wR|Djw_t2Lg(K0Rm$F&v->WjBQ+xG&c`VnJC>DU4M3<^B4N-w3P_`7^%^A*~2fB<_ zq7ew1(K~p^A*Bu-FC_x5BQ(l2J}XYAF0IVeonTH|Y13KS^rzx;%?llJu}{q?EvBMc z_M{BJR3R<%eXb^*G`;hKQ-7^mwY1Y(j0d)%FBBOb+xcH%&00M?gh@*y`7~nCi ztkQlxBk&TXGM5~epV?%iwQ(&^5AiYLJgRYz+Vsw8{SFP|;HPfm_CR*uQ~Z3v&Or4! z$3iVAIL2_cRI<)FE^^ZbG-`%sL8k8aD1LyMDZNT#M}zOy-C0JJ&c&@v*;(qqi*W0E znr)7jv$(6)_NM9LB@qS`{L!_RZeoa25smlFpU1u-k#EA3;4XW#laVPWf)Vhadr!0j z>Vv4Tvz9Nd0)ei{rn^M-;bmQ{hv|OHMF|Z75m#?kIByz{Fuan^CG5-#c?3G6G@EMq zR#GLJGt;EbhFWmzcA|WWEyecCWx8#)py-55KX+1v4k;XF!FjGIz?0pp^a}Kzb=}1* z^AcC*!>YKR40~hsuF&Vy#mWx3Uuyfht+@db%Z*VBivV69{ZaT^9>9`0`iaYj0^-{( zF)sfIG?!mtDmnmI&{2D|qOxeijq?T=B6O=#mj!2)9V(Z_*D_f)MZ9PYDATe35eAI^ z5creHr3(e?ts+)=40_9*d<;^g%M+J>aI(51R^35%6jaXoJW&&`r?Ors5lsG27)<7LNvfz*K;lgRyezJy^ax6*kF zu^91WyXL`hs)|>UC7wDVwQT2(GIY*{hud(pr-tf31>;{b32G5T(uUvcLc< zRUbUtwhL+cWSQi)mTE^-!mlBb^wKib#$2^lKjBJU z4@3Mw?;*B*midR!J&_Y72w?;8a)~7Jm1U9sa4$3LGf#B#nY82WSw`~6UV!AEa*52g z!XuoofBneZfe*%q8!FW4?D!)F{bYdrbSDkYAjHTMDIctl5P*qzm0a-iId7u03r}rUwk}_lceAd* z8xdF8b$w}s@q?h!N-NBz}B!nuncB`+|J@uB=5RD&7;suL0fEO@Ybl2dKSWIpPMqR9(&F=Bh;TL%-<07d&H5(P({Q+$bv(XJ~o2xXoxL3Jcons>6UJ~6NCfP z;D`oMc|=yr0|u*R#e!TK%WQ>A-sKEHYbm?29k1KP#%0qo$*V~KNdk$ z^aEAcBOAX-oU)c)8cz8RgVNLDd)N>*@6dh}sWo3zn2sYhSOj*IHCl`{`p0*F0-yBY z3sR@pW;{HM3l8~(?>!KRatr|U`!%-ed5*Xrcg_c7Tf4sV;g8e(5Xjp(0jAfOGCWVg zj)&{3vyWIH-UsrAmz_~vA9r|ckGxZIv@OdfO8KP_jm0{}OuSz#yZL&Ye4WB>tfWt_ zdSQtUq&VLFQf9`(Dvg0OCzA_Z0aOoZ)+-JZ*T4D z@Ne2)c~fpv0D%{p&@H-SiA4YkMM_&@0SVngnjR%0@JED$B5=YTN`?t4%t$OwSfrmS zJyJf=V*~tWY2`&VGDQH7fi!bd(V_E9wY&fKCjhw*1`XxmAR@X9ij0Ahu$CY=IJ#Ja zKPn$$mQ;o^{HKDHiS7t=LK*3lM7k-44x1X9`yzM9^3;LT2E~nu} z#b&AUO4Hx)bo>lM%zF#bu~LHd?YZp-P@))u7Hu-cz2B`%zeTSz;9|ag8i8K#f|*IGV4QhI-2m+S{Q_wPPeV z%xeJy!tOsjnrWKWK8ny$s1AT*39K%=7@#@<1Q_1Ma*M!yMcG{A-WKjIRbH~S$yM_4 z8=cWO`)@i&tn(YDhwt)nM5vilZa_(p6Uw-3ah3|TyGp?*yBFGAMXZ7Bb~k(T?+9VX zo!LDs;97~x*f6LvJ}8p$EZaVeAau9FAty%cN;$@JahZyB5PO0@vHlvO2n{krfv2c+ z1qx-5;S5CNvGMufBmgOGX?1QsUG*327NC$+Wg9wA4mt!5bMP;O4W%nKLbwqz(lD@y2=(>{!Nix_|9#@ zh}Fra#Xk%%*c$!*-_$Q;`=e;De|0Ba7(hT&|2d=k*CAH_mw4s>)}Q>FzR`g2L0-lD z=BIf-x?lfg!(apj>|sc42xcR6u?7y)2)mY!kr*$`XA@A(ybv*8UCUybMYm8Y``bLT zHoiG!n*;J(ChO03srOCyX7tx?4v96+p1!}v%^%;J%}d`=YZvY(FjS8c-(ey~?(SE1uR@5^^ zyS!)&h+kc#tw-L`t6ztY03E)HBmWGQhd_Ujo{vNzU$qe=Um-z>5hs}n%}8-zT%`tO z$5vbzii{_qK9Y;4@IWy;$v$rU*x2c{9X;>%Ac?B$C3(wVtN)OSFKD*X12|6^;OQec zj1C|L(^tDiMa{ZZMb#f%?S2U@el11cRl2o(eZ%#9Ddzd8HF+pT-%X0{xfzB>`B2z! zO4IQ>8os`JHKz9~JScm~2+Z>aKudl|qxKHe9p7Q2_72~ueBk*j+=`=uyd()+KXqT{ z6x0g8zjZ$0ZOpGOx|Z8N3%Kjo{i1hK;V*zF^0FaWvmYjINMH+?fMZUre@JI77f%Wm z$Pe#ovd-`3URusLR?ZPyZ>sCGCVhM*;)+C+*Ft*!wkeS{4H&V_SMUoZi~;PZpkxg{!zF zXrl-{5uTfs5$cvjJ1j6o^e({q`}3u`c&}E}Coq<2;p5Rg1oSn&eOMgbm>8&vM;8GW zfFD8!G-hP2lccpLWs; zH)ywsZ6ZS&M@L|#c~t69fnMmu*BKp3Yiy0ZFpSz7hmcWacy^o%I^#~Hp6^hut5F)Y zlAVNiWZp6s7G_pPU~P@)Il~U(>QgEtNE4kzye8JB@|u#N2N0oI4A7%d86}XRMUh5o zR7RK*<%b_u-1ISfTZEL?zlbc4nYO*aUnv+o=78iHP^kzQ!sEi~WUDiYgR z7V5D`M8srTBp!SScGhPd%9)bQJy{DJ11fqe*!TSGtHWuzkCJSv`OEH?E! z-Ac2^>4XCbQ*y-eu(B{#*Cx74N&33NtaPP47MIh+t@o&e%}Ar8?N8v;wmMHZ#W|V0kLC!Ck(-g8&7Urzb%cNnrrzdIU&uC5qlhT-98O2?=U zG5@ZulhTE8bH&=`WtRTYSY*BMeY4NDXE*x}3YT%xaKyo@=bvwgFxh~n{ljB#l;BBt z&+3m^LH2t=cK5_*K(;UGGlcV#YB9oHQ|P5@Fz73aPb!<70FOZt&ViO0NZNr{ZDtS< zZrCf0IL6=*Q3HptBWf@&TZCposbunl1K>ffz{LXCv<9!29L%(LSNZK{moRD1-4|h; z{Iz@m5tuEO4rRY8QkOqelO$(Z%aT5o<>?!54CRZ~B$?uNm5k^RaKXJD=jT?ch-Eg7>z)(>QSsK0qCbWOZ7vhH#1xqA$db$yMD5*NVTm1 zT8{Lj?+I+~Nz09+bAc{OgHFZlPW|eUc-G$+Y76VK*P8(qWu3dQC6YMdW1) z>`P}=c>;qZXFD4#<&+RC*YQ+T;4Xz&x-R2vo8_-?)LR0i2EDi~F-phJj#_)6E_$l* zx=Hu$tpuIFog1qLo}kALN@=2=SoCUY9H6XUte;w50x5O40w$r>ACKy*rW+62yfe2^ zbjcrgG-FyQtECNnp|F+K+AsA~LQCr{%PoPkW);P%>S#k~pA7;)-)e7p0&9dxV?LAG zoq%UK)6`0Rfz@+bOs5O%>B`dJ*1?J#uE}lU=YA|1;47Q+C!JZT-TcrV1adsRb%)L! z)rAdu_UZbSotn=H>rLpNLUFEsTUe%0ySD;lJPmI-iqH@ape3CkfCab~&vjG*991?Z z+&Ho9jP>l{Srw;oWqbahxII;m8(bw~SbKS*Sn+LAO;R5{XK$M3JvKr-{^nocdIOg)lu@r@zam`OD=mbo)!xicn} zfM8J;L`b@D;}Ti z5~T20ZhC+}+N{C^fJXI4yu|DNjFu{@;|bYzFB*~bwRncTnrW75*y=e4T0iz;o_-l)r(hB$;YVkf4$4%AJ4Y;nMLGPXapH<-7 z0mez?-^6+IuMz#{1X}XH#Do7zoJIfkdE(r-CCHkobql7S4EPf8g zbstfgZYt9qBr?3kWy<3M_Y2}4A!#|#w$U!P7%w(;gM7pO6Djv5IgdXC5D+`Ue~;A8 z*~QSt=D$ReIqI+O*y^ZXxvUEmckPZ_WTLVQSQliCO4^#4!5q+%*U6a^a#o{^k{~WL zvc(aj%tkB|N~w*>sVxYt2aR=xlq|Fj2P|{IA;2X9(57Mfujm{QT6^Bii8PaulDC{a z_B-Cs+mD^kyu9x>>cv#U(xDFrgpg5obgO4ud7yv2BS8-54!G}8Rf&woNILG)6!0Z5M zQeHbVa@~5O>MH<5QT355_-nOwQ=_7MVb6rSKQyE-4o!$6wt7)W(xoqjr9s zL+R+|bexEcGvj(swOEDO3`)nuz}(F-ji)+Z6`9o@T_noqb6>Z2sLU)kr6zFgUxWny z)r!RS-M@`YYl}%M1LFoTNw+yyC^D^a;)Q#7Hm$Yj8K^ST2D!~I(n{Z5 zGuSR}k~-)cF^;?nTCi2Ud9BOQHvfLl|Fv*qg85itxyTkOt&AM%Esz)Qc_uO0jI*Sx zJVPB7`Je;@ypeCK98`iH1+HGJKa^1m`=DLGKvu~+zn#9D&aPT+%AcGfX~)>yDJpb3T(*gi4vGhJUq#(4x&Tr4zaP^_F1vmjH5zp z61%WASsn~KLvhzC4B2}mH6JTke4y))+glL>+EQhxt=qBi`rBB2AmWgKx@U?*o1A*E z<19UJc9$LG5-~f}Mm$lQu;}(6103uH-FacrkDs1zeXVLrvj(_JhR9WUO7XRW`)Nuubqs>pFc_)(l7vIVAeZfB6n|Dd^!}2P zenGoTo>+QAH!OdvMgo6i9wdoRx$z0Njo4Mq#v4ZH98jgQQwM}@;CV!0dM-D7uy4iR zPvjq(gZjmgK};G|Xw(!Fc2nJb7oth}vXUkC_2x5SG}L~E-KxCzk4v6z+a)o?rA)O2 z-hLU7Hr5*_nQY}?IfTjaxRtc#9`CN_(!Z2a?hSn>EUFVa)M!jMt6y?Ol5*P&Du9LX zqP^tmNgRv|HD_&Ya%;>S^CRJRbz0NIHDRuFq`04DP;je`FyCG2XZy}Fq7{#58*-mT z-Xh=qk=aj-S{ftjJ9f$@de~1gZI&WlSH;~Ar!mK+&ajIY-wS7?!FP%>G&VjT*h^!zJd@9eQ&P~ zF1FoS^K0ch=_Ki}gCul$g42%YVg@HVnu1F);pGZ)V8%@mB=W#NGCH;9=dldj_j$p@ zTYWuaT@7Ey+wH*Bc6lJq3y(WnP#TYm4#DM!TQe+9SX{P87DtzyzBV3M zl}DQ{YIN5|$68kJ1;$79k1RK}pV&Aw9vYTUU{Vz1WK%b3@O4>XB}H9mDlRUT4W%&E z;-)Q_10tcU#j{~}O?AXenbg3us)}FQoqkjahf@bMUyfFpO&^5v`KP71>2u)q{8ERK zF)sV?O4%DE+CaBda3W3_B7PvPFD<0N%Me|C$@u0`O~9c$EM;mE^8GkH*_aTM&S!H3 zcYhAS79po(s#k!z(Lk3GPC1{xM_IwWOh8jKw2vXgtKC36IKdL*okNA6B@%7896j7` zLMYUa4rlxdR`!uu(>VVYkVVMa44-B}^bEF`LW=M-0x&OK)My;JLIWxP#-uS>;dYYD8CoZ5rG(uRHv!f_hSRMQ1-hI z73S~=`tT7o8^SxR{E|W4PUwNOSaoZ;Rl5sDzMSKZDYeQYD3bjP`EyjI>s%kE zf7?XWL&JV|@F4wXBnV~g*Z?H6E%pqZlIDKoGAm;-W*$HEAbuRt>CLg>LCZ&Ef;I6+ z?>F#2!}q=EqYd5PpXyAgfq)49n?&Vb;rrkHJxvG$m1ErRZ|6hZSO_74K1O*H6C^ey z6j(wD7Elrx5LF*Zy~H4Fz#m)^tEv`_YTXspd9I5AK~)tb2H=$d>`kk*7A^Cd&X(H9 z(%$dqKXhqF2=VbZ?>p>Y-oE;|Z*Kv-A}lezw@TD;$!5tcMJ1TT(`z;?ewMMRvyOTb zr^YOJHw1qBg!G=Cfz`6fW{GL{9Qv8S^yp3rX|+d2mSomC2PK3&qEGV69+_cf-k#vI zOCG6dVz)N*_>;~ir7D>nSoo(U4L;Fnai^YoRENk%_ac@P#TmPClb!)1sCati0Lez< zgfue8lBv9_edXdhBq#Jqt(LS<01`ZX%GZ*O-UzFn-VAjYM$M8(N}3r6`ifjqsaobT zuwjhAOKg~YS_U(VUKJn%kBvu%9Qjd?D*?Nhv3qMw7K_~)Cw`xcUiHq4p7tPrgpi&V z?JSDpYCqhkS%O*ru&GOBP%*|>Pm8eoxJ1<_I_z-4KHjV+joqm#Y?H^Q6~SAMEpKuc zHMQq-|Gt=CpW?M=1l?mi7-Rk;AK(4}y5zNBB&)kQR$baT!R8}j1l{_>m|oPxKHZ-P z!jDSlYig4JRQl*13G-73#VKMWjR`SH4-+nH{w^OeDua=1H!w29l)5stPFF#*$w%|} z19g%*O{Gp(tJMclS#FujI7ktRWk8mcRgDF~E^~6Jmj@|UQ*2Gk67;Y%jNaG@f>>78 zEZNdTm1IL@0fiMS&}@99e15@5OuBN3NX`q32z#(Ue7=u`Y;j})EW)*a!AN7;lz>qM z9cAp030EVt2O>-?z2>psgQmV;2jgd^>EojrP3ziE?8w$c83ZagFQC1xQLup@)_9A5 zFUG!Ac4sGx#(Q-p&PifevPDJJfO<___~nfGV{kN4kOVK{_JwfpBW}j?=1h>et@7w} zQTBd<^5+$C*+C|BP$RU(>}Z_oMsJE{#yONYEHwh8+$?))UIa?SjBu)p#np^Ecx)67 zE1)-vd^);a>O#TNA8ar6mMPU5Y7w*@=h{}8F_z5c%R|C4L4gBrfz6^Z^rJ4SHfegaAndFblMlRsp3 z4lUTUGdO6(noT7p#S}hlp~Ox&NN)k_ zEdDf1Aq02V?P^ez;kBOj@zB=AZnoC|S7wXfKw*Hr5nlFjl|s=q#(ca)$EKZ_L7+$2 zWbIKp)VFehDC7VptF9eyo*00op0>zupw-QvBtpd4NY)cNqYmPGVx`#zLQ8M>3x0T| zs)-N*Y!>7iSpz;*1uU5%^ywk0HMQ9O#rvAKmb}$-OiX?M1w88`I4zYu>+#aKa4^Hu z7m|-e*uj9-#2UJh?V_d~Q3WjlH)^Qpv9$5s&&)bX(>?>%Y8bg$7JloMIZKwSO^z4~ z7v5ZJQQKuEA9F-V&7eyx4n$uzpVCGHP`<8?*xmnx2qQymriEHl&o6D#u@oH&+>pM; z(^bpfoD#^I%0xc3X=cJk!yE(7?K4sxDzPQCUM_L05FwHGj%Nrryap;bVTr-*==d*bm7vi=Sl@^}l~38vo+;?I zRz7?{wf+ml$MYhq-)bp%99}Pp(W(!T#Vc+c6+RF57t4s5OOwlW`&2!utu&H(lOnF_unxBMNC55}SC0{9%n8;tD3`tjW=%@)=Aa6;#IH zGNqHma9Wx*%EcK})6I4&%3!J|CRrjWjJ~B-#U%Nbz-R5m5XpMNq=vHmEY-rH`6Sht zz*R321~q^9c$DGtyfDJzSU${JkuR?Exnxqs!Zv1_)T zKhRvSo(sQ8l<_vJm-#Pja`8&Voj>^g7AU(v^U2w$5H6ecp+&$~?57H=T|5_hE0E*Q zm&MYryNCU-&apqrV(HQ3vzvca+o`;_?Lv+C*prFLqw2F;eTC~mrYUy*d0MNfq86PA zkrFVo`NHmS_W*0z14Yn`zZ^8<4%p_}9o%&7NxKm)9@h!9@adi5Zr449+o`yx^ApIF z%fUy1t6lJ9?~ag}_w~@^u>lh@qbg+1@k}%t%hOYOA(su8y<-=dO6SLE_$W7{B}RC{ z-eUhocJi#B=4WlGvt_DGu=|j{STWQ(XBVSBlU)91)f*qyo%VES$jF2Ighsdg zU7H9ohegXP;W=BsskWBmzycZhN`I@qm4QD2_`XPpI7O*o>`M%VgtQ3rTDVXe#~=G> zF(JP}d(lJ2gfv}qS+tRlbJhy{67>pyAsZnMOteoWj)_FxoJ0@bLQopjNMH>AjLO3| znzN5~jYDKE{&9KBkLH=#@PoYLPl=sv!zLOm)(sN3iw~Uciu;?FXRdESu~}jBhfs~i zHaY}3kNosmXo(dF>Oik_-Nt11W%e*43Kg6t^O>dBIG-ee*Q6Q$liqx_`PVw5Xkq46 z^Y$0>vD&B18Tz|j&=u*0k8TM4iZ|KQv{y0{pM*k>KI(B>-b;p@Z^F$HA7{$cXhL2g zp+G?3odnNXz7F~$r4Es1{+sr1Y88KD60M6g2SDXW-T4O>e=tuMiv<=VBT?^G`tW|f zV!Lv_BIcSHu}wtPaD#X>^*$Um)&8*-2^(j$lH4i#i)_s9!fW0~>&*9odwuJC?VF2V z+V0}3?-!7$#R!*pnf#0J5*L?0N#!^DH+e-o-(&g=zHq>YK4Y|Ew`*&$cmW#^?@lRw z#BV;tYv0PEdXptJF8`6$iw{nF@jV`oK5;-+Hln{+3H$Y!{gNbzf|QK%-%a})AM6u?*rijx|PRW6H@2oxF?I?P-Q1+hXI4|+^fl7l!HgYoKE-Si-WKKt?y2z21#%FH})#`uS- zVvt)`37%Ta{QOAEquN+7QdJbw>t$!Q<8MLD^?JHCVJsxt9 zu@Sp-W=156D{AOlKPaCQ#otlRbjmU(Y#sFylq^iD>hL9Q!)>dkLxUWlRn{pmx3U%H z{c+<$AX?H(Lj%UTjegLNSxOlDm(iZ+Oj*ZLfNDXFrbkt7I-VD|QRFQ@diIxA^rZmh-_IO92K{{#cCT|6=Sbfa7SBEQJF{~j{&jA>XvQG{`-)wWT0&d)|_-tW@EDel$i>}7&wh4f?U z=lY*rw2z_IMYxjB+0k5V$;9R-i335+3PoNz07%wKvS|FHIg=%2a^kpJZakdj{ zXFsyEF7hF9PKcYxbBQ==dmPEXP>$6rVV+26YdUtK)!?rlI)pO0FmHuEi@O8}5OGb% zF&^fg1}a?t*}ugVQ*@309rTQec1~24YYEi?7wJ9~a0c7kZz&m%d&ZS{JB!5gg)O>- znGLic;?|@RZIS7S@>Z3E9VJ66Cb*oA9ip1Ym z3gkfRBGpTTE0963;Y?DHz>Z17_8 zZJ3;AYaEv&k`}h%t4lcqeHixJwOW`g9u=8Lh#w@mzhVoEs6LKsR4UD4b>&e z{Q{c2F&TSf0E2})<%G$-A;_eHUv3@Ba|$Lh-Fu76U$4`wW3{vO;wC!|Br;gSTYb*; zCT}m!3JYW#e3#DHCOpCKZmhsd8fTd+d@|%>44Z~~b=&S=8r?F8jGd_J=n91`6`__a zrj#2oik&FbET^=}3#8Q$h1sX-<{+FP4#{*RM=kl?Ag<8!8>mF=(s|?ZWrAbADJg7# z5Sz^ovnBb-b0$irD@5Fhw8Dr4+HB5^yTS##pxNc>TG1X3=V7gdqAGMj&z!kJ_3LuoSVg*lj7X4BlHLrygY%(&sh#)&UJ<< zESHfQnJ9v%Ygqt5)waqR*2Ph=kMY)}ldN5?Gux;;|0t_9ByA#vc-QF!J39Lsw=_T0 zn_$XME&$mE#M)~v^JBil;EvngrmfqX7B>(IqIvd zhM;6cG?wU#m)C}}Y?o*oy#3~ccqU)_2w_SkriOM=a2=Tcm4+IC5w#)Ll2P1SSX@2w zqnKI&*2X$3J>5X{gr>R-@RHf1U3OxSL5#sY+md8%r}$%>tLP70fFtT%kV+U)_9K#P zY)DNew1c*gCe7Ca(5JfG7h=bqo(b+-T^>y*{e&7-Uy&XnS zrmRlMqdExx4`Iew-9OR|TUdiKh3O3;#Rarg4C}0;N9lVbAvSAL@7sC{jViw;*A!fS z#T)FpT;%W6Th3Epu5PE~+gHUXgZv8Ut;lP#p+YPz0Xf5qRt%7)ED$HqJD}LR5-p9t zpWexJ=gQoNG3z1CJELTFhH;`c7)8Ok2gx{Or!CU--WMK&o+KTf4xunxZ)5k0B+j4C z0pFaZDdi8^u(0aHZ*RaOBE`LV`4&CsKzwkofTN+C&RP?spfxt1+ zX39xzn7aqdDJjlU&<~*^-!jv_)4;I~(vLL~^lq-lp-7L@sshZ=bn(!a0JAir`txi` z*w1e9wa2*egU&YTG0g$U^QG@BItfhe^K58m^hh67NK1B7M!!r3v)J(K^3bM@1p0nO zo=e~@$4UVh^T*z}K0t_?c6^`$pTPrws9WBcb4wAIuS9-sz1jCP{lG3M&2H(Of(_w( z3zCGl>~|2`akh-?Flny)U*mD_`oSi-Jz- zCPaw|Wvp{+72i)1Wv(EeylcM?b^&ZElx` zaXPB^z)x{+%}IW8?#S|4iA`YhTAg*cn)70-hj0VV)N%l;5T+p@HV_Q!e_M8%iH zGAMCqvw7h}*9T=L?!I%0$vHhjp84?QPB7Thw;eCb{$jP@MZPct% z2prUbYI2>@rqcCM_!0TMijRi+s~)K0ztT;Y19Z1p*b8K1NFrdr_Pn=;N-81UlMvQV zrknRR+Wk50@a62MH~Bqg-7^Y8VH$Fl;de)akV}Jtog;wQ(JzoAyDl#%t51e9x*ArrnVi4Tcpz}B4BbNV}+JffKWORxZ>#1IYnuIy2R7)D#N zfaU-LAh}}_PVzPI9g0B=@{5(>v{20Nxx+3{n(4y|h71{<4Bt`MV)o~Z__em*xu=y3 zmMbaCfpOs0WpFqycRVm?!LpTe@3S+K4M3gc$$34c$dQA%eml6-$SO<$( zB(pq~rV`z;RaYszrV8+GG3;@Yof>6G>)Ra51$YM`;DiCrbGB+61=6!m;bCL|auCFMmlND1S zVrl#-)32%*0|Fe*|(&k|XM* ziFH|{$C4BB@MJ8a8wa&+uqo#8^BmlIq@*RR&d}g)l3|t03pF07nxq$#6Yr>|d z!|1AKXp$D7l98*Wu#1bCow2Q%Gnt%&iIJ_?=NOl>l`+88%HbdVuqi6Kvbe%%?-S;0^Ud?k zcN%BpI)vLAYb3s^5Xun5iy~2o0%#P&NR;~Sy`}|^HE8f6gs-6QR7XFUlLuhC!?L)4 zU9g08_&@qWeM2Q2WC{!+;iJnqtm0mOdfY6KyTmO|$|>bA%3nq~AkonF$wg_IcQ~V! zzr0qR*M5@Isy1)M=4`SgWBEOmzn04LPH{cErXZO;k5YzxU{|5G#~Zvha(N{@-EDi9 zzIkqjAe~-Wu0{Zuv{v~*f+q`}uVhFx$x9i25nsR}ms?sFSXn6lGp?SB64=X@;>Cze zH%@98s-yc97rcSNVfOAYTwS83?c3T$GI^yTKQR1IS#fgB31hZ9@uh=M_K7TCU?=+G>Ni9Zb;RcL8FfbM4v}G@mE<#qM_gjauEyl?dL8 zC-PgUf8VoIa)FSTpY07spBy$6{~vbn_bN$>hLtGp0y;lv z?l1NTUErb&QnM|!8wyKq9hPo%^7K&Xxz$PGOCp2Sa-;l%E2SMtOI}Rp11Esj-8?=Z zoZ^Y;V(nr7xA%npde+l{|GEcim-cFmqn1NAb~>`&U<`CoJ3KCn77c8@escdT%_%gA zR$5k~lmeF74+n|d?NnQbk=mkdRAjtfO47&VcHSVxu&W=?0#TFVm+%6NGni^V%KIzG znSBi`d?nkmG{5l%G)cm@DvW&OlRFuDIs2wK#h*2>Hd3FSn0})UxRX8-{AS!_4896t zGDuEhEPc$2B&6oz(bt;2NirX<8=tQ?!JvcGS+0loCaFo2k&y0=h;lJWnpLHZx>0qZ zO*3azrM-c3Ir{-4?(L%8PX0FvSRlzwW07}G&Jyj)TJR#PM&T~ zq3OVu|0gGgY^ZNpEiq0uc0;_^;utO)ve#6j+(BUA{^Mq1V3!!NY!m5hvDsKMrv`$z zu;DmvAmeVD>q>G{C${4s`TFx5hQ*d-sFYT-lm2|85{8qBXRMCp++z9Mf~&WwKsPcA zu9uxU6bI82W{2Wm3uAgqf5hEgFYT0})=?ZImX-}@VR167pi7C`%hRH<^}(yq;s2qnM=o&P-U7UZj+fY zY;sBAoDwybKO?{++aeZkLsh}%);%czhd#b$?$ls4zeWkiLUcZ1j?!=lQBQk8&DzkR z_%9`ogmjygMXFV{Vh;RXnwA7aE&DFCFH+L1(SFPxMyC&1b?}r;TxkMiuqa#NyoMDg z`gS;s^(boXg+wB4J7Yh8CcXEXsCA-(O0yzPV2<2p5dWrSYA#^2h~r1WBRI&2m7E-EIAV>~ zIdf@~;1`sJp6UAlVB|1RzS2ctP2ba>loQC^cE|CH6J(OWc@Gz~dSnHnySDamSTeBN z@6V)~>;}(QaQz|rfb}|Vb1@rb=8WcN^rnQ}^WiW@&s^jgWjEL9uSdOs zH5aq(l!&8lkBtnaIk$ZL>7j?-92;b(+>5(t^#0~Ic%o$c^xi{-oX!u`#k;NB?-Q$CQ;F^|i(`DT?>#$Ae`+l*E~pmu!sdLEWD>RA_3>?`L+dTut0G9gxhT~(`hVDkVs^?`u&RMt;O7TQ#=4WRY*>TGo$ zitpz~l-R4B;PpC#VF(HxU}eCBUL%JRN%7iwB&&pHymCEtQ#qq=^2HPN?!&g0a|x(E z^pOglCTs}Acd^Q?YNzS;G$`+IY+ftrS&hi&hkD05wXhF!4oUil9PI8&-S*+HCJ}#o z7(<%&a&vU%7Lw>tzXianIbOJ#L)GmaQk$25RNFkEslF2|R}9)m?{MiHxj-eYDelhp zVfYc|eh}Yovj|AMY7AI>z2WoDxCX<}caX3?m8{*Z_m6gl9x0EEQ#ENBc;-=*IRa1= zl+a>%ls=F{B&`hZufwjlovmYRp#k{4leK?R$b?Sk09yLm8`v8a^qi*Eto8bL#IBt_ zLO9-Ch8aWRUf>lY#|Z|Gevic$ns15_c83AOp1~B=9sTj&xcI;L!p{iC5V%d1P`#B} zRFn+lLeY9eVhOtnyVFYV?4dA>Go)cqeMqSFmrre7L@6G4W+ZgUQxsgmelZl|y28l- zCQS#o9mlsJ%ddl~a!dl&#qO~^K&fT?sG`~ zlOWgC%FIQ|$o`XE_n#cMs;Zi3?;O%x#CT#tb6RSV8a?!Nm=)wwy6Dza5HeKZ9gCt| z6q3E%N5c_94)=aFidhqjVZQ;VawV+yA}Shk2Sd1R{uGrg?r;er|Rf2Hs~5 zRUL_)A8$K~Ac|W$AZzJLm(Cyv>CoR$RAIM49}As%KpvUfC>W%!Qu$1$5$OZS$%?d6Mbf6C#-)g>x|AHHbNTDi z({X>cGO_aVi!yT%@JjCOlAlFl3|pGhBs$vm%85hjDCn9`Ov_mqjP3%y4u^-8B=mVrOlz9kM!^kExmd6#ng1kqEp#pUL*vM#2ER~CvLhi8caNUtIXEO%+(`HE zgpjl_)r9{28#;%%`HjM~So*hbS!Uk0UbggQ7Wlm^RyTTo7LKGERG-k-T+6vL3|b2* z@$+$_d%@ahCgQkTtGH9){Um{S4SX4q$F-0dvf%&;`p-KoL8R++vWC7-&yhc))c@dh zFK{qejvs5Qc+ze-6pm)fXMZhUx!&+>E&#&b6a z9ER3`^6s;afk+iqyIQ`@l#OJ$!gElWDtkj0THXV8w5lG*@SPv=lbQ6&4xPi92Jfh? zKtUh+bOqLj!+~cY(!gj{)w@E~leD371uSg9cBQ^ebGCIUtFF;(x%F4#if=+)rdq-v zI<&-D^vMHe@l`GgVCFWRAdxwPP&%ZC9=$kk9@&wLP#gbe=ec@A)<|D5BmNX@j}LIkJ0J9jM8MOJ23N{fskhFpFPaK*w2`)x>-~ zUpKs>VBhUHV;gqoVVZ%%+WI3A#GHO$A!n3vPv(VJw5~PSLxts$^h4B@n+1`T&N2V% zYXaV;6W*=^QCI6$d)N+fH4f6Q=8&7PXK)6zWcT!fKisxE=8WvpAx#jpa=AFj^VDP= z3^*29R(QrqrP8BlFxI5oJWc!&r6tT*eY!|B)+6oUJ}@x{JJRKN?_eA5UIFh~?@f;HYA z+wOyhpZu~l2-=u9$iad|=Fe|hm6iiKgR<|D*~`5B^&>9Z93F?F`39@1Fm-tc@9hzr@)A!K zx$l9GeFQB!IZ?GSYu9$}EpD$fiUV?TV~5xPlF_kzQyj8{2rctB_y;wlMeBLKboZhl zR;Q@qj{UY_eptgf-96#ICnD#vxKIh7;K|b`(Z>H}uJ|9rn4%8$=2jK}XQO{+p)pBz zim1X!gC8pv$HF-vpyE}LjbV-|kU7#GrIBUEr9#`d&LItW)SAxj^L>g%5it>ruONO@ zJEv=4XRY!+tgO7OA4?k(O`RXFuaLQcl2&>>KCp12QoT}J1P@WGYRxT^(rqj*t^16`pHKhtP4Ymyr^sH4J*#07likw~UG#d1KmL(%rscp(i7@Kxz@gK< zb_U+iWYfwa7-c#pSkE8oTy@3~Q*1*3q}yq*$mK? zPNt4rudrsXCez+MIQ|J_qw!fjTxx!2N9R+&(K^~Nm_KyXypCq#CBD0-^Xb9Wl1V!5 zT{@8R?g*hPr`+09R z^c)0F!WlxpGGQH1@+y?@kFZ|PJ|i;m6CRP2ADHO(1#uzw4Lf{)Wm$6S8;&KBP|je{ zmQ!I1ff=#hA{voPuxJjf*hUHBtLeYHkn-gxOhpQWb9&X|i?I=D7g zEsoLPP;IyzQd$kES+#%%-;IYW%G-uBPcq_B38wp?jT6uH3m3tf z*VWD(Ka4JnSJ^%r@pgt_NiwyqJCb!G;_z7%i1q}D?Fz9$6&g1s$$pQ|-KzJa+0V!nwRRG(`CgAUH%hpSgV0s*8RC{Mq{VZ!bC zFwsZoNy5D?J!rz6ryV{Ykv>Y%M>N_?EAx-&VBSl#3a;LYoAzg0=p2(fMy6hIJ})d~W~@(mZ#!PiLYrqN(KUT?vptfBpv=ucc*a5W4Q=u{nFQC zRnr?V=NwdcniRnFNy^G*NzEzRrE5+P6|c|v8jXqszGmc-O^odUJ#oyVNC^DhJITCn zsI{q>&?T2>WV4K?cuN(od5s1YlFhIIwHbN6eugY9tSM;}($saQY((YdpXvZh$j%Ns z7a*?en&JS_Z-xA~$SkXkO(UrRmq&`btHg2e{>(D@GW#+ZDJ~vynauXQ;QKT$M3us9j6lcF8AR_HEy=VI;a0!-VX8B?7=7?Yil)>sC#*V2sC z2Hdas6O*pgY{FEOK3i7=SUriKl+mVLxl^*4~H{qEl#Y{-(gUgDpK%6n(bVZt5RrnVa#r-cAnYE@yfZ^+aK+g78Nw=v?X8nL+sfeX+^Icc-W)0!J8APDB$~} z^`u)1RNH31ol>AK_FuW=(BU0?<5dbWoF&zcf=zK4PqcjU9@M)-XGF0eLU*0hRP*hQ zYe5Ngx$`o3aTSNG(M1)bS&b)~u0p1Fh)RN8kCCtI#*gfXSZhaZO8~Yj$ugDQ7LLSq zi}j7{)0;D=I({5?fQvp@KH!#sdjoIJawS+zrtf#{}nt!@6 z=IWz!O#9_nbY|Y;XTQlTyL;XLn)d6o*bsSPnDnFXSp{0*?@!o`&y89cNY#5!$!7XC zo`@k-1q^sX_uiD^#D-KHAf-z>dVFPfL9(E0_QSCo07%VHt)yL|z_nt4Gi*YLMWu$1 zliYG?j1{(>702;9!We`V0Uvw9=YYON;_?Q_pU`% zT?`4U`+0sr9?Z`b)pm*2FKE@mB=lm&72KODYjHTh^sQz(PNg5 z!!QI5&LN{WwfCmkWKqXHs~0#jc1(``tfUB=%wp425SXNWNALs1|B{O(hloVC-kM+~ zY#7}AegL&$QMfbffavaORRXjs-?~&3oS7p&0-^eqqMT4+Ne5OMUm8AX>`TT^X5%B2 zx?9~nQ|=lrt~qaN$WOQlK@~hK;*<7%hY7#RNnJof@Y&1J+6ivl)@Vp!P(P)~Cub0j zcn}V(NPVJZ<9rqI`fX$sHG5R}p+2^Kr-lw2ZTFGV_NdJra(O!@8Q*)NP0CFvHX)}$ zOC%86sls=3e1Yk_WDK=Z9ke)w-3ZMo^IWFz9>!U#3m}wyc-yguRXaGms6@vAQEEwR zH{{L2yek901zM5BG86Q522`XRn1JFZRZJPaKzen&*H~W9MCiZ^xPB~&slRe%B z7W199)Czu#tePl2T^oSWRL4br7p)|-i_rs?CuO=v(u0V4&C;XyT~mdnBl56>&(9VB zu=?A}b!(pX5aXpT!hT(z!#Pp9)Q`Xj84=1R;w1TGoD87-d)}74p)F8>75A&-o1x7a zx}Rs?&X&1mnzR|=R4Cx0PL@f4O@5++$#E()ip5AMGnQ<`Rmd}agGSm5cHh$AMGO3UHu4$Sruzst z<5<@59%{1gy5c1=28f@frlFRVk!(H zx6d}oYAn#tuYglGlgGUp#Cc~0oDMxq*b&<)8!a}E-8FsW)cBz0TUV%;A^)_GK@RP; z-HFb*QAzVwIKmHss7%2=E%Y_ltxtp#EewGRYpkTt&$UUsT~6)hryGiSXu(oliYKMS41y^gB`tKNY}=wzkz$WXwp3IiXS(cmrKj5l@U|w9CCD;wH_KoLyL zT@zvC4Wqop!m13|g7*eemdNLYPC@%Q(`NHQ}ud4j7Y+!b>Q`_l}js+Bj72lWkIy560U zn7Tfi=a+;h=o)7|&eFJHxKF##Etesl@F*r6Y2Up>xPOj@7BSq2?6<6Y+;SDaOx`jy zkCWR_>I(sW0`|_DZ~tp3B4KP^AwDQpX=2X}Y< z#_b(uEOiCO1~@A+oa~5IkhsEXK_6dAX{*MK$ zXO`Bys^kZk41nPEt{^#sDZXyG<&w+Enb1ubQ&4_Bin1bspxL+)66q{ZxhZu|>F$ z#`yQO>woaX8Ld4-r#UQu)<=MtwQ?)llaPAx_=38mZ$ERZs8i*eJ%|Fy-N%`(oc*>r zPKp(Fs)1?x)2QsiX7WK|RI8+!poT7Ob$ z$YmSsFjboM*?gbL#9O7+Gf?umDBL9~xlMju4MfEX)3Dc%F-}Ok2327m)Vlh3Rs-uN zJdM1lZwfE<{wUA!CpzARKPHX@E77T|RfX#InT&X9Fk(gS?7y~Y#yW?6+qQ7svL6i4 z8=haSF6L=)VvHdEFl<_=-rk=GP9sgNH(yd|;^mpt%Wrtj-fuN+k2MN?Px3Nrk6^~$ z!9o?5b0DP@Nl6H!FbT}DEg&)u%Q+-*Gds$-^2(B^J+T{EwhKDlyGQ`!j zz(T{d+so;ysq>nGJcy>>&I+J)enBUZH#?}JuZg6XhOAIpUw|)hio+f-_~Ti6H$dQ} zig8g0la>G4jQUBK?+YKb&4+y=<-{o6)VT3u@dIL7l?>h`>+pVvolfsGI%yfEgUQ~a zh%4A+9FQ|@XAss=g%--tk#N_I@qJ%GHcw}oCidl7AopR;k+X{NTfv<8+K^4kyj`di zZ_Vs0IaSi*UAks#ula1}<-Y_UjF%Fo%7$#l*TChT_X5a%>9f)YNybKi~0 z#yxI`80_D;wGn69Q#Rcy4y#3YL=byNib#jxH%uZh4zRMj-9@o5dOmAC;}9g@36W%G zfFIDrf*jf3g5BPwaw9Kmkzk9G#X$Hb1v5m_Hj8hE<4iFR_CQ6qW!oUjzj&Q5eI z`+6LrV5olr^*EJ<`40K-fQoO`gs0?Z_loSNNBs}p^j|hCVP^|~-KU__Cqb{7<39nz zl!S2^aAvd+#b?%nCZLWT?Qzd}qdL^81}q6|&t^~R`K(pCggMIaSZU2(`DPE)WnLc{ zy?P_Gxl@w2^M$+O(97TnZU8HrEY-KsU^`3zCIZ+&CS3MC^l{ibzi**|nE2tHYQOj* zKMo2S!(KYFnlHnm9Y$O_&XjUtN(Li14no;BMNU+RYY%E5s$uyQ96G+_7#zvD{s>pG zu`LlM&6qL8OvOO}f1zF^!*|>Uvb?;acW2=#gYC1QEa_BFru(|R{Q>3?6!U2sNXgGE zs-SKA0}dyQCMBPa9XS>TJ#a$MK)m*a{euCOI&Ntjg?{&rF+ByG8P(Ml@MqRj;XP;T0+B7*)PAM{{r#vtJ1Ks{fzy&Di)usLjAuT%fGD3Ut*gWWqH|NAtc|~KLc|$ z<&={oY_Jl197ROp%Ft9~9vj6c_2g?qZmQ2Ke2?I-%G(?vC~~m+T5kK}zaK(>m907&Gf3Z&ZteKa88rcaovVPXT;;5ispEVuySTsP9&$#rt0; zpzX;*j42i}9W^QWsEiV(RU*D&^*L=W$$FfJ{J{7$hhC`@=W@o4#PA-#|2Y!(?h1>U5epTxxqnvsYEI2%OY?!<&aYF9s+h&Z+ z@Qc^sH%jXVJv8S^1ftF^YxS79svTI~_jxNIw0xs2(4rx=f5p*uuFFr^$%Y1Bm%Gad zxh8=W5A$O9FAzC+1;QKrCp@0{zk7B57DN8a{Z;%IQ_s?ncAwQid*9_sHHjj_LZKWJ zrHYkzTw#-w?nNqY#11HwhEYa45?I3>6D=rqeSqyUFGVGL}DPSheSAGBSeCQVhdnWJSl#6ID~o zELekjZ&rB?klEEPW2BMW`Bq~>JM z)SO5(o?tjIhJMq~+C-GsnPE6FM#fs4!O>_sGL=Ny(l5^blVG-Cxe&i^A6Lf4Q&qMs zH8m9pYo?)1A2epV~Ow7s2fVHHbQ=hmxyOVoTR{A73C9Uz4)gC!)->Q@-(}|4Fa_3(4La zOJRaAIXORoj1QBH#B~%kN>sJ0C+w_9e>@V2X4D#nK?wMK zr|gPCrAUxgkiDdF=#|g64BnKeJ?$uItbUBTw}|>es0FMqaTaGS!e8kB2KbY?Os|A~ z+M_$?%iSa0RNF-b%VE?I{R_Q4=nNJZAz8E7QnabxJ}9huDKJ6x_(}d_Sz{j>9f#%< zt+?3Aa+_|D>z9wPoBItaTbU_V5uFUlM0qmhq7@F-U?4p(s|az=JB84GCpd8OvgPtk zq&w|Vrh9?pHnjx3Jn(V%)r?-;FJXDq#Is?WqS1`CAv4$4kD^2s_x-4$Bvu;w_`G`p zmfxdV z#NfO&%wH|gu3^nbGWdG+!s(s-^v&)3OoVWut>qb9{_^HcclFT>^1UI?3MEIB{lbv$@^hA=OJQWGI7!l`nn~ef@*mx zM4^)MVjPRCWT#QWb6Yz*{HBkn$0PRj=a3Wahs80aV0{l97Kp74>V5o^!7}VdQI>Dx z{p@+b1q}XAQ@r?YTmbZAl(0-$=a6VG*CAQvu1qs0+#kV3s6;p4{{62%6=6D;BJ{zy z`#O5LwgWQvbuW{4V3f%~XH9#9Pd`;W2JK2GW|%nX3*AgkX;{gZ@P)6xghP>;?vBli7N`^e32p@(tMTn_%vj(?=aPBwRzZY$L-rv5ATRL0qgM zb^>Mq4j`5RpkU*adsKM?+xheTNMVetL7_py!rAao>ehO zuDKP*k!Y{^1C)fFdUE<86H4Aqy{SP!OcJ3_Ttu%Nj`@sYAOB#equfbh0owwmW)5&( z>Sj>7LkFvNL6T6xh*Gd6&SJBHSi?h{#uqAL25EB{`Av_pT}RyQh)I$pHg3+Y|j5pa1|0Q z{5KU)@ej);9XPkW)^M93gFGte$Uw^QGbP;_h{WS9Jr58>^5SOKEuVdVfwA`g(r=K! zBY{Uo&TnX0%KVjL+(XAIPYS53Vaq85*rqkL%l5byxR~h`je`HuR1Ho?+8;>GZ>(3M zb5@VYIp~iB5ow>zuq!TfIfa%ELz6jH!DD3q1pVJ6WmG1Qws?IRA2GgdvUW|qEIRBu zl-dj*{zVA1p3e71`Loyg0hZY>^-WNFq*AWpQ-l*0hmG>aw5tgL^~I&HVoL_2v#Y0D6Xm2g$yGoFpIB2w8a*@D1$&A{qwk zAn}C+q7On2HXUWFixin;8>|?T3`-|^L1r4&7)#39OCWurNKg2yIh+hro}ImnHA7kH zb$ubG8NbAGQe-)nDtv?J-TcQq(^3m;$KoYT5P#mDX{f@47LA>`>03)OHBt%hXJXk? zUP$|@XTIFh2G4(`8Cp3>3dv`5Sbv{Nje-+==SU$hE|t8X|Y>0|2|M(+!akK zJn-BuzdRhZDi+{YN7gAH<2_o@<>3>mPh8VV297Bj{aJtq$KseM!Z?=1<2dQR=jcmg zG9-b|mN;h)x2h_%*uxINOlXs_2(}oDu-9|!31I+jP#7~Z=u)M`h&Mf~Nh1o4XpL=G z;#9NKtx`t!9gN8QtQ@b_p{2O!gToDWwZ)-A;Lx#FM3;8c#I07D{jOw+&Muq9i5RZ` zYyftBvXmQyAt`adKMr_ScQr=Vl2Nlz;h@Eg%DzHUw`%-8fCbEGGNlS3y2H3=AceO+ zZntHE*O-V=GuNNMd2y%J2Fsqlw7xw*(c0?)ELENTiG zU8Kuc!o#yA_!NOyqA z5Z1a$D4ZX4n+7&OImMiub=U3RppIfMVgfJHzq)9)auex_Vd{!7%69i^$ho(t=7GC! zH%EXv2VK}tPe=%dZFbxBV3XO?E;@KXtU5W#IV^3VNpr`3iqYVk=Z1*Z{eV^N`A!Wg z0A{g2;jkZY0fxowg2%=z(k$khG3GXvR2j#$5V2kxg+&6ZNxK$q4E9Qo(GQ-;8!iCh z-!Fc(Xx~dRP2Tp1`R`f8{hpy&;omZd&#v^psIC0xUFpA`)W1i(E`NVQt5WO~XO%uD zYkuLL9Dc#23ZH}v6oO06%MWKp_JJN2Lp4P;T&l|G}z@|3Rkrq}|^|d-+n?O4H}!2hb0r@CD=x6+hVHH1S6(xqwf}-Ut<~&W8gH0_&FX;%g+_M2 ze%pCYJ_1EkyAyS{6n=OE=R{3rHtKNUm%JH$N4>8He(4j>s}s{X^l!z4ikB}DaHFtF z_25QTmsH*W-u+f|9$F4KW8g)TiZoy8Iq?~+_ggQP@_}qk{qdUy@)Qfq!&3*5&?5cp zq2G&Fqh*o==4?JdknwF>KJ3%|2heS*A64b|Yv5Dc<}nBvaiseJUzjQhcG7o- z`*YEgJGh@{SfcSQV1j_>=U(V1dGxv_&Ak>H7(c|nXg{?kh%>UG!@)<@-6CA+G+&6N z&Ej%f%M3J^ZEIjeHIFm7}|iCDDWfqlseHXcSwL#me49rO4V}g@DwD{ z-bdItM-B4r_FOVhLqHO7C3pZBPrBkbi|?5U1}1Hc&0oTdCW2|1Y#_635|t9z9?VDr zU(~NOD6toJ zrFN3q4z0>Fv3e4#EtHkHq{_UGX_fTEXpf}my6<(um1?UK2yi2HOMyS-)~^Q8XQ=XNZ8v21%AxSfO0f`-$8}zW>YDv)k(3fCvPZA7i(1ZV%^c z-jmt<-cA1RFDGyy*jOx~3B1BN`K6rhw8swE%-IOTR&c9ArOjqL_ zT|jbVw9*m=>9Ku$DkJu{=G{a?MSJzs_a$t&YN9db=rDh z#f@3)q0_Iv;a@$lV$_^vwzevVZ5P2~Qu3@g{@UB(mY%I*P-Vw?MmppSf!aZo8+9KL z`2p(Ye>gCrOT~Yd(x#~(T0@%GsxVVoAtnoioA8!oZPM%|)&FztB5D+iXln8ZeW0WK(F5{aI`2-LiXsgR`W^E)iIklu_=J}j zu)$nQ6&vaQZGtuD5qV30s0acf$mv=$``ow|O@R76RJBN`{1HA6AHHK%ytz-aP@-Qm z`+^U^*}s+jUCglo0)T8n7v=;ECexLO)$gXz1#C@vcinHEr1zn9?{`=o!$2FuIgwHC zV@)UZz;_tUo=b%IKNh%Y^sG8Ui*5VZv_W2@m!;^vFADg-@iC1yN9<&e8W_W19`dEH zv>mbxd8gHGW-I-PsS8Ie(!+@n>gU{_y~Sr7 z>}d4achGQj!fQDzQPD-o*Ft547CcZRN4Qb>@A@3 zO0q6c2yVgM-Q7L7yA#~qU4y&3ySqbhcL>4Vf(0kIzOVnDdEL$Q^qW^}-Nj`sYS*Ri zsk*1C&e_{zlVr7au&JU+=~C?;zRivj31T44H;@9qp;<*)5fTaFd}6B0o!PeI>ES6P z28ivF00!B$A$3Ly`tG{kCcm)X7+D3G75NVH`{(aTy=+4H${U8_%^iMvsi)#=k|8mEcjpkx9`eV@dB* zXij9G3}Z4> zJ*CaXP^H?UatFWB+s3L!o;H}9p(H)Xk$=Iqe+h9)CdjBz<|kAsI0rqt)D`}b@8JFo z)Mk(*W(4aJbZHQoLi9_6j*|KibQZZC_dv~#tl6R+>B(lUy;|uQkxjga&p!EIeZd$o zZh8!WANYs}1jPHlSgn+et*g!NzTod4N+l07;AOotvF^>nYEVcj&snX2YWhSP1la0x*P;?W81vkhwXOT<{t0 zOMOD|A;A0WB&hRE(Ek4KLR}1JSg~} zS`heOQ^bTk;lrtymju~*V+loW&~m>nA_Gm`pEx&sx=`r1B%tW)52cWFk}tx)SbgOB zYJSa?Y(qlQA(_~eKykfnjgdZ|1Xu_)fN2sJCz;8pTkw=M4aIv{rf@RkVqJ#Xn6Z~8 zS81>&?9roB+|od1`hqLS1-D8WA`jpYRfpY^2q00`W`vccO2nFr8Qn8~v%GDQYF!RGAK7(f z<@~`hl(D%;4EI`&J;g9jQ&xHPXDsyx>zjsVPWC*`3Kh>ClAs&7mbMV$(cZ!#3e+}A z8u{EsNSf5dlJ#hlvgpw?RST|{^ri)RDfe%1&X3I05A{sF(-=@S5=*rDF+iZN&-^6T zK4(QX2IyASyZV&yr#v*f`ke6Sm!}LMtSHSo%*KO_md>&H=lAG0DqYEc@JR&UMg z_&p#4pElAsV{h_xG|3GWsS_3;Rxz#ADi?P(N)I_`5fwlv_zlfIB~F#7d^Swa0Udun z-6uJv-TjfC%1u?xEQvgnaM0o$U`fF+BG8?i96~D4a#=R4aRm{Jt8zxD0IvXLILU=S}PO% z3U9rcvZ7-mkNBxYQbd;P$t$%{bnfC1DCg~ zus~_hq;Yku*2J87!5211@pSY)lJOpgSgH1IOl*jvpD%b9X$UOQYmj6YCKI9c2ft4J zhg0UtGfKf<4&TyEon;_dCX0u_=rWgIL;;C1dlFSVzSb~vd)=@v8G$x-SP_(KAXM6i z)DDfsaB)Y*BI{IQ!(}7$3+nEQ%t*4`mK7Q4BXcD%ar16o=}s%KtSJsZIkQF!IWx_< z=L$&Ibp}^^ERL(mtq{4;iFeFVbjlh`Kr~Mp_#``g|lQ!Kb1YI%E~k zE&BCi3a97bTw7!P&B;4iN3_|8ezj2k`T>6K>M{6)+`^em_2|i1al+q&EQGoQQqBWI z{H1&n9)-!gb=Dv77ma$~b}z%!LZwY=8YbqpxUy!gHc(DGv0x_B1PKtOuo*&_l2kp5 zYl|*_1_<(p^<5`aVC=0OnyE~6PGyy?w=p~OxE9-p*Tj#TX@40XA8QTz8V|OnV17XL zxDq6o4ha8C|{g?;XWEhwT?I#=2~920N}@+;7>cBCv-UyMd0y zXZ#Ba>%Q@duo4q&1e1J>yF1?zw8y~Rf&4o7bOuGmdz^+WT!*#(WA&!-W3Jw)fo6@s zz?}>6%pqr}W<5HN$RM6_-JZQN^hs|fvU+Q_KHt-!GWk9e!VdBd7qp1iPpo8Kk*@7y zZJj)XxNPRGCYSUy%EQl349FP<#R+*(A_BT`Tf+h5^ooJByRX=W?GVlhS~p)R$DoX$ zeDTGaOq~@5khw!P)C)KkwXI-rB!y}@a1%+}0+?hWMCE2VrVJZU8##2hu(c4Zt?)!9 zw|!qP=H{Z6jL7b%WPin=b zshKDw`iz(TmpAw2Xv@%D)pP~40m1Zhh_|)|TyBuO_rwtKUzVqT+kUwN95nt zs^&7d6jK#UNlBA-Q=@j#0`{#ulZkgy4KX~n$LZUgWHf%YnlfR?1u^WEPiikZVeXel zTP0$}FIqP=8hH#kU(|I0I%kkx#d5?{cWopni@ z`Iws5Y;nSNdBfnTGaYSFNC@M3mB>*vPm9(fQWTK8E?ZwYTD$4YOoHSn%fqlt0?QHD zIfZ2PWAyn|{G>>M@-LD$+5>isd@VL*A95Y0LR@>$x*6aZ;1%6FrD%1>0sYdsxCg$& zM9(`0F%To18IvpVxw2a=AKvIySUtDd#c%CT%FlzLUKACdgY>Uh=wLl2m*YO~8%oiR z9YSSb&clNQjFhf+0OOj%(&$a}5S?MP29AR#GvGng?LVy&2OsHZPB5%`f?$$;Z3)o- ziP8^+l~udekNf?_&vvyKT50O0gW>CDcvdkbPp}ocsnHQga-e3BJ}X>2i|}0Fp;2ff zd7;Q*8dWWbF!W$f=vf>Vp<}FjB2Nor&xVjGlIf8Z3&SvH{FW5-_#szJ9l}=>!6rd_ z{5o6OZ1ASJc59rf!5KSXbnlPW5+m-Smy{rdF#HJX!=LOu@K^2(TjluZurZqLju1*n zvI-$b)fn*n&x4`JP*WWu@k4xU#u=CW$v$(M*wYHr-g|`RO<&x4#%4}t1NBQ9{cPjIe{qoh;VK)%dvtWhtAkhF&O+LSM7zI zqp$R@D3tq#oHoG!SBJB+s_wEDVEtnN>;In|&VQM`tGj{~D*v|)>2s#KP(^J+ zG=c8b%V=cPqbC`QuKOjFP?jZ4!+-OvnTz_flnwVx&JO)W1U?HQYy59P4nvMoy>XK$ zVY(h?oCj^wjvmu(r_;KdzCaWPtic>ZEQhUxYP(px0P?Ze+1TO2a7s8TXetwy0eNM6 zr9s+Yw@I6(Ru%fRnPKXGhttAyEFD(>X<01{jpti3>(6#RD8sE<5H@~EwyOIBh@>6YI%{Qsc zxEfH@2Ax$@7W*K9Ysy$tfN$!wHdGr9h8v--SXa6Gv2@bWZ?Lk%4zA7ydYHDQ!Y5t7 zR!zNp-7u94^Po3Q0scl-&0)BD3fE2MqDAno(Z0zcT};-N%UIj`D}Bp-p=rZRk&8#Q6N4;f zUQDrU&MX4>UMR?DA&y6QVBR+zIC<0QI5i^SR4b;GO_1@r8pu7eJA~IC=U}HrJW@i2 z1>&`^!4%2)IH!c3hyctcrh=;k-9OL3*l%tqSi?2MAO!A z#2iy}Z@lugc51ox0RzB$^XQCJl`@0bBTgU?+R-q#zd78db-GK6Er+)fc< zUqy89xT;hFhw#e8k&Wi4xdLE}9F;{gU-=J`5OA&V7EvD1#|+aE80#BIn8eUV4{iTC z6qwC-o_Ya8p$ae**#DQc*Y88&{T4yezX!p>i~<`*&6t;f{TOs4(^Ur62O528r@rf*RS-B{Dw*qK&}(#;!=)9zD_Q-B@$+vA#PT_BpR zAb%DUlNrGi=$hJ=eSqPc#ZK%Q;y4S6H=_PK1hnbTjh?PfX?6a=DC}<6u>9bJGcx zTdl6qY6KtH3(~0Kv{cV)8*c7sPBO9fvB7%k2D)3f;<-Aea8j_hEvzWysy$FcevsqE z%1aKLH6IlT9yJSrx&M&Wqz_$_H|A$=WR|SI*i?R=?xGEE1)4V2g6Vqu(QR^(o7F;N zhzmsXexx47c_w-3$vt?@`5SDfN`noykJ4P#RZU=em$|ubcqg8A1YEvqx$JD!WlFKx ztGd`dr$Ck;&od3ujAX80TLi!UzCAx^(|%fbwSSPWQG_0$Uir1o%c#|j&` z%Gt46HmROIhINdsMxxRu^peYx`UC3qlXVDLHE!}>-@%}5)k;KZ4YM~4UYr8J4{<37 z$wZ@Fgc@hfipGNmt|<-hB|`O6vv~zayYvHpC#Y6f%Vvzn1f6^(i8=IKD2=xRv|HrKyHSx1 zbG2Uzh;b|aPu{G*Kb`t7n-NKh+Q0E;@iu5Q9FYx?%!_wh&7l;8R_sI+LbAzgLTZX% z=Gi6~Ey*rTjGYwTqd#+cQ(gB0;`x!ztv(144V>^~a=T9Rrg)yM@jrKi*hR|mF)dwe z8}tiJ_LB+SHYk73WHiERSA(^oK7$EP0_0m6u$(}@B)AffDX-Yah^c8wdFGI4|N2Y@ zyEkr0YhL|<86zsm>HU$u}G3)&c?i)97mH3R}tP5&FCW_fK}tpOv- zKDJzOxzT=2Bch6qSRW)jz_(d4pIGFxSdrmi4}rZ&sV!3=$2-ctr#e+EXU+uS)(4gv z@hD}+q3?nY{ytYUe)j3wY~)2m%U~&;A6m#7Z?tL#*+svb28SED?dJ?F0ZBw%;~o5z zE;P;$#rT^Sv>FP!NT`cC*w#k2M5W3t=kN-3sXB{aq~l)9i2S5ZWIHGBmp@Y((BukQ z+)|P|wpG(C+l$M8mZMR}Kwr^iOp%cX)B)_01 z`4C3N_vO6M{%qY}F9V3*}Ww9A;u5XF_n9KAJJA zBbIVvU@Pr_7nZB=i8kt;@|vmmMeb1S=jCnuwj+lclWH-)-FZAFr~9apOI}4Z-03hp zW@$9dT}|FWxL~8fniW`H>S)uNvxSzEEx1hwYlYF4*7jZyu_YN(rWF@KaBms3Nc|D7 zZFd)Wdv}Z#C%{Rfz+@#@$Iq4GJuZ{Mn#DFXR8pN^1dRdDM_v{LN(}|3vP*Uk2P!%x zT;4$j?V|0A#5Ue;gV^!W;SjJ#BQZ59@<13mI;A(iD3kZx66G2M6N6F>M|4SI@*+Mb z;|4!mJ<}AaL8st|uWmFs`?A-b97Heme}d_Y6rZsN1LUq;L)VoSKxi1~P|cJ&@qFlv z?0w5iam8)1fZ)p3lNg2!##EOWc80BR8#8eK3ng-_gh@4xf~ zO_V3J&sDZ@^4q3K+u+^xg?oX%r%L`RUGCugNm?1YCXmMJOTfnZvdH!mR0As_ z8>h|*69zf0h&D)5SnJK)2OH5jhep$5yaGG_f;886iO-p_hdiYYj;8-QrFEjefi?NG5!jr>we-mB?6dM;$70PNorVE_L=+~dDLJjhbs{Oy$f^~}0O@JNqHS_Hx$ z^2sj|Sa1Z=kA_f#Y0xNGc$2OGbMX6bt^xJMj|_UxOE4sv$gW3r%-yzAVf({K`1XV0 zmnqIoPVN@nuFf||J;VyG$GF+NaUmfcA%&1|v8&WYy)nyp7%WLFG|c$pX3G$4SV_9> z@m$po?+E=;llFz#g_-OL&elGJSYZuDWQRWY0ZUB{kE^Cf~5)L_|y- zn}qC%q{Uigm_?J@c^{|--4vSRjW)qrJCcPUKl1RC;CMdt6WEsHg%4Gb@3hXICiQW9 zhNu$LxO!fxz)8V|UhqEAChg5V9D@ZP`3f*!FP;`t_a);DKIT9+39d5wPT6+0zraZr zEp{ev);3!&YZq6nb-*&|5g6-X#;{g0Sl#|mNAy#11{sGt`NmiGHN_wwLQpl6g&`bP z=+Sipw&JZ#NG*P_-vFb{MiW-4^9^bRdDtOiTj1KkZ29aiy!QhyZ`Q5B7rb(4ItZx+ z0u3?=O-vGK^sRI8ZH#0cjdm?j$`5LhdDI7``3)`|91`XfMHChw%hPi3d z1@x$L-aXU`&db!y;_JAyB4bcvBRRLkg80?cr{x=v$$>9YuTaw4!0XflDm(ZFWbqBH z5)P5iFBE#IjZpF8cM9xa6Z$9If1UB$AV_K<02bd4I5%VZU%cS|SOq32ZQ6bZn7J$^ z3XCIIOPQm>n!KKs@|_7ox;P6X;VRMu-mQyYurp=LelznU|HDoM8Q(p`y%^@S^|Da_ zsQLG7{JYF^uY=6hO<$ka4|YI{qG;S~4ojm27Q0Z{nt*d61P6NWqv0CJG>_dtJ(s>b zG4<2O@7x_2cf2cBPI>@JNWov^E7a`E>=jJaI!+Ss0C_D-RsEHs_g#I@FXO@R_8oBLaq-k5T~tE z{lQ_*CKKt(#|bkY(V|deY5-AHkTb|cKSf^h#tSq+0!7NV#C{I-v_NJq%#oEh9wDeVurS~id-D0cr*Ub*QiGk+VJR+JOP^vG^ zb4#|Yv?r)_G4VlY`nGAet?j-bTt9O>15)j3pMOBDMr5?B(yW8uF`!*;N$YNn5rH=J z`Ko<bDt0N7fUj2cLS%4ClszF*{CDYjK z(1i0B?*1Y+gC*32C{}zQ$qH_zABG+79n#j*QeYPjeDxA5a>i!HM00Vf0`!sDNJzo} zI!%E ztZV>>Tm1ivS*h4q{=?B$r;3acfd9t3VU$e2;S(gnB@CiMJShTXE>S2^QIQIYW{|@c z8_DP6pC&0QR*BtPzLx|lUdrwl5N=mHi@g!(^pEH?o@}291xrcrI-I7juRUjfeQj`m zdphL?a$i$L=x_D^DDCu(ihQDwL1~AeMh}ZwK`UwpD?sbEwM2|@7{Pa7z5c8^3@G5S zr`g$cd1tR)$0SwVUW?eYwZrVF&EI%GIZH8Ybr5xSp`ta8>z+p_v>jZ?VGq-{*AcBH zYAyXBy;(r)vX3xX|DK{@TB&lET->O)QN}h-Kn~y3O7@%1WtwyFMZHqt&R3B!i=xJ| z_Lzs_q6l0tYo8@NTzl$%)$~^eK|6=lpUl!ypx`JovX`)x)eq2JVZ9p5n)H7@`zQ= z%as~r054FNw?~dpSTjg{IyllBVIO1zx?u@5UPVmvX`Ku*z>sNKiOe$*>iISrG1$JE zJ-*nclIQJPU~m1&`9uZWv5jH9cZg_WnoSNo9np1A7Oe)O?S zDi=8JMm|-Ny=6^Y$#i*H`2iKsAR>)Q0uc(Tg9w9300ro&4-h_xg9oQ^FeC0nOKDr=Efj%S zTAH)YTO5l56)aIzPcL*Wb}jCycy|r9G@d)VdsitEoV%X0Gp9*_BR`3qbvmAN9%MV7 zadvy2rL;_U*x~fhxYMF@+exyPs5lM{7$35NlJOj}ijWKse6+{hVH-#w*I|@S-C>TS zZVOH&3zpK!R%fD-3m%7@2Pn8EhJ7a8BrlMOOlAy5NyQ*H^k$NM!K=aQ&gU2wF3CJj zfU+>jw;(G^8|9-cq;trYE5=}&7iRRBpArd1$)FIZk()B5pH)`M=a5uUDh5rYZbL0E zE6o15dCgN6k6DgsG9ryU&omwjBR!F{96Z5TxH90?_DwiyLPhu&Y#C#ny1RZ?m}ZkA zEex!NnL!&;tGLO%QQg%TQj_Abknm}}GV8ds2A#8oQyd}sfqs+LP6BFhrE%7_OS{5eI$ zr3oV6&yB=l#HII#v0rK@5l%yYogR-{)OwCM!}o33154D%Zk`TioMl`Wv_;T-M(!01 z_yKF7mDb%NQw+6C%B4G#g8G zQ68tzfuAY#$~t+Gnw}=Hkt8{DU0ew)Oi$XSVpA9q_k)i%kRo+DP1eKb;XY$q93MAV zmua_DpVfo=`OZi8u=+yCepV+>C;LWku(ZbX&%qK4QrG+2*uqw!wb*PO13$YskS{?uW=EGgRctq9p zfh-(ud-L*)bGUqLH`R9>$SQc@fS;}g-*IhW6t5EH6c+8-l5QF+;SggNPcJ)aCfAt3Zp;*%YAEe{;JG!E%2-h4Po{W`3l+1+(seGQ5I)8Z#mgc zP?6$;Nb}S91VqVDN>MJEu;@lpG#Jnbmx@dmv4mb5p6_=Z4&qzA7kRhGzlwxqB#pchs zO6W%hR)~13T8VJ&QA;&gjf$^KmWzP-lm`#8_0GLkPhjnf zyufn7EI(VB7`1cMJ4|Cf_l@?MLfXEjuU`*!9eD%DrGjJ(azqC1C>e9~oeh-XIJ5O!Vep)U( z($W6}N=KnoTx|?RuAaG0C&DB=%jY;&;xG@(!oFIkK9h;b3_3^}P#{cM^O(uY{K#=Y zH3bvg$C=9`5uREie2*48Sq42ZBrevN#+od6UI#)Vqvk+!GRz0#x@`laD_`JwNot_F ziIxItV7)dJ`%$VoZXK=5zXl2#B47`gDODs=RO(iooITD`#W5?_w=Oh9!|vU`kRnu0-0@5WPp^pMLll6ziysTcGL=@GS_3 zwT;ovj;Df{nQ@_2)HI87EFCdOLH@VC?ww7V zhiHebgsVi-%_MTzhwLETk=bOP*%)51on)R0qA6`0>W`+N*&w0GJmf8!R~LjmvdR;C`g)a8z-yRWV>t z!v^NNE{*|F~kpH6WDTa&YpZ5*zq&# zuybYDQ01s{SaE`J-I5j3ssGX1VKs86B6@;qg_S?hC(bdav4jIP4ARShYHbS>XfDgL zq_wm*gluUNI*5^DLBDRD#rC2EvcTyjp-9=d)i7SJxM&pMZ0YWs7-OCOG?kW|%RO;%h%NDQa7S z{Yq5RMCvfCN+-Rz)A>DC&f%2A>?)dHIYku8H?OTH=XTX6ID(x__b@gW=s%@9KfivW zRX+z+;=|9-*I5BsHG>(zI^nf{$qNih;jZ+Jq@Qt4FFQQv3 zdyx|_U zO5sxG5$yrOB@~9OVVqO+u>eDtC*A`k#Yn~5tpeAScebSKXikvu^L8S;QOM_AYcA=d zFCF5ogh;Y@TjDZlECsSh2No*d9DJIW#?hAOHYQ-R7t9I^yoKaX6LPX|eiHkKH<$;I zI};H-`H5aF%v$Q$sA5BVL)SC#N@K-(_{EHg>mDQoUoARtFW|tDbr&~Pl)SCckipMD zZDhHWi2m62j<^BdgN+Gi|GHk%Eog>?-=cf&m2u&4C>-+3Iqw`d%cm~@$l(z^6lxi% zg+7^QRS37P`N!bQw0j3|2u6CC+I7ctp{2=$2^fENZP|EVDzb#RisumeEsB-M&2h8b zH>PBds6aXHH7nEm5&at1)P2)9t(-)5BAN8Zb11@s!Dz4o7pb4XMMxb1Frv%_O5Fkc zq$Lf{zCZ{15Og40y`1Gg_b9}8lL_xT@HYGTyE1Ovx_^pAtHp4?;)!DM6)$fL>q>3! zgpM1FZP6Y3l^j8Kgv9-d-0#RawNnIg+#1q~9I@X9eyzvB;|Zm2*c@-U16HJVhgm+T zou;Mchc3YGDpB(9NH3Fx!8k@B1udNs;2F57aX2w~V|csIJy<~b`N%mrQGnqJ?~vi4 z$Ckt!lW91DjN|7F+W*s&p`)zQ|2!EHZf}?&z6P>o(;Kz`6ygUi>lnHhet{)Vl8+qw z5Ke5#bM~{pO(gG^I9`m!LiJ&Gr_uh*Ti4x85RQ;UANa88)1g4Dn$6XyFp}16&;*uV zr*6|9eKyk7w_J%}g%rw-!J8MqQl6+LJ@L}$$YxO{owAFaJ&_7gj_=%*oDy;d=K?4Q zoDs|5iE1DQd7^*mlEH*obc|Vb-(eK*ecLolqOmm)tHSk3kJUCblOz^sYpI7IMNv-I zU5IiJ(b|ZDo|h}VeDGc`<@w^(O>a)8(z|Zq;So^6)k2`wR{0ZQ|2x&Iq6_LmY8ugG zpg1$BgGax0+xL0Te3*!`h{B2t^>e{XJr7DECH&>c;A&=Os&>YP9dlels_bkLu+=7v zY2nmx(K!QL)g6cCW5gctlL6F2VPu;=(c*rxp>-3Ua9TG!wH=71aQt1W=kP>)J?z&= zlk0qu;NE2WB|798svxrj#gkZ=IwdT`c$pSv@bT)~)yJQc%Hc9+DE)OtgvCOU1|G)AM3Wy%?W-`sb8>~AGu#c0+g^}l8zjpn!Cz{7#iZRkFzuf2 z=tc-E>&Q{S&`;rrA6!uhFDVU&|714w%EH5hWCCg05FQImbXE}h)DXH9f!A>u8Y{VC zV`tMKm`$9jqPrpQ-m!98ev9G;y%v%>2bQhDx)E;Vq7y5GY;vI2Z;fZt^MpFgAoflE zs0VRKh3s3YroOTWJKf38m(oi5@{)^=Pu=&22@=9Rm?stP;g*=B*ls_uF~KA^CwVR< zB1sOkWcK@{gyqq1!%u; zQHoMDfUehALvh3bx{Np!BRWyb*G6#6gH>`3ytuD|>W(;d=gv5w!LT*7?<+%_ZJXYf z!?~f4?(3kKJ(O!6G@wDz1okQ;2<`Iu>|+V~M&dH9by0)?_t1e+!Xs)f1`K!Vg85DE}dw$^wC3 zRPnc3vP#gQHOIf$IYix=Ml#l*!af?F^F}UGXG;wJY>NDZK<*HR;*&2-X>WjLXbLw& z*b@r1%Xvb!!57*uoNqI$p!s{0mkG5xEA*TW&UF)ET*0iN+1MU=0{^)Lf9PG6hzK#HV zrf7aaL?7X=T4!8{=N8edb43vwSNY%{u{>H^itHC+CAfUE37}i9hVB_(qa7_N6{gE_ zW%uF5_KKSyG@b=1%M?2xJ!P7jqlOUua(|Am(MtiTM5Xyo12UuBFTsjiFuE zH0fPMkgE8;p{7XX2(jYB=avk8Q&T!DX}hQ8z2jcc@a=JVrmsF&p}j|bxiii08y+Z^ zOFbf2x|_#nJbD@vl3TAlufU16{dSiWQDRrsRkQX3x7hL9B>N|YpIuzpUu&Yt&nmom zypy^|S4TNOa=PMW^TG*vA4rOQV5iMd4)0A7fh!8^c$d$!n8>TB zF1Ft0ri@;ZX|YE#XW!xyvL1FTxyKP)if#EMc$Y11pzWs2P7a4;HyF?8TD7P3Eqo3s zTzDbc&oB3tIUQ4J=U2q8pKD3`MibJ1(3>qX@cGMk3LUGDzgl!r7MvKK95loFIS_Br?707I zd-nD&YrTQy4CV!}MQjMz>>~TmZQ}nsYcTp(a{6zaf&V&URy)?kQN#2xp`WOihLorC zBReA7tEZ9rMzR7#ne=TS5D1{&L^6LEm_?I7$8F?_CS)n|xk~fgRis%o?sNA|j=b*!SdOEK%aU;jc=trd!Ne2afp^ZGgUg%y`Dr&0M<~C@j6WD^P9)Kn zAPW+El|cg(ebdWKH=dduB?V<}Zu+^c*;ds6^vig+j>;WoDn4uxT(tb9Fg1${PA#R& z2P`k(8qo_8RNe6JC*uk%JJeKNSR&YHMEB`#zP$dnp?B;-LoI=OEtVI!TFB$)&|l8W z?tMTP3l4iMS?_^$(7E_gV(`O;kEwhr^-5T6GgR4pt?a)~r7g3#4$&RMc!rZpZ;K2tXR57pXn2k-|xMbXfX1-rEmhysisVdLH zgK}BPiVTM-mDU0gfudFwOYl*bHr+VpYS78nu%=1{$&^=Hy4XI+D(>hS&Ve1`GQHXK zOVFCsu+gX!(qjl|YLm}U%qbvF@JyIUDTlHG5%Bu^@kRe^j}&M)U>OgNhV!`Y6r64h+EVdg1@8GyPGd zkN*B}qZ{fq#*WqW3T^th6hoZv@S2s&9Myq&2uexXZy)*|q|Y2q?1CBTtH5^&UjFgu z#cvTHsQ7N&W^Vi+EjS_rpz)UOxiZI(BK-B>@OvOQ$yqx5avaso?!kP@^r5;H5!!P$ zCzfv2XD%$CMF(w{5i;7;?1lQzFFe6Q*3vi;jz`E1_gaz~)O?D4770{s?`_j4Jmh#3gmDRFvrW?r246BEZwjv;VfIVC2YVPPvXXol-Fq5 zK~O<=9fUJBL>)EAleChlN~S^ElGvj^+1}2j=yP?8xFlL9R%s;h z2v1!QUrJt#;p)Pd(`mGEW?{VWSwBs923W1pKR$QF$ymd7T?sVbfFY;V)i>LOA7*$N zAb_$x$|!xe{M!w`KUP;vZq5}@t~4QJ5_b)mYA(qFLaL6y#YaJuew2!{PwNQ8C>4~V z=efnEsOkQfKd4+NTBB!CEKr}}xXBmf#j+m#2y``KA8%|}2-joXpi2}Zl- zkHp_Ru+l4DBa@Hx{9#L}msmM*kqn|x`UN8)FKHV$5*hqI4mSz~A9Bp^a^WBZOi!A| zo>QG=X$xUDTx_|Sjf~EH62G8vv{M(i`Pk>FBgC>?>xt=E91rKYSHY@P5B-t0>W#Q9 zGQ`FsjFZ5!6dREQp$Of6!6aVAJyZZ7uh3sPl0f2_$h})Bx?LwOg7ah_t(eNnNns8T zCC9rmZ6Ns_FKD7C zKHXgjK=EBG=TJk`N)kcN;18xnTfM5Q(q0XhN=b2M~Pf`62I=6X>JzQ_Q{OIjj6j9C|`$ireF+CzXMWwLo z?8`0CdKI?ZD{lM3H^%jEnDIrM#O0n~+P*U3ebADN*hUkSx77j*bhW0!4hS&x)lb*n_m)$ctff97nz~@}8M!AQMDV z;`Pi`$v|bBs%cS5)b6)c^v0h-XHnA`EXZ7JFeQ@-Ymn_No$MoaV!tj(LJz1@+g;PT zEtB}WPU&!7p-@JN=U6I`Lm@SD{#b9=w3|LVr~GJE)3rl-BckS^76)n9t~$qx&I`;~ z{N_A9o~mRuZI8q+=c==%;uw`O9+BEphM1l6X`@o^wsj;vzpQb91f;Ol( zd<*8i1L3|2=ClGhXBGhj?9luV4#e;AYQMV?QA*l!bDvOn*K5wi{EQ#uLG@7sjTOpE z?}3Rz&BRq1H3E8D^j#If+fR#6k+w@Ntac*cQ%gZ5=1hGPFJ(XLX^>pz&8Dq-P6Oh0 z0TQ)<*!9%D1eSV=@>FqRe*w$1ezO1n^QL~0?SeYk0&X_lY;aaYqssch-q_70~$tYgy=n^Ya`P*sU#+# zrQ95$^Mfu`!0JTWB?oay^)FMRR=8Ys8k`e|+TykK_o*BMc|v+qTL?oX@{G8HZ8$0| z96Al4Ur-&jbhH~SSxr<(=OovWn?+9J!S7UyfWX#+E*lb28k2Zc-S7P8`|-*Ope+)) zsm#%MJ;>am=U^*T(QyhCc9TnTOYGRBxMGclDcgK6rED13l|LnSs>IT*!j<&pK#jU= z;T$C(NeIDvpgLvMYTMy7(^6U<3d;gCR#0HGoV3|wY#0(~F7LlTLEqI;5CcuBS)c9G zu8!N*(q@}3xNLOeB-GE;hKFF8FjVC7OOx+EX!c(Vum2DzmMV++G&|i)HGhHe3k!`T zZ{`jAoH8-#Mn;DaepN0e_$-pz<->WhdC~Tm0u8%vP;O#n^!FZ3a8#d!u8KbG^7&3{ ztvp`}DSiw%>96AFbX+3eqBu@R9W?3XjXo-@059+GCGHRsSw4mOh@3R!c*m(e==xI` zD9?&<(~b<2UO(M~wBi_?2CB~v+J>IzpCW`cWqytMF};I6@G+Js55LdukphSJ6Pds6 zx7$*tpROmQ(YZQQH-{w80zc(@ z@ed1O@MBe@a7pTdFvwOEhF&BY830}(a+|dn!(bAwoGv*z2zGN|_qXJO``Ssk^D9=B z&aObamu_xJtbS{@?)uBFF!Hcg!W;+DvOARGMOft9J2Fu%mmxtfKu9kPAf%V;Z^np& zt%b3n)Bi$;oE0x6*Y^n}Xc`Pu*o$AjKmVi$G#$fvmslZ^I-dmNPKZ01(K-Yc1nNyv zjg0O$8Qfiza>ga$U7E9_OwP?~z#`I)ixT7>{FUjToc`flES~1CJwVP5TZ2|-J45Nj~!PpgVt5A z{J2-dbEs+Wb14J91lcrNDg_f8Iyg(K-`ty;dCe{g1_wr2RNeH5PTXo7F5^}SAEq5n z#T=3@O5d-MCL%9@M$p1l)u(5p2|qGPK=y7v-1&|}fi73t-VeA4k|<4BOnW(7AS)%;=bdqR-N z%@N831~f96e@(wlX0~or!c4G89sA90C*Vxy((-K(IG%@D%T~2>=|ufd=Hj~@YauvqwiL!cgiYn| z)MKSlAtyOL(SOQTF@=((+BdBGXpBnj7%)c7*abZgdPZVb+;!dfg{?a;joyhCY?3CQ zyUYymlP+Hqx}4AQMDy((yDa=$zZyV42?($h{y%l~fARSP0zUqk%YW}ZgFhrBBmhDH zaQ#s*0JjFt=2k|u4#tMY=5|hhRt1ovrJ9XHJjTsyekpcnvGTya= z2B`VlW64Vae?a-|?oa3dEBm_=PUCN1pKiY;Q9^rk3tE! z{eP>;2*^r^iYO`5$%wv3_^rmj8wLa|{;6aE?thah_@^2G{-HmW-hb8jm$1P;Ww3A6od` zUwaSd?kAm}2Y?v^T)&ZI|526!=Kc?Gfaf)JFm`m52B^Io+x%OA;ypa2M`3>lpew^* zf6s;Z1AY|qZ{YzH+*Zzx04^C(b1P#3Lqk9dGWs_9rvI&htlLpg4?u?p13LUSMZiDG z0>R%lAm*SCP)}6>Fjb1%S{qB-+FCl>{e9PvZ4aY80Bo)U&=G(bvOkp!fUW#Z*ZdBx z1~5E;QtNNF_xHGuI~e=r0JK%WMf4|BAfPq6zr~gKx7GbU9``Cak1xQw*b(024blHS zo{giEzLnK~v*BOHH&%3jX~l>d2#DY>&ldzp@%x+q8^8ec8{XeP-9eLe z{$J28rT!L8+Sc^HzU@GBexQ25pjQQWVH|$}%aZ+DFnNG>i-4n}v9$p}F_%Qz)==L{ z7+|mt<_6Ax@Vvh_+V^tze>7Ai|Nq^}-*>}%o!>t&fzO6ZBt23g4r?*WLL8)z|!gQsH?I_!|Jg%KoqXrnK`% z*#H3k$!LFz{d`~fz3$E*mEkP@qw>F{PyV|*_#XbfmdYRSsaF3L{(o6Yyl?2e;=vyc zeYXFPhW_;Y|3&}cJ^Xv>{y*R^9sUXaowxiR_B~_$AFv8e{{;KzZHV`n?^%ogz|8ab zC(PdyGydDm_?{p5|Ec8cRTBuJD7=ktkw-{nV;#0k5o;S?!9D>&LLkM0AP6Feg`f{0 zDQpB`k<`JrvB<<-J;OKd%+1!z`DQP}{M_XnsTQvW)#kKd4xjO+0(FK~P*t8f?34gT zNeb{dG5{jMk|Z%xPNd?)Kr$uFk;z0bG4oFYGnNlV6q8Vd`WhQhkz5p#m^vZSc48n^ z)8XlE1_e=c^$WG1no(|j8Tc`PgwP}{$Z2MV1V$=SXvP)gXKtqW)?5PUcJu&?e*#h! zqs>gH(jDQk$9cz8;-w$cc*dE1}qLepfsBCXA@(bAJ66ft0aCq$Wrcq)WXX{0nm+#w=uBj1o9rLyA i;x|p)^~-yfPOPa3(|vBayXKz \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/SpringBootTakaoBot/gradlew.bat b/SpringBootTakaoBot/gradlew.bat deleted file mode 100644 index f955316..0000000 --- a/SpringBootTakaoBot/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/SpringBootTakaoBot/settings.gradle b/SpringBootTakaoBot/settings.gradle deleted file mode 100644 index 063ca14..0000000 --- a/SpringBootTakaoBot/settings.gradle +++ /dev/null @@ -1,6 +0,0 @@ -pluginManagement { - repositories { - gradlePluginPortal() - } -} -rootProject.name = 'SpringBootTakaoBot' diff --git a/SpringBootTakaoBot/src/main/META-INF/MANIFEST.MF b/SpringBootTakaoBot/src/main/META-INF/MANIFEST.MF deleted file mode 100644 index 42677c6..0000000 --- a/SpringBootTakaoBot/src/main/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Main-Class: it.discordbot.StartBotKt - diff --git a/SpringBootTakaoBot/src/main/resources/jsonboss.json b/SpringBootTakaoBot/src/main/resources/jsonboss.json deleted file mode 100644 index 96829ae..0000000 --- a/SpringBootTakaoBot/src/main/resources/jsonboss.json +++ /dev/null @@ -1,387 +0,0 @@ -[ - { - "giorno": "MONDAY", - "bosses": [ - { - "nomeBoss": [ - "Kutum", - "Karanda" - ], - "ora": "0:15" - }, - { - "nomeBoss": [ - "Karanda" - ], - "ora": "2:0" - }, - { - "nomeBoss": [ - "Kzarka" - ], - "ora": "5:0" - }, - { - "nomeBoss": [ - "Kzarka" - ], - "ora": "9:0" - }, - { - "nomeBoss": [ - "Offin" - ], - "ora": "12:0" - }, - { - "nomeBoss": [ - "Kutum" - ], - "ora": "16:0" - }, - { - "nomeBoss": [ - "Nouver" - ], - "ora": "19:0" - }, - { - "nomeBoss": [ - "Kzarka" - ], - "ora": "22:15" - } - ] - }, - { - "giorno": "TUESDAY", - "bosses": [ - { - "nomeBoss": [ - "Karanda" - ], - "ora": "0:15" - }, - { - "nomeBoss": [ - "Kutum" - ], - "ora": "2:0" - }, - { - "nomeBoss": [ - "Kzarka" - ], - "ora": "5:0" - }, - { - "nomeBoss": [ - "Nouver" - ], - "ora": "9:0" - }, - { - "nomeBoss": [ - "Kutum" - ], - "ora": "12:0" - }, - { - "nomeBoss": [ - "Nouver" - ], - "ora": "16:0" - }, - { - "nomeBoss": [ - "Karanda" - ], - "ora": "19:0" - }, - { - "nomeBoss": [ - "Garmoth" - ], - "ora": "22:15" - } - ] - }, - { - "giorno": "WEDNESDAY", - "bosses": [ - { - "nomeBoss": [ - "Kutum", - "Kzarka" - ], - "ora": "0:15" - }, - { - "nomeBoss": [ - "Karanda" - ], - "ora": "2:0" - }, - { - "nomeBoss": [ - "Kzarka" - ], - "ora": "5:0" - }, - { - "nomeBoss": [ - "Karanda" - ], - "ora": "9:0" - }, - { - "nomeBoss": [ - "Manutenzione" - ], - "ora": "12:0" - }, - { - "nomeBoss": [ - "Kutum" - ], - "ora": "16:0" - }, - { - "nomeBoss": [ - "Offin" - ], - "ora": "19:0" - }, - { - "nomeBoss": [ - "Karanda", - "Kzarka" - ], - "ora": "22:15" - }, - { - "nomeBoss": [ - "Quint/Muraka" - ], - "ora": "23:15" - } - ] - }, - { - "giorno": "THURSDAY", - "bosses": [ - { - "nomeBoss": [ - "Nouver" - ], - "ora": "0:15" - }, - { - "nomeBoss": [ - "Kutum" - ], - "ora": "2:0" - }, - { - "nomeBoss": [ - "Nouver" - ], - "ora": "05:0" - }, - { - "nomeBoss": [ - "Kutum" - ], - "ora": "9:0" - }, - { - "nomeBoss": [ - "Nouver" - ], - "ora": "12:0" - }, - { - "nomeBoss": [ - "Kzarka" - ], - "ora": "16:0" - }, - { - "nomeBoss": [ - "Kutum" - ], - "ora": "19:0" - }, - { - "nomeBoss": [ - "Garmoth" - ], - "ora": "22:15" - } - ] - }, - { - "giorno": "FRIDAY", - "bosses": [ - { - "nomeBoss": [ - "Karanda", - "Kzarka" - ], - "ora": "0:15" - }, - { - "nomeBoss": [ - "Nouver" - ], - "ora": "2:0" - }, - { - "nomeBoss": [ - "Karanda" - ], - "ora": "5:0" - }, - { - "nomeBoss": [ - "Kutum" - ], - "ora": "9:0" - }, - { - "nomeBoss": [ - "Karanda" - ], - "ora": "12:0" - }, - { - "nomeBoss": [ - "Nouver" - ], - "ora": "16:0" - }, - { - "nomeBoss": [ - "Kzarka" - ], - "ora": "19:0" - }, - { - "nomeBoss": [ - "Kutum", - "Kzarka" - ], - "ora": "22:15" - } - ] - }, - { - "giorno": "SATURDAY", - "bosses": [ - { - "nomeBoss": [ - "Karanda" - ], - "ora": "0:15" - }, - { - "nomeBoss": [ - "Offin" - ], - "ora": "2:0" - }, - { - "nomeBoss": [ - "Nouver" - ], - "ora": "5:0" - }, - { - "nomeBoss": [ - "Kutum" - ], - "ora": "09:0" - }, - { - "nomeBoss": [ - "Nouver" - ], - "ora": "12:0" - }, - { - "nomeBoss": [ - "Quint/Muraka" - ], - "ora": "16:0" - }, - { - "nomeBoss": [ - "Karanda", - "Kzarka" - ], - "ora": "19:0" - }, - { - "nomeBoss": [ - "Conquest War" - ], - "ora": "22:15" - } - ] - }, - { - "giorno": "SUNDAY", - "bosses": [ - { - "nomeBoss": [ - "Nouver", - "Kutum" - ], - "ora": "0:15" - }, - { - "nomeBoss": [ - "Kzarka" - ], - "ora": "2:0" - }, - { - "nomeBoss": [ - "Kutum" - ], - "ora": "5:0" - }, - { - "nomeBoss": [ - "Nouver" - ], - "ora": "9:0" - }, - { - "nomeBoss": [ - "Kzarka" - ], - "ora": "12:0" - }, - { - "nomeBoss": [ - "Vell" - ], - "ora": "16:0" - }, - { - "nomeBoss": [ - "Garmoth" - ], - "ora": "19:0" - }, - { - "nomeBoss": [ - "Kzarka", - "Nouver" - ], - "ora": "22:15" - } - ] - } -] \ No newline at end of file diff --git a/build.gradle b/build.gradle index f3f83b5..7a12f46 100644 --- a/build.gradle +++ b/build.gradle @@ -1,101 +1,100 @@ plugins { - id 'java' - id 'application' - id 'com.github.johnrengelman.shadow' version '2.0.1' + id 'org.springframework.boot' version '2.1.4.RELEASE' + id 'org.jetbrains.kotlin.jvm' version '1.3.31' + id 'org.jetbrains.kotlin.plugin.spring' version '1.3.31' + id 'java' + id 'application' + id 'com.github.johnrengelman.shadow' version '4.0.4' } -mainClassName = 'starter.start' - -group 'it.github.samuele794.discordbotTakao' -version '1.2.0' -def jdaVersion = '3.8.2_459' +apply plugin: 'io.spring.dependency-management' +group = 'it.discordbot' +version = '2.0' +sourceCompatibility = '1.8' repositories { - jcenter() - mavenCentral() - maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + mavenCentral() + jcenter() } -dependencies { - testCompile group: 'junit', name: 'junit', version: '4.12' +jar { + enabled = true +} + +springBoot { + buildInfo() +} - compile "net.dv8tion:JDA:3.8.2_459" - // https://mvnrepository.com/artifact/com.rometools/rome - compile group: 'com.rometools', name: 'rome', version: '1.12.0' - // jsoup HTML parser library @ https://jsoup.org/ - compile 'org.jsoup:jsoup:1.11.3' - // https://mvnrepository.com/artifact/com.google.code.gson/gson - compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5' +bootJar { + classifier = 'boot' + manifest { + attributes 'Start-Class': 'it.discordbot.StartBotKt' - compile "org.apache.commons:commons-text:1.3" - // https://mvnrepository.com/artifact/org.quartz-scheduler/quartz - compile group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.0' + } + launchScript() +} - // https://mvnrepository.com/artifact/org.postgresql/postgresql - compile group: 'org.postgresql', name: 'postgresql', version: '42.2.5' - // https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -// compile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.25.2' +dependencies { - //SISTEMA PER LOG - compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' - compile group: 'ch.qos.logback', name: 'logback-core', version: '1.2.3' - // https://mvnrepository.com/artifact/com.sedmelluq/lavaplayer-natives - compile group: 'com.sedmelluq', name: 'lavaplayer-natives', version: '1.3.12' + implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.jetbrains.kotlin:kotlin-reflect' + annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" + implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' + testImplementation 'org.springframework.boot:spring-boot-starter-test' -// compile 'com.sedmelluq:lavaplayer:1.3.11' // https://mvnrepository.com/artifact/commons-validator/commons-validator - compile group: 'commons-validator', name: 'commons-validator', version: '1.6' + //SPRING LIBRARY + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web + implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.4.RELEASE' + implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.+" - //JDA 3.8.2 - // https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp - compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.14.0' - //DIPENDENZE PER MUSICBOT - // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient - compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.7' - // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core - compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.8' - // https://mvnrepository.com/artifact/commons-io/commons-io - compile group: 'commons-io', name: 'commons-io', version: '2.6' - // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind - compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8' + implementation 'net.dv8tion:JDA:3.8.3_463' - //TwitterAPI - // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-core - compile group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7' - // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-stream - compile group: 'org.twitter4j', name: 'twitter4j-stream', version: '4.0.7' - // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-async - compile group: 'org.twitter4j', name: 'twitter4j-async', version: '4.0.7' + //RSS + HTML PARSER + // https://mvnrepository.com/artifact/com.rometools/rome + implementation group: 'com.rometools', name: 'rome', version: '1.12.0' + // jsoup HTML parser library @ https://jsoup.org/ + implementation 'org.jsoup:jsoup:1.11.3' - compile "org.hibernate:hibernate-core:5.4.2.Final" + //ESCAPE UTIL + // https://mvnrepository.com/artifact/commons-io/commons-io + implementation "org.apache.commons:commons-text:1.3" + //POSTGRESQL DRIVER + // https://mvnrepository.com/artifact/org.postgresql/postgresql + implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.5' -} + //TwitterAPI + // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-core + implementation group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7' + // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-stream + implementation group: 'org.twitter4j', name: 'twitter4j-stream', version: '4.0.7' + // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-async + implementation group: 'org.twitter4j', name: 'twitter4j-async', version: '4.0.7' + + //MUSIC PLAYER + implementation 'com.sedmelluq:lavaplayer:1.3.17' -javadoc { - options.showAll() - options.setDestinationDirectory() - options.encoding('UTF-8') - options.setUse(true) - options.author(true) - options.version(true) - options.windowTitle("Documentazione TakaoBot") - options.docTitle("Documentazione TakaoBot") - exclude("com/sedmelluq/**") } -if (JavaVersion.current().isJava8Compatible()) { - tasks.withType(Javadoc) { - // disable the crazy super-strict doclint tool in Java 8 - //noinspection SpellCheckingInspection - options.addStringOption('Xdoclint:none', '-quiet') - } +compileKotlin { + kotlinOptions { + freeCompilerArgs = ['-Xjsr305=strict'] + jvmTarget = '1.8' + } } +compileTestKotlin { + kotlinOptions { + freeCompilerArgs = ['-Xjsr305=strict'] + jvmTarget = '1.8' + } +} compileJava.options.encoding = 'UTF-8' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 74aea4b..290541c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Sun Jan 13 11:13:41 CET 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-all.zip diff --git a/settings.gradle b/settings.gradle index bf400d9..a5ff7be 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,6 @@ -rootProject.name = 'discordbotTakao' - +pluginManagement { + repositories { + gradlePluginPortal() + } +} +rootProject.name = 'TakaoBot' diff --git a/src/main/META-INF/MANIFEST.MF b/src/main/META-INF/MANIFEST.MF index 93d0a2d..42677c6 100644 --- a/src/main/META-INF/MANIFEST.MF +++ b/src/main/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ Manifest-Version: 1.0 -Main-Class: starter.Start +Main-Class: it.discordbot.StartBotKt diff --git a/src/main/java/beans/BDOBossBean/Boss.java b/src/main/java/beans/BDOBossBean/Boss.java deleted file mode 100644 index 90c6d15..0000000 --- a/src/main/java/beans/BDOBossBean/Boss.java +++ /dev/null @@ -1,67 +0,0 @@ -package beans.BDOBossBean; - -import java.util.ArrayList; - -/** - * Rappresentazione dei boss - */ -public class Boss { - /** - * Lista boss dell'ora - */ - private String[] nomeBoss; - - /** - * Ora di spawn - */ - private String ora; - - public Boss(String[] nomeBoss, String ora) { - setNomeBoss(nomeBoss); - setOra(ora); - } - - /** - * Metodo per ottenere i boss dell'ora - * - * @param ora Ora di spawn del boss - * @param minuto Minuto di spawn del boss - * @param lists Lista dei boss del giorno - * @return Lista dei boss dell'ora indicata - */ - public static String[] getHourBoss(int ora, int minuto, ArrayList lists) { - String time = new StringBuilder(Integer.toString(ora)).append(":").append(minuto).toString(); - for (int cont = 0; cont < lists.size(); cont++) { - - Boss boss = lists.get(cont); - - if (boss.getOra().equals(time)) { - return boss.getNomeBoss(); - } - - } - - return null; - } - - /** - * Ottieni i nomi dei boss - * @return - */ - public String[] getNomeBoss() { - return nomeBoss; - } - - private void setNomeBoss(String[] nomeBoss) { - this.nomeBoss = nomeBoss; - } - - - private String getOra() { - return ora; - } - - private void setOra(String ora) { - this.ora = ora; - } -} diff --git a/src/main/java/beans/BDOBossBean/Giorno.java b/src/main/java/beans/BDOBossBean/Giorno.java deleted file mode 100644 index 67c0e0d..0000000 --- a/src/main/java/beans/BDOBossBean/Giorno.java +++ /dev/null @@ -1,50 +0,0 @@ -package beans.BDOBossBean; - -import java.util.ArrayList; - -/** - * Rappresentazione del giorno di spawn dei boss di BDO - */ -public class Giorno { - - private String giorno; - private ArrayList bosses; - - public Giorno(String giorno, ArrayList bosses) { - setBosses(bosses); - setGiorno(giorno); - } - - public static Giorno getDayBosses(String giorno, ArrayList list) { - giorno = giorno.trim().toUpperCase(); - if(list != null & (giorno != null | giorno.equals("")) ){ - for (int cont = 0; cont < list.size(); cont++) { - Giorno bossListDay = list.get(cont); - if (bossListDay.getGiorno().equals(giorno)) { - return bossListDay; - } - } - - throw new IndexOutOfBoundsException("Giorno non trovato"); - }else { - throw new NullPointerException("Qualche parametro a null"); - } - - } - - public String getGiorno() { - return giorno; - } - - private void setGiorno(String giorno) { - this.giorno = giorno; - } - - public ArrayList getBosses() { - return bosses; - } - - private void setBosses(ArrayList bosses) { - this.bosses = bosses; - } -} diff --git a/src/main/java/beans/RSSMessage.java b/src/main/java/beans/RSSMessage.java deleted file mode 100644 index 04d9002..0000000 --- a/src/main/java/beans/RSSMessage.java +++ /dev/null @@ -1,75 +0,0 @@ -package beans; - -import org.jsoup.nodes.Document; - -/** - * Classe contenitore per il titolo, il link e il body HTML - * del feed RSS - */ - -public class RSSMessage { - private String title; - private String link; - private Document doc; - - - public RSSMessage(String title, String link, Document doc){ - setTitle(title); - setLink(link); - setDoc(doc); - } - - /** - * Metodo per ottenre il titolo del feed - * - * @return String titolo del feed - */ - public String getTitle() { - return title; - } - - /** - * Metodo per ottenre il titolo del feed - * - * @param title titolo del feed - */ - public void setTitle(String title) { - this.title = title; - } - - /** - * Metodo per ottenere il link del feed - * @return String - */ - public String getLink() { - return link; - } - - /** - * Metodo per impostare il link del feed - * @param link Url del feed in stringa - */ - public void setLink(String link) { - this.link = link; - } - - /** - * Metodo per ottenere il body del feed RSS - * @return documento HTML - * - * @see org.jsoup.nodes.Document Document - */ - public Document getDoc() { - return doc; - } - - /** - * Metodo per impostare il body del feed RSS - * @param doc documento HTMl - * - * @see org.jsoup.nodes.Document Document - */ - public void setDoc(Document doc) { - this.doc = doc; - } -} diff --git a/src/main/java/beans/Rsslink.java b/src/main/java/beans/Rsslink.java deleted file mode 100644 index a58dc7a..0000000 --- a/src/main/java/beans/Rsslink.java +++ /dev/null @@ -1,73 +0,0 @@ -package beans; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; - -/** - * Tabella RSSLink - */ -@Entity -@Table(name = "`RSSLink`") -public class Rsslink { - - @Id - @Column(name = "`id`") - private long id; - /** - * Lista link ultime news di BDO - */ - @Column(name = "`LastNewsBDO`") - private String lastNewsBDO; - @Column(name = "`LastPatchBDO`") - /** - * Link ultima patch di BDO - */ - private String lastPatchBDO; - /** - * Link ultimo feed di atm - */ - @Column(name = "`LastATMAlert`") - private String lastAtmAlert; - - public Rsslink() { - } - - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - - public String getLastNewsBDO() { - return lastNewsBDO; - } - - public void setLastNewsBDO(String lastNewsBDO) { - this.lastNewsBDO = lastNewsBDO; - } - - - public String getLastPatchBDO() { - return lastPatchBDO; - } - - public void setLastPatchBDO(String lastPatchBDO) { - this.lastPatchBDO = lastPatchBDO; - } - - - public String getLastAtmAlert() { - return lastAtmAlert; - } - - public void setLastAtmAlert(String lastAtmAlert) { - this.lastAtmAlert = lastAtmAlert; - } - -} diff --git a/src/main/java/beans/ServerToChannel.java b/src/main/java/beans/ServerToChannel.java deleted file mode 100644 index ac5d827..0000000 --- a/src/main/java/beans/ServerToChannel.java +++ /dev/null @@ -1,74 +0,0 @@ -package beans; - -/** - * Classe di appoggio per ottenere serverID e channelID - * per i publish del feed RSS - */ -public class ServerToChannel { - - private String serverID; - private String channelID; - - public ServerToChannel(String serverID, String channelID) { - setServerID(serverID); - setChannelID(channelID); - } - - /** - * Metodo per ottenere il serverID - * - * @return serverID - */ - public String getServerID() { - return serverID; - } - - /** - * Metodo per impostare il serverID - * - * @param serverID id del server discord - */ - - public void setServerID(String serverID) { - this.serverID = serverID; - } - - /** - * Metodo per ottenere il channelID - * - * @return String id del canale - */ - public String getChannelID() { - return channelID; - } - - /** - * Metodo per impostare il channelID - * - * @param channelID id del canale testuale - */ - public void setChannelID(String channelID) { - this.channelID = channelID; - } - - - @Override - public boolean equals(Object object) { - if (object instanceof ServerToChannel) { - - ServerToChannel obj = (ServerToChannel) object; - - if (obj.serverID != null) { - if (obj.serverID.equals(this.serverID)) { - return true; - } else { - return false; - } - } else { - return false; - } - } else { - return false; - } - } -} diff --git a/src/main/java/beans/ServersDiscord.java b/src/main/java/beans/ServersDiscord.java deleted file mode 100644 index 11c1b36..0000000 --- a/src/main/java/beans/ServersDiscord.java +++ /dev/null @@ -1,118 +0,0 @@ -package beans; - -import org.apache.commons.text.StringEscapeUtils; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; - -/** - * Tabella contenente tutti gli id dei canali per le funzionalità del bot - */ -@Entity -@Table(name = "`ServersDiscord`") -public class ServersDiscord { - - /** - * Id del server - */ - @Id - @Column(name = "`SERVER_ID`") - private String serverId; - - /** - * Nome del server - */ - @Column(name = "`NAME_SERVER`") - private String nameServer; - - /** - * Simbolo di comando - */ - @Column(name = "`SIMBOL_COMMAND`") - private String simbolCommand; - - /** - * ID Canale per invio news di BDO - */ - @Column(name = "`BDONewsIDChannel`") - private String bdoNewsIDChannel; - - /** - * ID Canale per invio patch di BDO - */ - @Column(name = "`BDOPatchIDChannel`") - private String bdoPatchIDChannel; - - /** - * ID Canale per invio alert boss di BDO - */ - @Column(name = "`BDOBossIDChannel`") - private String bdoBossIDChannel; - - /** - * ID Canale per invio degli alert dell'ATM - */ - @Column(name = "`ATMAlertIDChannel`") - private String atmAlertIDChannel; - - public ServersDiscord() { - } - - public String getServerId() { - return serverId; - } - - public void setServerId(String serverId) { - this.serverId = serverId; - } - - public String getNameServer() { - return nameServer; - } - - public void setNameServer(String nameServer) { - this.nameServer = nameServer; - } - - public String getSimbolCommand() { - return StringEscapeUtils.unescapeJava(simbolCommand); - } - - public void setSimbolCommand(String simbolCommand) { - this.simbolCommand = StringEscapeUtils.escapeJava(simbolCommand); - } - - public String getBdoNewsIDChannel() { - return bdoNewsIDChannel; - } - - public void setBdoNewsIDChannel(String bdoNewsIDChannel) { - this.bdoNewsIDChannel = bdoNewsIDChannel; - } - - public String getBdoPatchIDChannel() { - return bdoPatchIDChannel; - } - - public void setBdoPatchIDChannel(String bdoPatchIDChannel) { - this.bdoPatchIDChannel = bdoPatchIDChannel; - } - - public String getAtmAlertIDChannel() { - return atmAlertIDChannel; - } - - public void setAtmAlertIDChannel(String atmAlertIDChannel) { - this.atmAlertIDChannel = atmAlertIDChannel; - } - - public String getBdoBossIDChannel() { - return bdoBossIDChannel; - } - - public void setBdoBossIDChannel(String bdoBossIDChannel) { - this.bdoBossIDChannel = bdoBossIDChannel; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/Formats.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/Formats.java deleted file mode 100644 index 4fbd823..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/Formats.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container; - -/** - * Standard mime types and codec names for supported formats. - */ -public class Formats { - public static final String MIME_AUDIO_WEBM = "audio/webm"; - public static final String MIME_VIDEO_WEBM = "video/webm"; - public static final String MIME_AUDIO_MP4 = "audio/mp4"; - public static final String MIME_VIDEO_MP4 = "video/mp4"; - - public static final String CODEC_OPUS = "opus"; - public static final String CODEC_VORBIS = "vorbis"; - public static final String CODEC_AAC_LC = "mp4a.40.2"; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainer.java deleted file mode 100644 index 19bbffb..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainer.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container; - -import com.sedmelluq.discord.lavaplayer.container.adts.AdtsContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.flac.FlacContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.matroska.MatroskaContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.mp3.Mp3ContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.mpegts.MpegAdtsContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.ogg.OggContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.playlists.M3uPlaylistContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.playlists.PlainPlaylistContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.playlists.PlsPlaylistContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.wav.WavContainerProbe; - -import java.util.ArrayList; -import java.util.List; - -/** - * Lists currently supported containers and their probes. - */ -public enum MediaContainer { - WAV(new WavContainerProbe()), - MKV(new MatroskaContainerProbe()), - MP4(new MpegContainerProbe()), - FLAC(new FlacContainerProbe()), - OGG(new OggContainerProbe()), - M3U(new M3uPlaylistContainerProbe()), - PLS(new PlsPlaylistContainerProbe()), - PLAIN(new PlainPlaylistContainerProbe()), - MP3(new Mp3ContainerProbe()), - ADTS(new AdtsContainerProbe()), - MPEGADTS(new MpegAdtsContainerProbe()); - - /** - * The probe used to detect files using this container and create the audio tracks for them. - */ - public final MediaContainerProbe probe; - - MediaContainer(MediaContainerProbe probe) { - this.probe = probe; - } - - public static List asList() { - List probes = new ArrayList<>(); - - for (MediaContainer container : MediaContainer.class.getEnumConstants()) { - probes.add(container.probe); - } - - return probes; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDescriptor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDescriptor.java deleted file mode 100644 index 33be777..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDescriptor.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; - -public class MediaContainerDescriptor { - public final MediaContainerProbe probe; - public final String parameters; - - public MediaContainerDescriptor(MediaContainerProbe probe, String parameters) { - this.probe = probe; - this.parameters = parameters; - } - - public AudioTrack createTrack(AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - return probe.createTrack(parameters, trackInfo, inputStream); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDetection.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDetection.java deleted file mode 100644 index 60aad48..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDetection.java +++ /dev/null @@ -1,170 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container; - -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.io.GreedyInputStream; -import com.sedmelluq.discord.lavaplayer.tools.io.SavedHeadSeekableInputStream; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.regex.Pattern; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.unknownFormat; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Detects the container used by a file and whether the specific file is supported for playback. - */ -public class MediaContainerDetection { - public static final String UNKNOWN_TITLE = "Unknown title"; - public static final String UNKNOWN_ARTIST = "Unknown artist"; - public static final int STREAM_SCAN_DISTANCE = 1000; - - private static final Logger log = LoggerFactory.getLogger(MediaContainerDetection.class); - - private static final int HEAD_MARK_LIMIT = 1024; - - private final MediaContainerRegistry containerRegistry; - private final AudioReference reference; - private final SeekableInputStream inputStream; - private final MediaContainerHints hints; - - /** - * @param reference Reference to the track with an identifier, used in the AudioTrackInfo in result - * @param inputStream Input stream of the file - * @param hints Hints about the format (mime type, extension) - */ - public MediaContainerDetection(MediaContainerRegistry containerRegistry, AudioReference reference, - SeekableInputStream inputStream, MediaContainerHints hints) { - - this.containerRegistry = containerRegistry; - this.reference = reference; - this.inputStream = inputStream; - this.hints = hints; - } - - /** - * @return Result of detection. - */ - public MediaContainerDetectionResult detectContainer() { - MediaContainerDetectionResult result; - - try { - SavedHeadSeekableInputStream savedHeadInputStream = new SavedHeadSeekableInputStream(inputStream, HEAD_MARK_LIMIT); - savedHeadInputStream.loadHead(); - - result = detectContainer(savedHeadInputStream, true); - - if (result == null) { - result = detectContainer(savedHeadInputStream, false); - } - } catch (Exception e) { - throw ExceptionTools.wrapUnfriendlyExceptions("Could not read the file for detecting file type.", SUSPICIOUS, e); - } - - return result != null ? result : unknownFormat(); - } - - private MediaContainerDetectionResult detectContainer(SeekableInputStream innerStream, boolean matchHints) - throws IOException { - - boolean checked = false; - - for (MediaContainerProbe probe : containerRegistry.getAll()) { - if (matchHints == probe.matchesHints(hints)) { - innerStream.seek(0); - MediaContainerDetectionResult result = checkContainer(probe, reference, innerStream); - - if (result != null) { - return result; - } - - checked = true; - } - } - - return checked ? unknownFormat() : null; - } - - private static MediaContainerDetectionResult checkContainer(MediaContainerProbe probe, AudioReference reference, - SeekableInputStream inputStream) { - - try { - return probe.probe(reference, inputStream); - } catch (Exception e) { - log.warn("Attempting to detect file with container {} failed.", probe.getName(), e); - return null; - } - } - - /** - * Checks the next bytes in the stream if they match the specified bytes. The input may contain -1 as byte value as - * a wildcard, which means the value of this byte does not matter. The position of the stream is restored on return. - * - * @param stream Input stream to read the bytes from - * @param match Bytes that the next bytes from input stream should match (-1 as wildcard - * @return True if the bytes matched - * @throws IOException On IO error - */ - public static boolean checkNextBytes(SeekableInputStream stream, int[] match) throws IOException { - return checkNextBytes(stream, match, true); - } - - /** - * Checks the next bytes in the stream if they match the specified bytes. The input may contain -1 as byte value as - * a wildcard, which means the value of this byte does not matter. - * - * @param stream Input stream to read the bytes from - * @param match Bytes that the next bytes from input stream should match (-1 as wildcard - * @param rewind If set to true, restores the original position of the stream after checking - * @return True if the bytes matched - * @throws IOException On IO error - */ - public static boolean checkNextBytes(SeekableInputStream stream, int[] match, boolean rewind) throws IOException { - long position = stream.getPosition(); - boolean result = true; - - for (int matchByte : match) { - int inputByte = stream.read(); - - if (inputByte == -1 || (matchByte != -1 && matchByte != inputByte)) { - result = false; - break; - } - } - - if (rewind) { - stream.seek(position); - } - - return result; - } - - /** - * Check if the next bytes in the stream match the specified regex pattern. - * - * @param stream Input stream to read the bytes from - * @param distance Maximum number of bytes to read for matching - * @param pattern Pattern to match against - * @param charset Charset to use to decode the bytes - * @return True if the next bytes in the stream are a match - * @throws IOException On read error - */ - public static boolean matchNextBytesAsRegex(SeekableInputStream stream, int distance, Pattern pattern, Charset charset) throws IOException { - long position = stream.getPosition(); - byte[] bytes = new byte[distance]; - - int read = new GreedyInputStream(stream).read(bytes); - stream.seek(position); - - if (read == -1) { - return false; - } - - String text = new String(bytes, 0, read, charset); - return pattern.matcher(text).find(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDetectionResult.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDetectionResult.java deleted file mode 100644 index 6aeb8e6..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerDetectionResult.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container; - -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; - -/** - * Result of audio container detection. - */ -public class MediaContainerDetectionResult { - private static final MediaContainerDetectionResult UNKNOWN_FORMAT = - new MediaContainerDetectionResult(null, null, null, null, null); - - private final AudioTrackInfo trackInfo; - private final MediaContainerProbe containerProbe; - private final String probeSettings; - private final AudioReference reference; - private final String unsupportedReason; - - private MediaContainerDetectionResult(AudioTrackInfo trackInfo, MediaContainerProbe containerProbe, - String probeSettings, AudioReference reference, String unsupportedReason) { - - this.trackInfo = trackInfo; - this.containerProbe = containerProbe; - this.probeSettings = probeSettings; - this.reference = reference; - this.unsupportedReason = unsupportedReason; - } - - /** - * Creates an unknown format result. - */ - public static MediaContainerDetectionResult unknownFormat() { - return UNKNOWN_FORMAT; - } - - /** - * Creates a result ofr an unsupported file of a known container. - * - * @param probe Probe of the container - * @param reason The reason why this track is not supported - */ - public static MediaContainerDetectionResult unsupportedFormat(MediaContainerProbe probe, String reason) { - return new MediaContainerDetectionResult(null, probe, null, null, reason); - } - - /** - * Creates a load result referring to another item. - * - * @param probe Probe of the container - * @param reference Reference to another item - */ - public static MediaContainerDetectionResult refer(MediaContainerProbe probe, AudioReference reference) { - return new MediaContainerDetectionResult(null, probe, null, reference, null); - } - - - /** - * Creates a load result for supported file. - * - * @param probe Probe of the container - * @param trackInfo Track info for the file - */ - public static MediaContainerDetectionResult supportedFormat(MediaContainerProbe probe, String settings, - AudioTrackInfo trackInfo) { - - return new MediaContainerDetectionResult(trackInfo, probe, settings, null, null); - } - - /** - * @return If the container this file uses was detected. In case this returns true, the container probe is non-null. - */ - public boolean isContainerDetected() { - return containerProbe != null; - } - - /** - * @return The probe for the container of the file - */ - public MediaContainerDescriptor getContainerDescriptor() { - return new MediaContainerDescriptor(containerProbe, probeSettings); - } - - /** - * @return Whether this specific file is supported. If this returns true, the track info is non-null. Otherwise - * the reason why this file is not supported can be retrieved via getUnsupportedReason(). - */ - public boolean isSupportedFile() { - return isContainerDetected() && unsupportedReason == null; - } - - /** - * @return The reason why this track is not supported. - */ - public String getUnsupportedReason() { - return unsupportedReason; - } - - /** - * @return Track info for the detected file. - */ - public AudioTrackInfo getTrackInfo() { - return trackInfo; - } - - public boolean isReference() { - return reference != null; - } - - public AudioReference getReference() { - return reference; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerHints.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerHints.java deleted file mode 100644 index 67b22d2..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerHints.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container; - -/** - * Optional meta-information about a stream which may narrow down the list of possible containers. - */ -public class MediaContainerHints { - private static final MediaContainerHints NO_INFORMATION = new MediaContainerHints(null, null); - - /** - * Mime type, null if not known. - */ - public final String mimeType; - /** - * File extension, null if not known. - */ - public final String fileExtension; - - private MediaContainerHints(String mimeType, String fileExtension) { - this.mimeType = mimeType; - this.fileExtension = fileExtension; - } - - /** - * @return true if any hint parameters have a value. - */ - public boolean present() { - return mimeType != null || fileExtension != null; - } - - /** - * @param mimeType Mime type - * @param fileExtension File extension - * @return Instance of hints object with the specified parameters - */ - public static MediaContainerHints from(String mimeType, String fileExtension) { - if (mimeType == null && fileExtension == null) { - return NO_INFORMATION; - } else { - return new MediaContainerHints(mimeType, fileExtension); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerProbe.java deleted file mode 100644 index 71fb095..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerProbe.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; - -import java.io.IOException; - -/** - * Track information probe for one media container type and factory for tracks for that container. - */ -public interface MediaContainerProbe { - /** - * @return The name of this container - */ - String getName(); - - /** - * @param hints The available hints about the possible container. - * @return True if the hints match the format this probe detects. Should always return false if all hints are null. - */ - boolean matchesHints(MediaContainerHints hints); - - /** - * Detect whether the file readable from the input stream is using this container and if this specific file uses - * a format and codec that is supported for playback. - * - * @param reference Reference with an identifier to use in the returned audio track info - * @param inputStream Input stream that contains the track file - * @return Returns result with audio track on supported format, result with unsupported reason set if this is the - * container that the file uses, but this specific file uses a format or codec that is not supported. Returns - * null in case this file does not appear to be using this container format. - * @throws IOException On read error. - */ - MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException; - - /** - * Creates a new track for this container. The audio tracks created here are never used directly, but the playback is - * delegated to them. As such, they do not have to support cloning or have a source manager. - * - * @param parameters Parameters specific to the probe. - * @param trackInfo Track meta information - * @param inputStream Input stream of the track file - * @return A new audio track - */ - AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerRegistry.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerRegistry.java deleted file mode 100644 index c579030..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/MediaContainerRegistry.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container; - -import java.util.List; - -public class MediaContainerRegistry { - public static final MediaContainerRegistry DEFAULT_REGISTRY = new MediaContainerRegistry(MediaContainer.asList()); - - private final List probes; - - public MediaContainerRegistry(List probes) { - this.probes = probes; - } - - public MediaContainerProbe find(String name) { - for (MediaContainerProbe probe : probes) { - if (name.equals(probe.getName())) { - return probe; - } - } - - return null; - } - - public List getAll() { - return probes; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsAudioTrack.java deleted file mode 100644 index 5c81fa5..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsAudioTrack.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.adts; - -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.BaseAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.InputStream; - -/** - * Audio track that handles an ADTS packet stream - */ -public class AdtsAudioTrack extends BaseAudioTrack { - private static final Logger log = LoggerFactory.getLogger(AdtsAudioTrack.class); - - private final InputStream inputStream; - - /** - * @param trackInfo Track info - * @param inputStream Input stream for the ADTS stream - */ - public AdtsAudioTrack(AudioTrackInfo trackInfo, InputStream inputStream) { - super(trackInfo); - - this.inputStream = inputStream; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - AdtsStreamProvider provider = new AdtsStreamProvider(inputStream, localExecutor.getProcessingContext()); - - try { - log.debug("Starting to play ADTS stream {}", getIdentifier()); - - localExecutor.executeProcessingLoop(provider::provideFrames, null); - } finally { - provider.close(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsContainerProbe.java deleted file mode 100644 index df1c1b7..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsContainerProbe.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.adts; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.supportedFormat; - -/** - * Container detection probe for ADTS stream format. - */ -public class AdtsContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(AdtsContainerProbe.class); - - @Override - public String getName() { - return "adts"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - boolean invalidFileExtension = hints.fileExtension != null && !"aac".equalsIgnoreCase(hints.fileExtension); - return hints.present() && !invalidFileExtension; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException { - AdtsStreamReader reader = new AdtsStreamReader(inputStream); - - if (reader.findPacketHeader(MediaContainerDetection.STREAM_SCAN_DISTANCE) == null) { - return null; - } - - log.debug("Track {} is an ADTS stream.", reference.identifier); - - return supportedFormat(this, null, AudioTrackInfoBuilder.create(reference, inputStream).build()); - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - return new AdtsAudioTrack(trackInfo, inputStream); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsPacketHeader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsPacketHeader.java deleted file mode 100644 index 7e3fdf4..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsPacketHeader.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.adts; - -/** - * ADTS packet header. - */ -public class AdtsPacketHeader { - /** - * If this is false, then the packet header is followed by a 2-byte CRC. - */ - public final boolean isProtectionAbsent; - /** - * Decoder profile (2 is AAC-LC). - */ - public final int profile; - /** - * Sample rate. - */ - public final int sampleRate; - /** - * Number of channels. - */ - public final int channels; - /** - * Packet payload length, excluding the CRC after this header. - */ - public final int payloadLength; - - /** - * @param isProtectionAbsent If this is false, then the packet header is followed by a 2-byte CRC. - * @param profile Decoder profile (2 is AAC-LC). - * @param sampleRate Sample rate. - * @param channels Number of channels. - * @param payloadLength Packet payload length, excluding the CRC after this header. - */ - public AdtsPacketHeader(boolean isProtectionAbsent, int profile, int sampleRate, int channels, int payloadLength) { - this.isProtectionAbsent = isProtectionAbsent; - this.profile = profile; - this.sampleRate = sampleRate; - this.channels = channels; - this.payloadLength = payloadLength; - } - - /** - * @param packetHeader The packet to check against. - * @return True if the decoder does not have to be reconfigured between these two packets. - */ - public boolean canUseSameDecoder(AdtsPacketHeader packetHeader) { - return packetHeader != null && - profile == packetHeader.profile && - sampleRate == packetHeader.sampleRate && - channels == packetHeader.channels; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsStreamProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsStreamProvider.java deleted file mode 100644 index e2f50bd..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsStreamProvider.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.adts; - -import com.sedmelluq.discord.lavaplayer.filter.AudioPipeline; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipelineFactory; -import com.sedmelluq.discord.lavaplayer.filter.PcmFormat; -import com.sedmelluq.discord.lavaplayer.natives.aac.AacDecoder; -import com.sedmelluq.discord.lavaplayer.tools.io.DirectBufferStreamBroker; -import com.sedmelluq.discord.lavaplayer.tools.io.ResettableBoundedInputStream; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; - -/** - * Provides the frames of an ADTS stream track to the frame consumer. - */ -public class AdtsStreamProvider { - private final AudioProcessingContext context; - private final AdtsStreamReader streamReader; - private final AacDecoder decoder; - private final ResettableBoundedInputStream packetBoundedStream; - private final DirectBufferStreamBroker directBufferBroker; - private ShortBuffer outputBuffer; - private AdtsPacketHeader previousHeader; - private AudioPipeline downstream; - private Long requestedTimecode; - private Long providedTimecode; - - /** - * @param inputStream Input stream to read from. - * @param context Configuration and output information for processing - */ - public AdtsStreamProvider(InputStream inputStream, AudioProcessingContext context) { - this.context = context; - this.streamReader = new AdtsStreamReader(inputStream); - this.decoder = new AacDecoder(); - this.packetBoundedStream = new ResettableBoundedInputStream(inputStream); - this.directBufferBroker = new DirectBufferStreamBroker(2048); - } - - /** - * Used to pass the initial position of the stream in case it is part of a chain, to keep timecodes of audio frames - * continuous. - * - * @param requestedTimecode The timecode at which the samples from this stream should be outputted. - * @param providedTimecode The timecode at which this stream starts. - */ - public void setInitialSeek(long requestedTimecode, long providedTimecode) { - this.requestedTimecode = requestedTimecode; - this.providedTimecode = providedTimecode; - } - - /** - * Provides frames to the frame consumer. - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - public void provideFrames() throws InterruptedException { - try { - while (true) { - AdtsPacketHeader header = streamReader.findPacketHeader(); - if (header == null) { - // Reached EOF while scanning for header - return; - } - - configureProcessing(header); - - packetBoundedStream.resetLimit(header.payloadLength); - directBufferBroker.consumeNext(packetBoundedStream, Integer.MAX_VALUE, Integer.MAX_VALUE); - - ByteBuffer buffer = directBufferBroker.getBuffer(); - - if (buffer.limit() < header.payloadLength) { - // Reached EOF in the middle of a packet - return; - } - - decodeAndSend(buffer); - streamReader.nextPacket(); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void decodeAndSend(ByteBuffer inputBuffer) throws InterruptedException { - decoder.fill(inputBuffer); - - if (downstream == null) { - AacDecoder.StreamInfo streamInfo = decoder.resolveStreamInfo(); - if (streamInfo == null) { - return; - } - - downstream = AudioPipelineFactory.create(context, new PcmFormat(streamInfo.channels, streamInfo.sampleRate)); - outputBuffer = ByteBuffer.allocateDirect(2 * streamInfo.frameSize * streamInfo.channels) - .order(ByteOrder.nativeOrder()).asShortBuffer(); - - if (requestedTimecode != null) { - downstream.seekPerformed(requestedTimecode, providedTimecode); - requestedTimecode = null; - } - } - - outputBuffer.clear(); - - while (decoder.decode(outputBuffer, false)) { - downstream.process(outputBuffer); - outputBuffer.clear(); - } - } - - private void configureProcessing(AdtsPacketHeader header) { - if (!header.canUseSameDecoder(previousHeader)) { - decoder.configure(header.profile, header.sampleRate, header.channels); - - if (downstream != null) { - downstream.close(); - } - - downstream = null; - outputBuffer = null; - } - - previousHeader = header; - } - - /** - * Free all resources. - */ - public void close() { - try { - if (downstream != null) { - downstream.close(); - } - } finally { - decoder.close(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsStreamReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsStreamReader.java deleted file mode 100644 index dce1cee..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/adts/AdtsStreamReader.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.adts; - -import com.sedmelluq.discord.lavaplayer.tools.io.BitBufferReader; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; - -/** - * Finds and reads ADTS packet headers from an input stream. - */ -public class AdtsStreamReader { - private static final AdtsPacketHeader EOF_PACKET = new AdtsPacketHeader(false, 0, 0, 0, 0); - - private static final int HEADER_BASE_SIZE = 7; - private static final int INVALID_VALUE = -1; - - private static final int[] sampleRateMapping = new int[]{ - 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, - 16000, 12000, 11025, 8000, 7350, INVALID_VALUE, INVALID_VALUE, INVALID_VALUE - }; - - private final InputStream inputStream; - private final byte[] scanBuffer; - private final ByteBuffer scanByteBuffer; - private final BitBufferReader scanBufferReader; - private AdtsPacketHeader currentPacket; - - /** - * @param inputStream The input stream to use. - */ - public AdtsStreamReader(InputStream inputStream) { - this.inputStream = inputStream; - this.scanBuffer = new byte[32]; - this.scanByteBuffer = ByteBuffer.wrap(scanBuffer); - this.scanBufferReader = new BitBufferReader(scanByteBuffer); - } - - /** - * Scan the input stream for an ADTS packet header. Subsequent calls will return the same header until nextPacket() is - * called. - * - * @return The packet header if found before EOF. - * @throws IOException On read error. - */ - public AdtsPacketHeader findPacketHeader() throws IOException { - return findPacketHeader(Integer.MAX_VALUE); - } - - /** - * Scan the input stream for an ADTS packet header. Subsequent calls will return the same header until nextPacket() is - * called. - * - * @param maximumDistance Maximum number of bytes to scan. - * @return The packet header if found before EOF and maximum byte limit. - * @throws IOException On read error. - */ - public AdtsPacketHeader findPacketHeader(int maximumDistance) throws IOException { - if (currentPacket == null) { - currentPacket = scanForPacketHeader(maximumDistance); - } - - return currentPacket == EOF_PACKET ? null : currentPacket; - } - - /** - * Resets the current packet, makes next calls to findPacketHeader scan for the next occurrence in the stream. - */ - public void nextPacket() { - currentPacket = null; - } - - private AdtsPacketHeader scanForPacketHeader(int maximumDistance) throws IOException { - int bufferPosition = 0; - - for (int i = 0; i < maximumDistance; i++) { - int nextByte = inputStream.read(); - - if (nextByte == -1) { - return EOF_PACKET; - } - - scanBuffer[bufferPosition++] = (byte) nextByte; - - if (bufferPosition >= HEADER_BASE_SIZE) { - AdtsPacketHeader header = readHeaderFromBufferTail(bufferPosition); - - if (header != null) { - return header; - } - } - - if (bufferPosition == scanBuffer.length) { - copyEndToBeginning(scanBuffer, HEADER_BASE_SIZE); - bufferPosition = HEADER_BASE_SIZE; - } - } - - return null; - } - - private AdtsPacketHeader readHeaderFromBufferTail(int position) throws IOException { - scanByteBuffer.position(position - HEADER_BASE_SIZE); - - AdtsPacketHeader header = readHeader(scanBufferReader); - scanBufferReader.readRemainingBits(); - - if (header == null) { - return null; - } else if (!header.isProtectionAbsent) { - int crcFirst = inputStream.read(); - int crcSecond = inputStream.read(); - - if (crcFirst == -1 || crcSecond == -1) { - return EOF_PACKET; - } - } - - return header; - } - - private static void copyEndToBeginning(byte[] buffer, int chunk) { - for (int i = 0; i < chunk; i++) { - buffer[i] = buffer[buffer.length - chunk + i]; - } - } - - private static AdtsPacketHeader readHeader(BitBufferReader reader) { - if ((reader.asLong(15) & 0x7FFB) != 0x7FF8) { - // Possible reasons: - // 1) Syncword is not present, cannot be an ADTS header - // 2) Layer value is not 0, which must always be 0 for ADTS - return null; - } - - boolean isProtectionAbsent = reader.asLong(1) == 1; - int profile = reader.asInteger(2); - int sampleRate = sampleRateMapping[reader.asInteger(4)]; - - // Private bit - reader.asLong(1); - - int channels = reader.asInteger(3); - - if (sampleRate == INVALID_VALUE || channels == 0) { - return null; - } - - // 4 boring bits - reader.asLong(4); - - int frameLength = reader.asInteger(13); - int payloadLength = frameLength - 7 - (isProtectionAbsent ? 0 : 2); - - // More boring bits - reader.asLong(11); - - if (reader.asLong(2) != 0) { - // Not handling multiple frames per packet - return null; - } - - return new AdtsPacketHeader(isProtectionAbsent, profile + 1, sampleRate, channels, payloadLength); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/common/AacPacketRouter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/common/AacPacketRouter.java deleted file mode 100644 index 6b278c3..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/common/AacPacketRouter.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.common; - -import com.sedmelluq.discord.lavaplayer.filter.AudioPipeline; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipelineFactory; -import com.sedmelluq.discord.lavaplayer.filter.PcmFormat; -import com.sedmelluq.discord.lavaplayer.natives.aac.AacDecoder; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; -import java.util.function.Consumer; - -public class AacPacketRouter { - private final AudioProcessingContext context; - private final Consumer decoderConfigurer; - - private Long initialRequestedTimecode; - private Long initialProvidedTimecode; - private ShortBuffer outputBuffer; - private AudioPipeline downstream; - private AacDecoder decoder; - - public AacPacketRouter(AudioProcessingContext context, Consumer decoderConfigurer) { - this.context = context; - this.decoderConfigurer = decoderConfigurer; - } - - public void processInput(ByteBuffer inputBuffer) throws InterruptedException { - if (decoder == null) { - decoder = new AacDecoder(); - decoderConfigurer.accept(decoder); - } - - decoder.fill(inputBuffer); - - if (downstream == null) { - AacDecoder.StreamInfo streamInfo = decoder.resolveStreamInfo(); - - if (streamInfo != null) { - downstream = AudioPipelineFactory.create(context, new PcmFormat(streamInfo.channels, streamInfo.sampleRate)); - outputBuffer = ByteBuffer.allocateDirect(2 * streamInfo.frameSize * streamInfo.channels) - .order(ByteOrder.nativeOrder()).asShortBuffer(); - - if (initialRequestedTimecode != null) { - downstream.seekPerformed(initialRequestedTimecode, initialProvidedTimecode); - } - } - } - - if (downstream != null) { - while (decoder.decode(outputBuffer, false)) { - downstream.process(outputBuffer); - outputBuffer.clear(); - } - } - } - - public void seekPerformed(long requestedTimecode, long providedTimecode) { - if (downstream != null) { - downstream.seekPerformed(requestedTimecode, providedTimecode); - } else { - this.initialRequestedTimecode = requestedTimecode; - this.initialProvidedTimecode = providedTimecode; - } - - if (decoder != null) { - decoder.close(); - decoder = null; - } - } - - public void flush() throws InterruptedException { - if (downstream != null) { - while (decoder.decode(outputBuffer, true)) { - downstream.process(outputBuffer); - outputBuffer.clear(); - } - } - } - - public void close() { - try { - if (downstream != null) { - downstream.close(); - } - } finally { - if (decoder != null) { - decoder.close(); - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/common/OpusPacketRouter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/common/OpusPacketRouter.java deleted file mode 100644 index c2ad0fe..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/common/OpusPacketRouter.java +++ /dev/null @@ -1,205 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.common; - -import com.sedmelluq.discord.lavaplayer.filter.AudioPipeline; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipelineFactory; -import com.sedmelluq.discord.lavaplayer.filter.PcmFormat; -import com.sedmelluq.discord.lavaplayer.filter.volume.AudioFrameVolumeChanger; -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.format.OpusAudioDataFormat; -import com.sedmelluq.discord.lavaplayer.natives.opus.OpusDecoder; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; -import com.sedmelluq.discord.lavaplayer.track.playback.MutableAudioFrame; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; - -/** - * A router for opus packets to the output specified by an audio processing context. It automatically detects if the - * packets can go clean through to the output without any decoding and encoding steps on each packet and rebuilds the - * pipeline of the output if necessary. - */ -public class OpusPacketRouter { - private static final Logger log = LoggerFactory.getLogger(OpusPacketRouter.class); - - private final AudioProcessingContext context; - private final int inputFrequency; - private final int inputChannels; - private final byte[] headerBytes; - private final MutableAudioFrame offeredFrame; - - private long currentTimecode; - private OpusDecoder opusDecoder; - private AudioPipeline downstream; - private ByteBuffer directInput; - private ShortBuffer frameBuffer; - private AudioDataFormat inputFormat; - private int lastFrameSize; - - /** - * @param context Configuration and output information for processing - * @param inputFrequency Sample rate of the opus track - * @param inputChannels Number of channels in the opus track - */ - public OpusPacketRouter(AudioProcessingContext context, int inputFrequency, int inputChannels) { - this.context = context; - this.inputFrequency = inputFrequency; - this.inputChannels = inputChannels; - this.headerBytes = new byte[2]; - this.offeredFrame = new MutableAudioFrame(); - this.lastFrameSize = 0; - - offeredFrame.setVolume(100); - offeredFrame.setFormat(context.outputFormat); - } - - /** - * Notify downstream handlers about a seek. - * - * @param requestedTimecode Timecode in milliseconds to which the seek was requested to - * @param providedTimecode Timecode in milliseconds to which the seek was actually performed to - */ - public void seekPerformed(long requestedTimecode, long providedTimecode) { - currentTimecode = providedTimecode; - - if (downstream != null) { - downstream.seekPerformed(requestedTimecode, providedTimecode); - } - } - - /** - * Indicates that no more input is coming. Flush any buffers to output. - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - public void flush() throws InterruptedException { - if (downstream != null) { - downstream.flush(); - } - } - - /** - * Process one opus packet. - * - * @param buffer Byte buffer of the packet - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - public void process(ByteBuffer buffer) throws InterruptedException { - int frameSize = processFrameSize(buffer); - - if (frameSize != 0) { - checkDecoderNecessity(); - - if (opusDecoder != null) { - passDownstream(buffer, frameSize); - } else { - passThrough(buffer); - } - } - } - - /** - * Free all resources. - */ - public void close() { - if (opusDecoder != null) { - destroyDecoder(); - } - } - - private int processFrameSize(ByteBuffer buffer) { - int frameSize; - - if (buffer.isDirect()) { - buffer.mark(); - buffer.get(headerBytes); - buffer.reset(); - - frameSize = OpusDecoder.getPacketFrameSize(inputFrequency, headerBytes, 0, headerBytes.length); - } else { - frameSize = OpusDecoder.getPacketFrameSize(inputFrequency, buffer.array(), buffer.position(), buffer.remaining()); - } - - if (frameSize == 0) { - return 0; - } else if (frameSize != lastFrameSize) { - lastFrameSize = frameSize; - inputFormat = new OpusAudioDataFormat(inputChannels, inputFrequency, frameSize); - } - - currentTimecode += frameSize * 1000 / inputFrequency; - return frameSize; - } - - private void passDownstream(ByteBuffer buffer, int frameSize) throws InterruptedException { - ByteBuffer nativeBuffer; - - if (!buffer.isDirect()) { - if (directInput == null || directInput.capacity() < buffer.remaining()) { - directInput = ByteBuffer.allocateDirect(buffer.remaining() + 200); - } - - directInput.clear(); - directInput.put(buffer); - directInput.flip(); - - nativeBuffer = directInput; - } else { - nativeBuffer = buffer; - } - - if (frameBuffer == null || frameBuffer.capacity() < frameSize * inputChannels) { - frameBuffer = ByteBuffer.allocateDirect(frameSize * inputChannels * 2).order(ByteOrder.nativeOrder()).asShortBuffer(); - } - - frameBuffer.clear(); - frameBuffer.limit(frameSize); - - opusDecoder.decode(nativeBuffer, frameBuffer); - downstream.process(frameBuffer); - } - - private void passThrough(ByteBuffer buffer) throws InterruptedException { - offeredFrame.setTimecode(currentTimecode); - offeredFrame.setBuffer(buffer); - - context.frameBuffer.consume(offeredFrame); - } - - private void checkDecoderNecessity() { - if (AudioPipelineFactory.isProcessingRequired(context, inputFormat)) { - if (opusDecoder == null) { - log.debug("Enabling reencode mode on opus track."); - - initialiseDecoder(); - - AudioFrameVolumeChanger.apply(context); - } - } else { - if (opusDecoder != null) { - log.debug("Enabling passthrough mode on opus track."); - - destroyDecoder(); - - AudioFrameVolumeChanger.apply(context); - } - } - } - - private void initialiseDecoder() { - opusDecoder = new OpusDecoder(inputFrequency, inputChannels); - downstream = AudioPipelineFactory.create(context, new PcmFormat(inputChannels, inputFrequency)); - downstream.seekPerformed(currentTimecode, currentTimecode); - } - - private void destroyDecoder() { - opusDecoder.close(); - opusDecoder = null; - downstream.close(); - downstream = null; - directInput = null; - frameBuffer = null; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacAudioTrack.java deleted file mode 100644 index bc4f8b2..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacAudioTrack.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.BaseAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Audio track that handles a FLAC stream - */ -public class FlacAudioTrack extends BaseAudioTrack { - private static final Logger log = LoggerFactory.getLogger(FlacAudioTrack.class); - - private final SeekableInputStream inputStream; - - /** - * @param trackInfo Track info - * @param inputStream Input stream for the FLAC file - */ - public FlacAudioTrack(AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - super(trackInfo); - - this.inputStream = inputStream; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - FlacFileLoader file = new FlacFileLoader(inputStream); - FlacTrackProvider trackProvider = file.loadTrack(localExecutor.getProcessingContext()); - - try { - log.debug("Starting to play FLAC track {}", getIdentifier()); - localExecutor.executeProcessingLoop(trackProvider::provideFrames, trackProvider::seekToTimecode); - } finally { - trackProvider.close(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacContainerProbe.java deleted file mode 100644 index 1c30ed7..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacContainerProbe.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.checkNextBytes; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.supportedFormat; - -/** - * Container detection probe for MP3 format. - */ -public class FlacContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(FlacContainerProbe.class); - - private static final String TITLE_TAG = "TITLE"; - private static final String ARTIST_TAG = "ARTIST"; - - @Override - public String getName() { - return "flac"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - return false; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException { - if (!checkNextBytes(inputStream, FlacFileLoader.FLAC_CC)) { - return null; - } - - log.debug("Track {} is a FLAC file.", reference.identifier); - - FlacTrackInfo fileInfo = new FlacFileLoader(inputStream).parseHeaders(); - - AudioTrackInfo trackInfo = AudioTrackInfoBuilder.create(reference, inputStream) - .setTitle(fileInfo.tags.get(TITLE_TAG)) - .setAuthor(fileInfo.tags.get(ARTIST_TAG)) - .setLength(fileInfo.duration) - .build(); - - return supportedFormat(this, null, trackInfo); - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - return new FlacAudioTrack(trackInfo, inputStream); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacFileLoader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacFileLoader.java deleted file mode 100644 index b272495..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacFileLoader.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.checkNextBytes; - -/** - * Loads either FLAC header information or a FLAC track object from a stream. - */ -public class FlacFileLoader { - static final int[] FLAC_CC = new int[]{0x66, 0x4C, 0x61, 0x43}; - - private final SeekableInputStream inputStream; - private final DataInput dataInput; - - /** - * @param inputStream Input stream to read the FLAC data from. This must be positioned right before FLAC FourCC. - */ - public FlacFileLoader(SeekableInputStream inputStream) { - this.inputStream = inputStream; - this.dataInput = new DataInputStream(inputStream); - } - - /** - * Read all metadata from a FLAC file. Stream position is at the beginning of the first frame after this call. - * - * @return FLAC track information - * @throws IOException On IO Error - */ - public FlacTrackInfo parseHeaders() throws IOException { - if (!checkNextBytes(inputStream, FLAC_CC, false)) { - throw new IllegalStateException("Not a FLAC file"); - } - - FlacTrackInfoBuilder trackInfoBuilder = new FlacTrackInfoBuilder(FlacMetadataReader.readStreamInfoBlock(dataInput)); - readMetadataBlocks(trackInfoBuilder); - trackInfoBuilder.setFirstFramePosition(inputStream.getPosition()); - return trackInfoBuilder.build(); - } - - /** - * Initialise a FLAC track stream. - * - * @param context Configuration and output information for processing - * @return The FLAC track stream which can produce frames. - * @throws IOException On IO error - */ - public FlacTrackProvider loadTrack(AudioProcessingContext context) throws IOException { - return new FlacTrackProvider(context, parseHeaders(), inputStream); - } - - private void readMetadataBlocks(FlacTrackInfoBuilder trackInfoBuilder) throws IOException { - boolean hasMoreBlocks = trackInfoBuilder.getStreamInfo().hasMetadataBlocks; - - while (hasMoreBlocks) { - hasMoreBlocks = FlacMetadataReader.readMetadataBlock(dataInput, inputStream, trackInfoBuilder); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacMetadataHeader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacMetadataHeader.java deleted file mode 100644 index 812190c..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacMetadataHeader.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac; - -import com.sedmelluq.discord.lavaplayer.tools.io.BitBufferReader; - -import java.nio.ByteBuffer; - -/** - * A header of FLAC metadata. - */ -public class FlacMetadataHeader { - public static final int LENGTH = 4; - - public static final int BLOCK_SEEKTABLE = 3; - public static final int BLOCK_COMMENT = 4; - - /** - * If this header is for the last metadata block. If this is true, then the current metadata block is followed by - * frames. - */ - public final boolean isLastBlock; - - /** - * Block type, see: https://xiph.org/flac/format.html#metadata_block_header - */ - public final int blockType; - - /** - * Length of the block, current header excluded - */ - public final int blockLength; - - /** - * @param data The raw header data - */ - public FlacMetadataHeader(byte[] data) { - BitBufferReader bitReader = new BitBufferReader(ByteBuffer.wrap(data)); - isLastBlock = bitReader.asInteger(1) == 1; - blockType = bitReader.asInteger(7); - blockLength = bitReader.asInteger(24); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacMetadataReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacMetadataReader.java deleted file mode 100644 index 9579f17..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacMetadataReader.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac; - -import org.apache.commons.io.IOUtils; - -import java.io.DataInput; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - -import static com.sedmelluq.discord.lavaplayer.container.flac.FlacMetadataHeader.BLOCK_COMMENT; -import static com.sedmelluq.discord.lavaplayer.container.flac.FlacMetadataHeader.BLOCK_SEEKTABLE; - -/** - * Handles reading one FLAC metadata blocks. - */ -public class FlacMetadataReader { - private static final Charset CHARSET = StandardCharsets.UTF_8; - - /** - * Reads FLAC stream info metadata block. - * - * @param dataInput Data input where the block is read from - * @return Stream information - * @throws IOException On read error - */ - public static FlacStreamInfo readStreamInfoBlock(DataInput dataInput) throws IOException { - FlacMetadataHeader header = readMetadataHeader(dataInput); - - if (header.blockType != 0) { - throw new IllegalStateException("Wrong metadata block, should be stream info."); - } else if (header.blockLength != FlacStreamInfo.LENGTH) { - throw new IllegalStateException("Invalid stream info block size."); - } - - byte[] streamInfoData = new byte[FlacStreamInfo.LENGTH]; - dataInput.readFully(streamInfoData); - return new FlacStreamInfo(streamInfoData, !header.isLastBlock); - } - - private static FlacMetadataHeader readMetadataHeader(DataInput dataInput) throws IOException { - byte[] headerBytes = new byte[FlacMetadataHeader.LENGTH]; - dataInput.readFully(headerBytes); - return new FlacMetadataHeader(headerBytes); - } - - /** - * @param dataInput Data input where the block is read from - * @param inputStream Input stream matching the data input - * @param trackInfoBuilder Track info builder object where detected metadata is stored in - * @return True if there are more metadata blocks available - * @throws IOException On read error - */ - public static boolean readMetadataBlock(DataInput dataInput, InputStream inputStream, FlacTrackInfoBuilder trackInfoBuilder) throws IOException { - FlacMetadataHeader header = readMetadataHeader(dataInput); - - if (header.blockType == BLOCK_SEEKTABLE) { - readSeekTableBlock(dataInput, trackInfoBuilder, header.blockLength); - } else if (header.blockType == BLOCK_COMMENT) { - readCommentBlock(dataInput, inputStream, trackInfoBuilder); - } else { - IOUtils.skipFully(inputStream, header.blockLength); - } - - return !header.isLastBlock; - } - - private static void readCommentBlock(DataInput dataInput, InputStream inputStream, FlacTrackInfoBuilder trackInfoBuilder) throws IOException { - int vendorLength = Integer.reverseBytes(dataInput.readInt()); - IOUtils.skipFully(inputStream, vendorLength); - - int listLength = Integer.reverseBytes(dataInput.readInt()); - - for (int i = 0; i < listLength; i++) { - int itemLength = Integer.reverseBytes(dataInput.readInt()); - - byte[] textBytes = new byte[itemLength]; - dataInput.readFully(textBytes); - - String text = new String(textBytes, 0, textBytes.length, CHARSET); - String[] keyAndValue = text.split("=", 2); - - if (keyAndValue.length > 1) { - trackInfoBuilder.addTag(keyAndValue[0].toUpperCase(), keyAndValue[1]); - } - } - } - - private static void readSeekTableBlock(DataInput dataInput, FlacTrackInfoBuilder trackInfoBuilder, int length) throws IOException { - FlacSeekPoint[] seekPoints = new FlacSeekPoint[length / FlacSeekPoint.LENGTH]; - int seekPointCount = 0; - - for (int i = 0; i < seekPoints.length; i++) { - long sampleIndex = dataInput.readLong(); - long byteOffset = dataInput.readLong(); - int sampleCount = dataInput.readUnsignedShort(); - - seekPoints[i] = new FlacSeekPoint(sampleIndex, byteOffset, sampleCount); - - if (sampleIndex != -1) { - seekPointCount = i + 1; - } - } - - trackInfoBuilder.setSeekPoints(seekPoints, seekPointCount); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacSeekPoint.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacSeekPoint.java deleted file mode 100644 index d94940a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacSeekPoint.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac; - -/** - * FLAC seek point info. Field descriptions are from: - * https://xiph.org/flac/format.html#seekpoint - *

- * - For placeholder points, the second and third field values are undefined. - * - Seek points within a table must be sorted in ascending order by sample number. - * - Seek points within a table must be unique by sample number, with the exception of placeholder points. - * - The previous two notes imply that there may be any number of placeholder points, but they must all occur at the end - * of the table. - */ -public class FlacSeekPoint { - public static final int LENGTH = 18; - - /** - * Sample number of first sample in the target frame, or 0xFFFFFFFFFFFFFFFF for a placeholder point. - */ - public final long sampleIndex; - - /** - * Offset (in bytes) from the first byte of the first frame header to the first byte of the target frame's header. - */ - public final long byteOffset; - - /** - * Number of samples in the target frame. - */ - public final int sampleCount; - - /** - * @param sampleIndex Index of the first sample in the frame - * @param byteOffset Offset in bytes from first frame start to target frame start - * @param sampleCount Number of samples in the frame - */ - public FlacSeekPoint(long sampleIndex, long byteOffset, int sampleCount) { - this.sampleIndex = sampleIndex; - this.byteOffset = byteOffset; - this.sampleCount = sampleCount; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacStreamInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacStreamInfo.java deleted file mode 100644 index 9c1bc77..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacStreamInfo.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac; - -import com.sedmelluq.discord.lavaplayer.tools.io.BitBufferReader; - -import java.nio.ByteBuffer; - -/** - * FLAC stream info metadata block contents. Field descriptions are from: - * https://xiph.org/flac/format.html#metadata_block_streaminfo - *

- * FLAC specifies a minimum block size of 16 and a maximum block size of 65535, meaning the bit patterns corresponding - * to the numbers 0-15 in the minimum blocksize and maximum blocksize fields are invalid. - */ -public class FlacStreamInfo { - public static final int LENGTH = 34; - - /** - * The minimum block size (in samples) used in the stream. - */ - public final int minimumBlockSize; - /** - * The maximum block size (in samples) used in the stream. (Minimum blocksize == maximum blocksize) implies a - * fixed-blocksize stream. - */ - public final int maximumBlockSize; - /** - * The minimum frame size (in bytes) used in the stream. May be 0 to imply the value is not known. - */ - public final int minimumFrameSize; - /** - * The maximum frame size (in bytes) used in the stream. May be 0 to imply the value is not known. - */ - public final int maximumFrameSize; - /** - * Sample rate in Hz. Though 20 bits are available, the maximum sample rate is limited by the structure of frame - * headers to 655350Hz. Also, a value of 0 is invalid. - */ - public final int sampleRate; - /** - * FLAC supports from 1 to 8 channels - */ - public final int channelCount; - /** - * FLAC supports from 4 to 32 bits per sample. Currently the reference encoder and decoders only support up to 24 bits - * per sample. - */ - public final int bitsPerSample; - /** - * Total samples in stream. 'Samples' means inter-channel sample, i.e. one second of 44.1Khz audio will have 44100 - * samples regardless of the number of channels. A value of zero here means the number of total samples is unknown. - */ - public final long sampleCount; - /** - * MD5 signature of the unencoded audio data. This allows the decoder to determine if an error exists in the audio - * data even when the error does not result in an invalid bitstream. - */ - public final byte[] md5Signature; - /** - * Whether the file has any metadata blocks after the stream info. - */ - public final boolean hasMetadataBlocks; - - /** - * @param blockData The raw block data. - * @param hasMetadataBlocks Whether the file has any metadata blocks after the stream info. - */ - public FlacStreamInfo(byte[] blockData, boolean hasMetadataBlocks) { - BitBufferReader bitReader = new BitBufferReader(ByteBuffer.wrap(blockData)); - minimumBlockSize = bitReader.asInteger(16); - maximumBlockSize = bitReader.asInteger(16); - minimumFrameSize = bitReader.asInteger(24); - maximumFrameSize = bitReader.asInteger(24); - sampleRate = bitReader.asInteger(20); - channelCount = bitReader.asInteger(3) + 1; - bitsPerSample = bitReader.asInteger(5) + 1; - sampleCount = bitReader.asLong(36); - - md5Signature = new byte[16]; - System.arraycopy(blockData, 18, md5Signature, 0, 16); - - this.hasMetadataBlocks = hasMetadataBlocks; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackInfo.java deleted file mode 100644 index 734a612..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackInfo.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac; - -import java.util.Map; - -/** - * All relevant information about a FLAC track from its metadata. - */ -public class FlacTrackInfo { - /** - * FLAC stream information. - */ - public final FlacStreamInfo stream; - /** - * An array of seek points. - */ - public final FlacSeekPoint[] seekPoints; - /** - * The actual number of seek points that are not placeholders. The end of the array may contain empty seek points, - * which is why this value should be used to determine how far into the array to look. - */ - public final int seekPointCount; - /** - * The map of tag values from comment metadata block. - */ - public final Map tags; - /** - * The position in the stream where the first frame starts. - */ - public final long firstFramePosition; - /** - * The duration of the track in milliseconds - */ - public final long duration; - - /** - * @param stream FLAC stream information. - * @param seekPoints An array of seek points. - * @param seekPointCount The actual number of seek points that are not placeholders. - * @param tags The map of tag values from comment metadata block. - * @param firstFramePosition The position in the stream where the first frame starts. - */ - public FlacTrackInfo(FlacStreamInfo stream, FlacSeekPoint[] seekPoints, int seekPointCount, Map tags, - long firstFramePosition) { - - this.stream = stream; - this.seekPoints = seekPoints; - this.seekPointCount = seekPointCount; - this.tags = tags; - this.firstFramePosition = firstFramePosition; - this.duration = stream.sampleCount * 1000L / stream.sampleRate; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackInfoBuilder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackInfoBuilder.java deleted file mode 100644 index faee6be..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackInfoBuilder.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac; - -import java.util.HashMap; -import java.util.Map; - -/** - * Builder for FLAC track info. - */ -public class FlacTrackInfoBuilder { - private final FlacStreamInfo streamInfo; - private final Map tags; - private FlacSeekPoint[] seekPoints; - private int seekPointCount; - private long firstFramePosition; - - /** - * @param streamInfo Stream info metadata block. - */ - public FlacTrackInfoBuilder(FlacStreamInfo streamInfo) { - this.streamInfo = streamInfo; - this.tags = new HashMap<>(); - } - - /** - * @return Stream info metadata block. - */ - public FlacStreamInfo getStreamInfo() { - return streamInfo; - } - - /** - * @param seekPoints Seek point array. - * @param seekPointCount The number of seek points which are not placeholders. - */ - public void setSeekPoints(FlacSeekPoint[] seekPoints, int seekPointCount) { - this.seekPoints = seekPoints; - this.seekPointCount = seekPointCount; - } - - /** - * @param key Name of the tag - * @param value Value of the tag - */ - public void addTag(String key, String value) { - tags.put(key, value); - } - - /** - * @param firstFramePosition File position of the first frame - */ - public void setFirstFramePosition(long firstFramePosition) { - this.firstFramePosition = firstFramePosition; - } - - /** - * @return Track info object. - */ - public FlacTrackInfo build() { - return new FlacTrackInfo(streamInfo, seekPoints, seekPointCount, tags, firstFramePosition); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackProvider.java deleted file mode 100644 index 3bfadca..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/FlacTrackProvider.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac; - -import com.sedmelluq.discord.lavaplayer.container.flac.frame.FlacFrameReader; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipeline; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipelineFactory; -import com.sedmelluq.discord.lavaplayer.filter.PcmFormat; -import com.sedmelluq.discord.lavaplayer.tools.io.BitStreamReader; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.io.IOException; - -/** - * A provider of audio frames from a FLAC track. - */ -public class FlacTrackProvider { - private final FlacTrackInfo info; - private final SeekableInputStream inputStream; - private final AudioPipeline downstream; - private final BitStreamReader bitStreamReader; - private final int[] decodingBuffer; - private final int[][] rawSampleBuffers; - private final short[][] sampleBuffers; - - /** - * @param context Configuration and output information for processing - * @param info Track information from FLAC metadata - * @param inputStream Input stream to use - */ - public FlacTrackProvider(AudioProcessingContext context, FlacTrackInfo info, SeekableInputStream inputStream) { - this.info = info; - this.inputStream = inputStream; - this.downstream = AudioPipelineFactory.create(context, - new PcmFormat(info.stream.channelCount, info.stream.sampleRate)); - this.bitStreamReader = new BitStreamReader(inputStream); - this.decodingBuffer = new int[FlacFrameReader.TEMPORARY_BUFFER_SIZE]; - this.rawSampleBuffers = new int[info.stream.channelCount][]; - this.sampleBuffers = new short[info.stream.channelCount][]; - - for (int i = 0; i < rawSampleBuffers.length; i++) { - rawSampleBuffers[i] = new int[info.stream.maximumBlockSize]; - sampleBuffers[i] = new short[info.stream.maximumBlockSize]; - } - } - - /** - * Decodes audio frames and sends them to frame consumer - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - public void provideFrames() throws InterruptedException { - try { - int sampleCount; - - while ((sampleCount = readFlacFrame()) != 0) { - downstream.process(sampleBuffers, 0, sampleCount); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private int readFlacFrame() throws IOException { - return FlacFrameReader.readFlacFrame(inputStream, bitStreamReader, info.stream, rawSampleBuffers, sampleBuffers, decodingBuffer); - } - - /** - * Seeks to the specified timecode. - * - * @param timecode The timecode in milliseconds - */ - public void seekToTimecode(long timecode) { - try { - FlacSeekPoint seekPoint = findSeekPointForTime(timecode); - inputStream.seek(info.firstFramePosition + seekPoint.byteOffset); - downstream.seekPerformed(timecode, seekPoint.sampleIndex * 1000 / info.stream.sampleRate); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private FlacSeekPoint findSeekPointForTime(long timecode) { - if (info.seekPointCount == 0) { - return new FlacSeekPoint(0, 0, 0); - } - - long targetSampleIndex = timecode * info.stream.sampleRate / 1000L; - return binarySearchSeekPoints(info.seekPoints, info.seekPointCount, targetSampleIndex); - } - - private FlacSeekPoint binarySearchSeekPoints(FlacSeekPoint[] seekPoints, int length, long targetSampleIndex) { - int low = 0; - int high = length - 1; - - while (high > low) { - int mid = (low + high + 1) / 2; - - if (info.seekPoints[mid].sampleIndex > targetSampleIndex) { - high = mid - 1; - } else { - low = mid; - } - } - - return seekPoints[low]; - } - - /** - * Free all resources associated to processing the track. - */ - public void close() { - downstream.close(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameHeaderReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameHeaderReader.java deleted file mode 100644 index fb0cf22..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameHeaderReader.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac.frame; - -import com.sedmelluq.discord.lavaplayer.container.flac.FlacStreamInfo; -import com.sedmelluq.discord.lavaplayer.container.flac.frame.FlacFrameInfo.ChannelDelta; -import com.sedmelluq.discord.lavaplayer.tools.io.BitStreamReader; - -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.container.flac.frame.FlacFrameInfo.ChannelDelta.*; - -/** - * Contains methods for reading a frame header. - */ -public class FlacFrameHeaderReader { - private static final int VALUE_INVALID = Integer.MIN_VALUE; - private static final int VALUE_INHERITED = -1024; - - private static final int BLOCK_SIZE_EXPLICIT_8_BIT = -2; - private static final int BLOCK_SIZE_EXPLICIT_16_BIT = -1; - - private static final int SAMPLE_RATE_EXPLICIT_8_BIT = -3; - private static final int SAMPLE_RATE_EXPLICIT_16_BIT = -2; - private static final int SAMPLE_RATE_EXPLICIT_10X_16_BIT = -1; - - private static final int[] blockSizeMapping = new int[]{ - VALUE_INVALID, 192, 576, 1152, 2304, 4608, BLOCK_SIZE_EXPLICIT_8_BIT, BLOCK_SIZE_EXPLICIT_16_BIT, - 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 - }; - - private static final int[] sampleRateMapping = new int[]{ - VALUE_INHERITED, 88200, 176400, 192000, 8000, 16000, 22050, 24000, - 32000, 44100, 48000, 96000, SAMPLE_RATE_EXPLICIT_8_BIT, SAMPLE_RATE_EXPLICIT_16_BIT, SAMPLE_RATE_EXPLICIT_10X_16_BIT, VALUE_INVALID - }; - - private static final int[] channelCountMapping = new int[]{ - 1, 2, 3, 4, 5, 6, 7, 8, - 2, 2, 2, VALUE_INVALID, VALUE_INVALID, VALUE_INVALID, VALUE_INVALID, VALUE_INVALID - }; - - private static final ChannelDelta[] channelDeltaMapping = new ChannelDelta[]{ - NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, - LEFT_SIDE, RIGHT_SIDE, MID_SIDE, NONE, NONE, NONE, NONE, NONE - }; - - private static final int[] sampleSizeMapping = new int[]{VALUE_INHERITED, 8, 12, VALUE_INVALID, 16, 20, 24, VALUE_INVALID}; - - /** - * Reads a frame header. At this point the first two bytes of the frame have actually been read during the frame sync - * scanning already. This means that this method expects there to be no EOF in the middle of the header. The frame - * information must match that of the stream, as changing sample rates, channel counts and sample sizes are not - * supported. - * - * @param bitStreamReader Bit stream reader for input - * @param streamInfo Information about the stream from metadata headers - * @param variableBlock If this is a variable block header. This information was included in the frame sync bytes - * consumed before calling this method. - * @return The frame information. - * @throws IOException On read error. - */ - public static FlacFrameInfo readFrameHeader(BitStreamReader bitStreamReader, FlacStreamInfo streamInfo, - boolean variableBlock) throws IOException { - - int blockSize = blockSizeMapping[bitStreamReader.asInteger(4)]; - int sampleRate = sampleRateMapping[bitStreamReader.asInteger(4)]; - int channelAssignment = bitStreamReader.asInteger(4); - int channelCount = channelCountMapping[channelAssignment]; - ChannelDelta channelDelta = channelDeltaMapping[channelAssignment]; - int sampleSize = sampleSizeMapping[bitStreamReader.asInteger(3)]; - - bitStreamReader.asInteger(1); - - readUtf8Value(variableBlock, bitStreamReader); - - if (blockSize == BLOCK_SIZE_EXPLICIT_8_BIT) { - blockSize = bitStreamReader.asInteger(8) + 1; - } else if (blockSize == BLOCK_SIZE_EXPLICIT_16_BIT) { - blockSize = bitStreamReader.asInteger(16) + 1; - } - - verifyNotInvalid(blockSize, "block size"); - - if (blockSize == SAMPLE_RATE_EXPLICIT_8_BIT) { - sampleRate = bitStreamReader.asInteger(8); - } else if (blockSize == SAMPLE_RATE_EXPLICIT_16_BIT) { - sampleRate = bitStreamReader.asInteger(16); - } else if (blockSize == SAMPLE_RATE_EXPLICIT_10X_16_BIT) { - sampleRate = bitStreamReader.asInteger(16) * 10; - } - - verifyMatchesExpected(sampleRate, streamInfo.sampleRate, "sample rate"); - verifyMatchesExpected(channelCount, streamInfo.channelCount, "channel count"); - verifyMatchesExpected(sampleSize, streamInfo.bitsPerSample, "bits per sample"); - - // Ignore CRC for now - bitStreamReader.asInteger(8); - - return new FlacFrameInfo(blockSize, channelDelta); - } - - private static void verifyNotInvalid(int value, String description) { - if (value < 0) { - throw new IllegalStateException("Invalid value " + value + " for " + description); - } - } - - private static void verifyMatchesExpected(int value, int expected, String description) { - if (value != VALUE_INHERITED && value != expected) { - throw new IllegalStateException("Invalid value " + value + " for " + description + ", should match value " + expected + " in stream."); - } - } - - private static long readUtf8Value(boolean isLong, BitStreamReader bitStreamReader) throws IOException { - int maximumSize = isLong ? 7 : 6; - int firstByte = bitStreamReader.asInteger(8); - int leadingOnes = Integer.numberOfLeadingZeros((~firstByte) & 0xFF) - 24; - - if (leadingOnes > maximumSize || leadingOnes == 1) { - throw new IllegalStateException("Invalid number of leading ones in UTF encoded integer"); - } else if (leadingOnes == 0) { - return firstByte; - } - - long value = firstByte - (1L << (7 - leadingOnes)) - 1L; - - for (int i = 0; i < leadingOnes - 1; i++) { - int currentByte = bitStreamReader.asInteger(8); - if ((currentByte & 0xC0) != 0x80) { - throw new IllegalStateException("Invalid content of payload byte, first bits must be 1 and 0."); - } - - value = (value << 6) | (currentByte & 0x3F); - } - - return value; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameInfo.java deleted file mode 100644 index 357ab31..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameInfo.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac.frame; - -/** - * Information of a FLAC frame that is required for reading its subframes. Most of the fields in the frame info are not - * actually needed, since it is an error if they differ from the ones specified in the file metadata. - */ -public class FlacFrameInfo { - /** - * Number of samples in each subframe of this frame. - */ - public final int sampleCount; - - /** - * The way stereo channel data is related. With stereo frames, one channel can contain its original data and the other - * just the difference from the first one, which allows for better compression for the other channel. - */ - public final ChannelDelta channelDelta; - - /** - * @param sampleCount Number of samples in each subframe of this frame - * @param channelDelta Channel data delta setting - */ - public FlacFrameInfo(int sampleCount, ChannelDelta channelDelta) { - this.sampleCount = sampleCount; - this.channelDelta = channelDelta; - } - - /** - * The relationship between stereo channels. - */ - public enum ChannelDelta { - NONE(-1), - LEFT_SIDE(1), - RIGHT_SIDE(0), - MID_SIDE(1); - - /** - * The index of the channel containing delta values. - */ - public final int deltaChannel; - - ChannelDelta(int deltaChannel) { - this.deltaChannel = deltaChannel; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameReader.java deleted file mode 100644 index d7f15c3..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacFrameReader.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac.frame; - -import com.sedmelluq.discord.lavaplayer.container.flac.FlacStreamInfo; -import com.sedmelluq.discord.lavaplayer.container.flac.frame.FlacFrameInfo.ChannelDelta; -import com.sedmelluq.discord.lavaplayer.tools.io.BitStreamReader; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Handles reading one FLAC audio frame. - */ -public class FlacFrameReader { - public static final int TEMPORARY_BUFFER_SIZE = 32; - - /** - * Reads one frame, returning the number of samples written to sampleBuffers. A return value of 0 indicates that EOF - * was reached in the frame, which happens when the track ends. - * - * @param inputStream Input stream for reading the track - * @param reader Bit stream reader for the same underlying stream as inputStream - * @param streamInfo Global stream information - * @param rawSampleBuffers Intermediate sample decoding buffers. FlacStreamInfo#channelCount integer buffers of size - * at least FlacStreamInfo#maximumBlockSize. - * @param sampleBuffers The sample buffers where the final decoding result is written to. FlacStreamInfo#channelCount - * short buffers of size at least FlacStreamInfo#maximumBlockSize. - * @param temporaryBuffer Temporary working buffer of size at least TEMPORARY_BUFFER_SIZE. No state is held in this - * between separate calls. - * @return The number of samples read, zero on EOF - * @throws IOException On read error - */ - public static int readFlacFrame(InputStream inputStream, BitStreamReader reader, FlacStreamInfo streamInfo, - int[][] rawSampleBuffers, short[][] sampleBuffers, int[] temporaryBuffer) throws IOException { - FlacFrameInfo frameInfo = findAndParseFrameHeader(inputStream, reader, streamInfo); - - if (frameInfo == null) { - return 0; - } - - for (int i = 0; i < streamInfo.channelCount; i++) { - FlacSubFrameReader.readSubFrame(reader, streamInfo, frameInfo, rawSampleBuffers[i], i, temporaryBuffer); - } - - reader.readRemainingBits(); - reader.asInteger(16); - - applyChannelDelta(frameInfo.channelDelta, rawSampleBuffers, frameInfo.sampleCount); - convertToShortPcm(streamInfo, frameInfo.sampleCount, rawSampleBuffers, sampleBuffers); - - return frameInfo.sampleCount; - } - - private static FlacFrameInfo findAndParseFrameHeader(InputStream inputStream, BitStreamReader reader, - FlacStreamInfo streamInfo) throws IOException { - int blockingStrategy; - - if ((blockingStrategy = skipToFrameSync(inputStream)) == -1) { - return null; - } - - return FlacFrameHeaderReader.readFrameHeader(reader, streamInfo, blockingStrategy == 1); - } - - private static int skipToFrameSync(InputStream inputStream) throws IOException { - int lastByte = -1; - int currentByte; - - while ((currentByte = inputStream.read()) != -1) { - if (lastByte == 0xFF && (currentByte & 0xFE) == 0xF8) { - return currentByte & 0x01; - } - lastByte = currentByte; - } - - return -1; - } - - private static void applyChannelDelta(ChannelDelta channelDelta, int[][] rawSampleBuffers, int sampleCount) { - switch (channelDelta) { - case LEFT_SIDE: - applyLeftSideDelta(rawSampleBuffers, sampleCount); - break; - case RIGHT_SIDE: - applyRightSideDelta(rawSampleBuffers, sampleCount); - break; - case MID_SIDE: - applyMidDelta(rawSampleBuffers, sampleCount); - break; - case NONE: - default: - break; - } - } - - private static void applyLeftSideDelta(int[][] rawSampleBuffers, int sampleCount) { - for (int i = 0; i < sampleCount; i++) { - rawSampleBuffers[1][i] = rawSampleBuffers[0][i] - rawSampleBuffers[1][i]; - } - } - - private static void applyRightSideDelta(int[][] rawSampleBuffers, int sampleCount) { - for (int i = 0; i < sampleCount; i++) { - rawSampleBuffers[0][i] += rawSampleBuffers[1][i]; - } - } - - private static void applyMidDelta(int[][] rawSampleBuffers, int sampleCount) { - for (int i = 0; i < sampleCount; i++) { - int delta = rawSampleBuffers[1][i]; - int middle = (rawSampleBuffers[0][i] << 1) + (delta & 1); - - rawSampleBuffers[0][i] = (middle + delta) >> 1; - rawSampleBuffers[1][i] = (middle - delta) >> 1; - } - } - - private static void convertToShortPcm(FlacStreamInfo streamInfo, int sampleCount, int[][] rawSampleBuffers, short[][] sampleBuffers) { - if (streamInfo.bitsPerSample < 16) { - increaseSampleSize(streamInfo, sampleCount, rawSampleBuffers, sampleBuffers); - } else if (streamInfo.bitsPerSample > 16) { - decreaseSampleSize(streamInfo, sampleCount, rawSampleBuffers, sampleBuffers); - } else { - for (int channel = 0; channel < streamInfo.channelCount; channel++) { - for (int i = 0; i < sampleCount; i++) { - sampleBuffers[channel][i] = (short) rawSampleBuffers[channel][i]; - } - } - } - } - - private static void increaseSampleSize(FlacStreamInfo streamInfo, int sampleCount, int[][] rawSampleBuffers, short[][] sampleBuffers) { - int shiftLeft = 16 - streamInfo.bitsPerSample; - - for (int channel = 0; channel < streamInfo.channelCount; channel++) { - for (int i = 0; i < sampleCount; i++) { - sampleBuffers[channel][i] = (short) (rawSampleBuffers[channel][i] << shiftLeft); - } - } - } - - private static void decreaseSampleSize(FlacStreamInfo streamInfo, int sampleCount, int[][] rawSampleBuffers, short[][] sampleBuffers) { - int shiftRight = streamInfo.bitsPerSample - 16; - - for (int channel = 0; channel < streamInfo.channelCount; channel++) { - for (int i = 0; i < sampleCount; i++) { - sampleBuffers[channel][i] = (short) (rawSampleBuffers[channel][i] >> shiftRight); - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacSubFrameReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacSubFrameReader.java deleted file mode 100644 index cbf16f5..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/flac/frame/FlacSubFrameReader.java +++ /dev/null @@ -1,197 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.flac.frame; - -import com.sedmelluq.discord.lavaplayer.container.flac.FlacStreamInfo; -import com.sedmelluq.discord.lavaplayer.tools.io.BitStreamReader; - -import java.io.IOException; - -/** - * Contains methods for reading a FLAC subframe - */ -public class FlacSubFrameReader { - private static final Encoding[] encodingMapping = new Encoding[]{ - Encoding.LPC, null, Encoding.FIXED, null, null, Encoding.VERBATIM, Encoding.CONSTANT - }; - - /** - * Reads and decodes one subframe (a channel of a frame) - * - * @param reader Bit stream reader - * @param streamInfo Stream global info - * @param frameInfo Current frame info - * @param sampleBuffer Output buffer for the (possibly delta) decoded samples of this subframe - * @param channel The index of the current channel - * @param temporaryBuffer Temporary working buffer of size at least 32 - * @throws IOException On read error - */ - public static void readSubFrame(BitStreamReader reader, FlacStreamInfo streamInfo, FlacFrameInfo frameInfo, - int[] sampleBuffer, int channel, int[] temporaryBuffer) throws IOException { - - if (reader.asInteger(1) == 1) { - throw new IllegalStateException("Subframe header must start with 0 bit."); - } - - boolean isDeltaChannel = frameInfo.channelDelta.deltaChannel == channel; - - int subFrameDescriptor = reader.asInteger(6); - - int wastedBitCount = reader.asInteger(1) == 1 ? reader.readAllZeroes() + 1 : 0; - int bitsPerSample = streamInfo.bitsPerSample - wastedBitCount + (isDeltaChannel ? 1 : 0); - - readSubFrameSamples(reader, subFrameDescriptor, bitsPerSample, sampleBuffer, frameInfo.sampleCount, temporaryBuffer); - - if (wastedBitCount > 0) { - for (int i = 0; i < frameInfo.sampleCount; i++) { - sampleBuffer[i] <<= wastedBitCount; - } - } - } - - private static void readSubFrameSamples(BitStreamReader reader, int subFrameDescriptor, int bitsPerSample, int[] sampleBuffer, - int sampleCount, int[] temporaryBuffer) throws IOException { - - Encoding subframeEncoding = encodingMapping[Integer.numberOfLeadingZeros(subFrameDescriptor) - 26]; - - if (subframeEncoding == null) { - throw new RuntimeException("Invalid subframe type."); - } else if (subframeEncoding == Encoding.LPC) { - readSubFrameLpcData(reader, (subFrameDescriptor & 0x1F) + 1, bitsPerSample, sampleBuffer, sampleCount, temporaryBuffer); - } else if (subframeEncoding == Encoding.FIXED) { - readSubFrameFixedData(reader, subFrameDescriptor & 0x07, bitsPerSample, sampleBuffer, sampleCount); - } else if (subframeEncoding == Encoding.VERBATIM) { - readSubFrameVerbatimData(reader, bitsPerSample, sampleBuffer, sampleCount); - } else if (subframeEncoding == Encoding.CONSTANT) { - readSubFrameConstantData(reader, bitsPerSample, sampleBuffer, sampleCount); - } - } - - private static void readSubFrameConstantData(BitStreamReader reader, int bitsPerSample, int[] sampleBuffer, - int sampleCount) throws IOException { - - int value = reader.asSignedInteger(bitsPerSample); - - for (int i = 0; i < sampleCount; i++) { - sampleBuffer[i] = value; - } - } - - private static void readSubFrameVerbatimData(BitStreamReader reader, int bitsPerSample, int[] sampleBuffer, - int sampleCount) throws IOException { - for (int i = 0; i < sampleCount; i++) { - sampleBuffer[i] = reader.asSignedInteger(bitsPerSample); - } - } - - private static void readSubFrameFixedData(BitStreamReader reader, int order, int bitsPerSample, int[] sampleBuffer, - int sampleCount) throws IOException { - for (int i = 0; i < order; i++) { - sampleBuffer[i] = reader.asSignedInteger(bitsPerSample); - } - - readResidual(reader, order, sampleBuffer, order, sampleCount); - restoreFixedSignal(sampleBuffer, sampleCount, order); - } - - private static void restoreFixedSignal(int[] buffer, int sampleCount, int order) { - switch (order) { - case 1: - for (int i = order; i < sampleCount; i++) { - buffer[i] += buffer[i - 1]; - } - break; - case 2: - for (int i = order; i < sampleCount; i++) { - buffer[i] += (buffer[i - 1] << 1) - buffer[i - 2]; - } - break; - case 3: - for (int i = order; i < sampleCount; i++) { - buffer[i] += (((buffer[i - 1] - buffer[i - 2]) << 1) + (buffer[i - 1] - buffer[i - 2])) + buffer[i - 3]; - } - break; - case 4: - for (int i = order; i < sampleCount; i++) { - buffer[i] += ((buffer[i - 1] + buffer[i - 3]) << 2) - ((buffer[i - 2] << 2) + (buffer[i - 2] << 1)) - buffer[i - 4]; - } - break; - default: - break; - } - } - - private static void readSubFrameLpcData(BitStreamReader reader, int order, int bitsPerSample, int[] sampleBuffer, - int sampleCount, int[] coefficients) throws IOException { - for (int i = 0; i < order; i++) { - sampleBuffer[i] = reader.asSignedInteger(bitsPerSample); - } - - int precision = reader.asInteger(4) + 1; - int shift = reader.asInteger(5); - - for (int i = 0; i < order; i++) { - coefficients[i] = reader.asSignedInteger(precision); - } - - readResidual(reader, order, sampleBuffer, order, sampleCount); - restoreLpcSignal(sampleBuffer, sampleCount, order, shift, coefficients); - } - - private static void restoreLpcSignal(int[] buffer, int sampleCount, int order, int shift, int[] coefficients) { - for (int i = order; i < sampleCount; i++) { - long sum = 0; - - for (int j = 0; j < order; j++) { - sum += (long) coefficients[j] * buffer[i - j - 1]; - } - - buffer[i] += (int) (sum >> shift); - } - } - - private static void readResidual(BitStreamReader reader, int order, int[] buffer, int startOffset, int endOffset) throws IOException { - int method = reader.asInteger(2); - - if (method > 1) { - throw new RuntimeException("Invalid residual coding method " + method); - } - - int partitionOrder = reader.asInteger(4); - int partitions = 1 << partitionOrder; - int partitionSamples = partitionOrder > 0 ? endOffset >> partitionOrder : endOffset - order; - int parameterLength = method == 0 ? 4 : 5; - int parameterMaximum = (1 << parameterLength) - 1; - - int sample = startOffset; - - for (int partition = 0; partition < partitions; partition++) { - int parameter = reader.asInteger(parameterLength); - int value = (partitionOrder == 0 || partition > 0) ? 0 : order; - - if (parameter < parameterMaximum) { - value = partitionSamples - value; - readResidualBlock(reader, buffer, sample, sample + value, parameter); - sample += value; - } else { - parameter = reader.asInteger(5); - - for (int i = value; i < partitionSamples; i++, sample++) { - buffer[sample] = reader.asSignedInteger(parameter); - } - } - } - } - - private static void readResidualBlock(BitStreamReader reader, int[] buffer, int offset, int endOffset, int parameter) throws IOException { - for (int i = offset; i < endOffset; i++) { - int lowOrderSigned = (reader.readAllZeroes() << parameter) | reader.asInteger(parameter); - buffer[i] = (lowOrderSigned & 1) == 0 ? lowOrderSigned >> 1 : -(lowOrderSigned >> 1) - 1; - } - } - - private enum Encoding { - CONSTANT, - VERBATIM, - FIXED, - LPC - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaAacTrackConsumer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaAacTrackConsumer.java deleted file mode 100644 index 1a19f88..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaAacTrackConsumer.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska; - -import com.sedmelluq.discord.lavaplayer.container.common.AacPacketRouter; -import com.sedmelluq.discord.lavaplayer.container.matroska.format.MatroskaFileTrack; -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegAacTrackConsumer; -import com.sedmelluq.discord.lavaplayer.natives.aac.AacDecoder; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; - -/** - * Consumes AAC track data from a matroska file. - */ -public class MatroskaAacTrackConsumer implements MatroskaTrackConsumer { - private static final Logger log = LoggerFactory.getLogger(MpegAacTrackConsumer.class); - - private final MatroskaFileTrack track; - private final ByteBuffer inputBuffer; - private final AacPacketRouter packetRouter; - - /** - * @param context Configuration and output information for processing - * @param track The MP4 audio track descriptor - */ - public MatroskaAacTrackConsumer(AudioProcessingContext context, MatroskaFileTrack track) { - this.track = track; - this.inputBuffer = ByteBuffer.allocateDirect(4096); - this.packetRouter = new AacPacketRouter(context, this::configureDecoder); - } - - @Override - public void initialise() { - log.debug("Initialising AAC track with expected frequency {} and channel count {}.", - track.audio.samplingFrequency, track.audio.channels); - } - - @Override - public MatroskaFileTrack getTrack() { - return track; - } - - @Override - public void seekPerformed(long requestedTimecode, long providedTimecode) { - packetRouter.seekPerformed(requestedTimecode, providedTimecode); - } - - @Override - public void flush() throws InterruptedException { - packetRouter.flush(); - } - - @Override - public void consume(ByteBuffer data) throws InterruptedException { - while (data.hasRemaining()) { - int chunk = Math.min(data.remaining(), inputBuffer.capacity()); - ByteBuffer chunkBuffer = data.duplicate(); - chunkBuffer.limit(chunkBuffer.position() + chunk); - - inputBuffer.clear(); - inputBuffer.put(chunkBuffer); - inputBuffer.flip(); - - packetRouter.processInput(inputBuffer); - - data.position(chunkBuffer.position()); - } - } - - @Override - public void close() { - packetRouter.close(); - } - - private void configureDecoder(AacDecoder decoder) { - decoder.configure(track.codecPrivate); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaAudioTrack.java deleted file mode 100644 index 2b0c6ee..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaAudioTrack.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska; - -import com.sedmelluq.discord.lavaplayer.container.matroska.format.MatroskaFileTrack; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.BaseAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -/** - * Audio track that handles the processing of MKV and WEBM formats - */ -public class MatroskaAudioTrack extends BaseAudioTrack { - private static final Logger log = LoggerFactory.getLogger(MatroskaAudioTrack.class); - - private final SeekableInputStream inputStream; - - /** - * @param trackInfo Track info - * @param inputStream Input stream for the file - */ - public MatroskaAudioTrack(AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - super(trackInfo); - - this.inputStream = inputStream; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) { - MatroskaStreamingFile file = loadMatroskaFile(); - MatroskaTrackConsumer trackConsumer = loadAudioTrack(file, localExecutor.getProcessingContext()); - - try { - localExecutor.executeProcessingLoop(() -> { - file.provideFrames(trackConsumer); - }, position -> { - file.seekToTimecode(trackConsumer.getTrack().index, position); - }); - } finally { - trackConsumer.close(); - } - } - - private MatroskaStreamingFile loadMatroskaFile() { - try { - MatroskaStreamingFile file = new MatroskaStreamingFile(inputStream); - file.readFile(); - - accurateDuration.set((int) file.getDuration()); - return file; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private MatroskaTrackConsumer loadAudioTrack(MatroskaStreamingFile file, AudioProcessingContext context) { - MatroskaTrackConsumer trackConsumer = null; - boolean success = false; - - try { - trackConsumer = selectAudioTrack(file.getTrackList(), context); - - if (trackConsumer == null) { - throw new IllegalStateException("No supported audio tracks in the file."); - } else { - log.debug("Starting to play track with codec {}", trackConsumer.getTrack().codecId); - } - - trackConsumer.initialise(); - success = true; - } finally { - if (!success && trackConsumer != null) { - trackConsumer.close(); - } - } - - return trackConsumer; - } - - private MatroskaTrackConsumer selectAudioTrack(MatroskaFileTrack[] tracks, AudioProcessingContext context) { - MatroskaTrackConsumer trackConsumer = null; - - for (MatroskaFileTrack track : tracks) { - if (track.type == MatroskaFileTrack.Type.AUDIO) { - if (MatroskaContainerProbe.OPUS_CODEC.equals(track.codecId)) { - trackConsumer = new MatroskaOpusTrackConsumer(context, track); - break; - } else if (MatroskaContainerProbe.VORBIS_CODEC.equals(track.codecId)) { - trackConsumer = new MatroskaVorbisTrackConsumer(context, track); - } else if (MatroskaContainerProbe.AAC_CODEC.equals(track.codecId)) { - trackConsumer = new MatroskaAacTrackConsumer(context, track); - } - } - } - - return trackConsumer; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaContainerProbe.java deleted file mode 100644 index 55c1ab0..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaContainerProbe.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.matroska.format.MatroskaFileTrack; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.*; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.supportedFormat; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.unsupportedFormat; - -/** - * Container detection probe for matroska format. - */ -public class MatroskaContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(MatroskaContainerProbe.class); - - static final String OPUS_CODEC = "A_OPUS"; - static final String VORBIS_CODEC = "A_VORBIS"; - static final String AAC_CODEC = "A_AAC"; - - private static final int[] EBML_TAG = new int[]{0x1A, 0x45, 0xDF, 0xA3}; - private static final List supportedCodecs = Arrays.asList(OPUS_CODEC, VORBIS_CODEC, AAC_CODEC); - - @Override - public String getName() { - return "matroska/webm"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - return false; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException { - if (!checkNextBytes(inputStream, EBML_TAG)) { - return null; - } - - log.debug("Track {} is a matroska file.", reference.identifier); - - MatroskaStreamingFile file = new MatroskaStreamingFile(inputStream); - file.readFile(); - - if (!hasSupportedAudioTrack(file)) { - return unsupportedFormat(this, "No supported audio tracks present in the file."); - } - - return supportedFormat(this, null, new AudioTrackInfo(UNKNOWN_TITLE, UNKNOWN_ARTIST, - (long) file.getDuration(), reference.identifier, false, reference.identifier)); - } - - private boolean hasSupportedAudioTrack(MatroskaStreamingFile file) { - for (MatroskaFileTrack track : file.getTrackList()) { - if (track.type == MatroskaFileTrack.Type.AUDIO && supportedCodecs.contains(track.codecId)) { - return true; - } - } - - return false; - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - return new MatroskaAudioTrack(trackInfo, inputStream); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaOpusTrackConsumer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaOpusTrackConsumer.java deleted file mode 100644 index aa929fe..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaOpusTrackConsumer.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska; - -import com.sedmelluq.discord.lavaplayer.container.common.OpusPacketRouter; -import com.sedmelluq.discord.lavaplayer.container.matroska.format.MatroskaFileTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.nio.ByteBuffer; - -/** - * Consumes OPUS track data from a matroska file. - */ -public class MatroskaOpusTrackConsumer implements MatroskaTrackConsumer { - private final MatroskaFileTrack track; - private final OpusPacketRouter opusPacketRouter; - - /** - * @param context Configuration and output information for processing - * @param track The associated matroska track - */ - public MatroskaOpusTrackConsumer(AudioProcessingContext context, MatroskaFileTrack track) { - this.track = track; - this.opusPacketRouter = new OpusPacketRouter(context, (int) track.audio.samplingFrequency, track.audio.channels); - } - - @Override - public MatroskaFileTrack getTrack() { - return track; - } - - @Override - public void initialise() { - // Nothing to do here - } - - @Override - public void seekPerformed(long requestedTimecode, long providedTimecode) { - opusPacketRouter.seekPerformed(requestedTimecode, providedTimecode); - } - - @Override - public void flush() throws InterruptedException { - opusPacketRouter.flush(); - } - - @Override - public void consume(ByteBuffer data) throws InterruptedException { - opusPacketRouter.process(data); - } - - @Override - public void close() { - opusPacketRouter.close(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaStreamingFile.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaStreamingFile.java deleted file mode 100644 index 4e85bff..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaStreamingFile.java +++ /dev/null @@ -1,398 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska; - -import com.sedmelluq.discord.lavaplayer.container.matroska.format.*; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Handles processing an MKV/WEBM file for the purpose of streaming one specific track from it. Only performs seeks when - * absolutely necessary, as the stream may be a network connection, in which case each seek may require a new connection. - */ -public class MatroskaStreamingFile { - private final MatroskaFileReader reader; - - private long timecodeScale = 1000000; - private double duration; - private final ArrayList trackList = new ArrayList<>(); - private MatroskaElement segmentElement = null; - private MatroskaElement firstClusterElement = null; - - private long minimumTimecode = 0; - private boolean seeking = false; - - private Long cueElementPosition = null; - private List cuePoints = null; - - /** - * @param inputStream The input stream for the file - */ - public MatroskaStreamingFile(SeekableInputStream inputStream) { - this.reader = new MatroskaFileReader(inputStream); - } - - /** - * @return Timescale for the durations used in this file - */ - public long getTimecodeScale() { - return timecodeScale; - } - - /** - * @return Total duration of the file - */ - public double getDuration() { - return duration; - } - - /** - * @return Array of tracks in this file - */ - public MatroskaFileTrack[] getTrackList() { - if (!trackList.isEmpty()) { - MatroskaFileTrack[] tracks = new MatroskaFileTrack[trackList.size()]; - - for (int t = 0; t < trackList.size(); t++) { - tracks[t] = trackList.get(t); - } - return tracks; - } else { - return new MatroskaFileTrack[0]; - } - } - - /** - * Read the headers and tracks from the file. - * - * @throws IOException On read error. - */ - public void readFile() throws IOException { - MatroskaElement ebmlElement = reader.readNextElement(null); - if (ebmlElement == null) { - throw new RuntimeException("Unable to scan for EBML elements"); - } - - if (ebmlElement.is(MatroskaElementType.Ebml)) { - parseEbmlElement(ebmlElement); - } else { - throw new RuntimeException("EBML Header not the first element in the file"); - } - - segmentElement = reader.readNextElement(null).frozen(); - - if (segmentElement.is(MatroskaElementType.Segment)) { - parseSegmentElement(segmentElement); - } else { - throw new RuntimeException(String.format("Segment not the second element in the file: was %s (%d) instead", - segmentElement.getType().name(), segmentElement.getId())); - } - } - - private void parseEbmlElement(MatroskaElement ebmlElement) throws IOException { - MatroskaElement child; - - while ((child = reader.readNextElement(ebmlElement)) != null) { - if (child.is(MatroskaElementType.DocType)) { - String docType = reader.asString(child); - - if (docType.compareTo("matroska") != 0 && docType.compareTo("webm") != 0) { - throw new RuntimeException("Error: DocType is not matroska, \"" + docType + "\""); - } - } - - reader.skip(child); - } - } - - private void parseSegmentElement(MatroskaElement segmentElement) throws IOException { - MatroskaElement child; - - while ((child = reader.readNextElement(segmentElement)) != null) { - if (child.is(MatroskaElementType.Info)) { - parseSegmentInfo(child); - } else if (child.is(MatroskaElementType.Tracks)) { - parseTracks(child); - } else if (child.is(MatroskaElementType.Cluster)) { - firstClusterElement = child.frozen(); - break; - } else if (child.is(MatroskaElementType.SeekHead)) { - parseSeekInfoForCuePosition(child); - } else if (child.is(MatroskaElementType.Cues)) { - cuePoints = parseCues(child); - } - - reader.skip(child); - } - } - - private void parseSeekInfoForCuePosition(MatroskaElement seekHeadElement) throws IOException { - MatroskaElement child; - - while ((child = reader.readNextElement(seekHeadElement)) != null) { - if (child.is(MatroskaElementType.Seek)) { - parseSeekElement(child); - } - - reader.skip(child); - } - } - - private void parseSeekElement(MatroskaElement seekElement) throws IOException { - MatroskaElement child; - boolean isCueElement = false; - - while ((child = reader.readNextElement(seekElement)) != null) { - if (child.is(MatroskaElementType.SeekId)) { - isCueElement = ByteBuffer.wrap(reader.asBytes(child)).equals(ByteBuffer.wrap(MatroskaElementType.Cues.bytes)); - } else if (child.is(MatroskaElementType.SeekPosition) && isCueElement) { - cueElementPosition = reader.asLong(child); - } - - reader.skip(child); - } - } - - private List parseCues(MatroskaElement cuesElement) throws IOException { - List parsedCuePoints = new ArrayList<>(); - MatroskaElement child; - - while ((child = reader.readNextElement(cuesElement)) != null) { - if (child.is(MatroskaElementType.CuePoint)) { - MatroskaCuePoint cuePoint = parseCuePoint(child); - - if (cuePoint != null) { - parsedCuePoints.add(cuePoint); - } - } - - reader.skip(child); - } - - return parsedCuePoints.isEmpty() ? null : parsedCuePoints; - } - - private MatroskaCuePoint parseCuePoint(MatroskaElement cuePointElement) throws IOException { - MatroskaElement child; - - Long cueTime = null; - long[] positions = null; - - while ((child = reader.readNextElement(cuePointElement)) != null) { - if (child.is(MatroskaElementType.CueTime)) { - cueTime = reader.asLong(child); - } else if (child.is(MatroskaElementType.CueTrackPositions)) { - positions = parseCueTrackPositions(child); - } - - reader.skip(child); - } - - if (cueTime != null && positions != null) { - return new MatroskaCuePoint(cueTime, positions); - } else { - return null; - } - } - - private long[] parseCueTrackPositions(MatroskaElement positionsElement) throws IOException { - Long currentTrackId = null; - MatroskaElement child; - - long[] positions = new long[trackList.size() + 1]; - Arrays.fill(positions, -1); - - while ((child = reader.readNextElement(positionsElement)) != null) { - if (child.is(MatroskaElementType.CueTrack)) { - currentTrackId = reader.asLong(child); - } else if (child.is(MatroskaElementType.CueClusterPosition) && currentTrackId != null) { - positions[currentTrackId.intValue()] = reader.asLong(child); - } - - reader.skip(child); - } - - return positions; - } - - /** - * Perform a seek to a specified timecode - * - * @param trackId ID of the reference track - * @param timecode Timecode using the timescale of the file - */ - public void seekToTimecode(int trackId, long timecode) { - try { - seekToTimecodeInternal(trackId, timecode); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void seekToTimecodeInternal(int trackId, long timecode) throws IOException { - minimumTimecode = timecode; - seeking = true; - - if (cuePoints == null && cueElementPosition != null) { - reader.seek(segmentElement.getPosition() + cueElementPosition); - - MatroskaElement cuesElement = reader.readNextElement(segmentElement); - if (!cuesElement.is(MatroskaElementType.Cues)) { - throw new IllegalStateException("The element here should be cue."); - } - - cuePoints = parseCues(cuesElement); - } - - if (cuePoints != null) { - MatroskaCuePoint cuePoint = lastCueNotAfterTimecode(timecode); - - if (cuePoint != null && cuePoint.trackClusterOffsets[trackId] >= 0) { - reader.seek(segmentElement.getDataPosition() + cuePoint.trackClusterOffsets[trackId]); - return; - } - } - - // If there were no cues available, just seek to the beginning and discard until the right timecode - reader.seek(firstClusterElement.getPosition()); - } - - private MatroskaCuePoint lastCueNotAfterTimecode(long timecode) { - int largerTimecodeIndex; - - for (largerTimecodeIndex = 0; largerTimecodeIndex < cuePoints.size(); largerTimecodeIndex++) { - if (cuePoints.get(largerTimecodeIndex).timecode > timecode) { - break; - } - } - - if (largerTimecodeIndex > 0) { - return cuePoints.get(largerTimecodeIndex - 1); - } else { - return null; - } - } - - /** - * Provide data chunks for the specified track consumer - * - * @param consumer Track data consumer - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - public void provideFrames(MatroskaTrackConsumer consumer) throws InterruptedException { - try { - long position = reader.getPosition(); - MatroskaElement child = position == firstClusterElement.getDataPosition() - ? firstClusterElement : reader.readNextElement(segmentElement); - - while (child != null) { - if (child.is(MatroskaElementType.Cluster)) { - parseNextCluster(child, consumer); - } - - reader.skip(child); - - if (segmentElement.getRemaining(reader.getPosition()) <= 0) { - break; - } - - child = reader.readNextElement(segmentElement); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void parseNextCluster(MatroskaElement clusterElement, MatroskaTrackConsumer consumer) throws InterruptedException, IOException { - MatroskaElement child; - long clusterTimecode = 0; - - while ((child = reader.readNextElement(clusterElement)) != null) { - if (child.is(MatroskaElementType.Timecode)) { - clusterTimecode = reader.asLong(child); - } else if (child.is(MatroskaElementType.SimpleBlock)) { - parseClusterSimpleBlock(child, consumer, clusterTimecode); - } else if (child.is(MatroskaElementType.BlockGroup)) { - parseClusterBlockGroup(child, consumer, clusterTimecode); - } - - reader.skip(child); - } - } - - private void parseClusterSimpleBlock(MatroskaElement simpleBlock, MatroskaTrackConsumer consumer, long clusterTimecode) - throws InterruptedException, IOException { - - MatroskaBlock block = reader.readBlockHeader(simpleBlock, consumer.getTrack().index); - - if (block != null) { - processFrameInBlock(block, consumer, clusterTimecode); - } - } - - private void parseClusterBlockGroup(MatroskaElement blockGroup, MatroskaTrackConsumer consumer, long clusterTimecode) - throws InterruptedException, IOException { - - MatroskaElement child; - - while ((child = reader.readNextElement(blockGroup)) != null) { - if (child.is(MatroskaElementType.Block)) { - MatroskaBlock block = reader.readBlockHeader(child, consumer.getTrack().index); - - if (block != null) { - processFrameInBlock(block, consumer, clusterTimecode); - } - } - - reader.skip(child); - } - } - - private void processFrameInBlock(MatroskaBlock block, MatroskaTrackConsumer consumer, long clusterTimecode) - throws InterruptedException, IOException { - - long timecode = clusterTimecode + block.getTimecode(); - - if (timecode >= minimumTimecode) { - int frameCount = block.getFrameCount(); - - if (seeking) { - consumer.seekPerformed(minimumTimecode, timecode); - seeking = false; - } - - for (int i = 0; i < frameCount; i++) { - consumer.consume(block.getNextFrameBuffer(reader, i)); - } - } - } - - private void parseSegmentInfo(MatroskaElement infoElement) throws IOException { - MatroskaElement child; - - while ((child = reader.readNextElement(infoElement)) != null) { - if (child.is(MatroskaElementType.Duration)) { - duration = reader.asDouble(child); - } else if (child.is(MatroskaElementType.TimecodeScale)) { - timecodeScale = reader.asLong(child); - } - - reader.skip(child); - } - } - - private void parseTracks(MatroskaElement tracksElement) throws IOException { - MatroskaElement child; - - while ((child = reader.readNextElement(tracksElement)) != null) { - if (child.is(MatroskaElementType.TrackEntry)) { - trackList.add(MatroskaFileTrack.parse(child, reader)); - } - - reader.skip(child); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaTrackConsumer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaTrackConsumer.java deleted file mode 100644 index d0ea0c1..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaTrackConsumer.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska; - -import com.sedmelluq.discord.lavaplayer.container.matroska.format.MatroskaFileTrack; - -import java.nio.ByteBuffer; - -/** - * Consumer for the file frames of a specific matroska file track - */ -public interface MatroskaTrackConsumer { - /** - * @return The associated matroska file track - */ - MatroskaFileTrack getTrack(); - - /** - * Initialise the consumer, called before first consume() - */ - void initialise(); - - /** - * Indicates that the next frame is not a direct continuation of the previous one - * - * @param requestedTimecode Timecode in milliseconds to which the seek was requested to - * @param providedTimecode Timecode in milliseconds to which the seek was actually performed to - */ - void seekPerformed(long requestedTimecode, long providedTimecode); - - /** - * Indicates that no more input will come, all remaining buffers should be flushed - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void flush() throws InterruptedException; - - /** - * Consume one frame from the track - * - * @param data The data of the frame - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void consume(ByteBuffer data) throws InterruptedException; - - /** - * Already flushed, no more input coming. Free all resources - */ - void close(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaVorbisTrackConsumer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaVorbisTrackConsumer.java deleted file mode 100644 index 64f108a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaVorbisTrackConsumer.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska; - -import com.sedmelluq.discord.lavaplayer.container.matroska.format.MatroskaFileTrack; -import com.sedmelluq.discord.lavaplayer.container.matroska.format.MatroskaFileTrack.AudioDetails; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipeline; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipelineFactory; -import com.sedmelluq.discord.lavaplayer.filter.PcmFormat; -import com.sedmelluq.discord.lavaplayer.natives.vorbis.VorbisDecoder; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.nio.ByteBuffer; - -/** - * Consumes Vorbis track data from a matroska file. - */ -public class MatroskaVorbisTrackConsumer implements MatroskaTrackConsumer { - private static final int PCM_BUFFER_SIZE = 4096; - private static final int COPY_BUFFER_SIZE = 256; - - private final MatroskaFileTrack track; - private final VorbisDecoder decoder; - private final byte[] copyBuffer; - private final AudioPipeline downstream; - private ByteBuffer inputBuffer; - private float[][] channelPcmBuffers; - - /** - * @param context Configuration and output information for processing - * @param track The associated matroska track - */ - public MatroskaVorbisTrackConsumer(AudioProcessingContext context, MatroskaFileTrack track) { - - this.track = track; - this.decoder = new VorbisDecoder(); - this.copyBuffer = new byte[COPY_BUFFER_SIZE]; - - AudioDetails audioTrack = fillMissingDetails(track.audio, track.codecPrivate); - this.downstream = AudioPipelineFactory.create(context, - new PcmFormat(audioTrack.channels, (int) audioTrack.samplingFrequency)); - } - - @Override - public MatroskaFileTrack getTrack() { - return track; - } - - @Override - public void initialise() { - ByteBuffer directPrivateData = ByteBuffer.allocateDirect(track.codecPrivate.length); - - directPrivateData.put(track.codecPrivate); - directPrivateData.flip(); - - try { - int lengthInfoSize = directPrivateData.get(); - - if (lengthInfoSize != 2) { - throw new IllegalStateException("Unexpected lacing count."); - } - - int firstHeaderSize = readLacingValue(directPrivateData); - int secondHeaderSize = readLacingValue(directPrivateData); - - ByteBuffer infoBuffer = directPrivateData.duplicate(); - infoBuffer.limit(infoBuffer.position() + firstHeaderSize); - - directPrivateData.position(directPrivateData.position() + firstHeaderSize + secondHeaderSize); - - decoder.initialise(infoBuffer, directPrivateData); - - channelPcmBuffers = new float[decoder.getChannelCount()][]; - - for (int i = 0; i < channelPcmBuffers.length; i++) { - channelPcmBuffers[i] = new float[PCM_BUFFER_SIZE]; - } - } catch (Exception e) { - throw new RuntimeException("Reading Vorbis header failed.", e); - } - } - - private static int readLacingValue(ByteBuffer buffer) { - int value = 0; - int current; - - do { - current = buffer.get() & 0xFF; - value += current; - } while (current == 255); - - return value; - } - - private static AudioDetails fillMissingDetails(AudioDetails details, byte[] headers) { - if (details.channels != 0) { - return details; - } - - ByteBuffer buffer = ByteBuffer.wrap(headers); - readLacingValue(buffer); // first header size - readLacingValue(buffer); // second header size - - buffer.getInt(); // vorbis version - int channelCount = buffer.get() & 0xFF; - - return new AudioDetails(details.samplingFrequency, details.outputSamplingFrequency, channelCount, details.bitDepth); - } - - @Override - public void seekPerformed(long requestedTimecode, long providedTimecode) { - downstream.seekPerformed(requestedTimecode, providedTimecode); - } - - @Override - public void flush() throws InterruptedException { - downstream.flush(); - } - - private ByteBuffer getDirectBuffer(int size) { - if (inputBuffer == null || inputBuffer.capacity() < size) { - inputBuffer = ByteBuffer.allocateDirect(size * 3 / 2); - } - - inputBuffer.clear(); - return inputBuffer; - } - - private ByteBuffer getAsDirectBuffer(ByteBuffer data) { - ByteBuffer buffer = getDirectBuffer(data.remaining()); - - while (data.remaining() > 0) { - int chunk = Math.min(copyBuffer.length, data.remaining()); - data.get(copyBuffer, 0, chunk); - buffer.put(copyBuffer, 0, chunk); - } - - buffer.flip(); - return buffer; - } - - @Override - public void consume(ByteBuffer data) throws InterruptedException { - ByteBuffer directBuffer = getAsDirectBuffer(data); - decoder.input(directBuffer); - - int output; - - do { - output = decoder.output(channelPcmBuffers); - - if (output > 0) { - downstream.process(channelPcmBuffers, 0, output); - } - } while (output == PCM_BUFFER_SIZE); - } - - @Override - public void close() { - downstream.close(); - decoder.close(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaBlock.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaBlock.java deleted file mode 100644 index d35d14b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaBlock.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska.format; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * Provides information and buffer to read from for a Matroska block. - */ -public interface MatroskaBlock { - /** - * @return The timecode of this block relative to its cluster - */ - int getTimecode(); - - /** - * @return The track number which this block is for - */ - int getTrackNumber(); - - /** - * @return Whether this block is a keyframe - */ - boolean isKeyFrame(); - - /** - * @return The number of frames in this block - */ - int getFrameCount(); - - /** - * The reader must already be positioned at the frame that is to be read next. - * - * @param reader The reader to use to read the block contents into a buffer. - * @param index The index of the frame to get the buffer for. - * @return A buffer where the range between position and limit contains the data for the specific frame. The contents - * of this buffer are only valid until the next call to this method. - * @throws IOException On read error. - */ - ByteBuffer getNextFrameBuffer(MatroskaFileReader reader, int index) throws IOException; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaCuePoint.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaCuePoint.java deleted file mode 100644 index 129b26a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaCuePoint.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska.format; - -/** - * Matroska file cue point. Provides the offsets at a specific timecode for each track - */ -public class MatroskaCuePoint { - /** - * Timecode using the file timescale - */ - public final long timecode; - /** - * Absolute offset to the cluster - */ - public final long[] trackClusterOffsets; - - /** - * @param timecode Timecode using the file timescale - * @param trackClusterOffsets Absolute offset to the cluster - */ - public MatroskaCuePoint(long timecode, long[] trackClusterOffsets) { - this.timecode = timecode; - this.trackClusterOffsets = trackClusterOffsets; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaEbmlReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaEbmlReader.java deleted file mode 100644 index e946f4b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaEbmlReader.java +++ /dev/null @@ -1,169 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska.format; - -import java.io.DataInput; -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * Handles reading various different EBML code formats. - */ -public class MatroskaEbmlReader { - /** - * Read an EBML code from data input with fixed size - no size encoded in the data. - * - * @param input Data input to read bytes from - * @param codeLength Length of the code in bytes - * @param type Method of sign handling (null is unsigned) - * @return Read EBML code - * @throws IOException On read error - */ - public static long readFixedSizeEbmlInteger(DataInput input, int codeLength, Type type) throws IOException { - long code = 0; - - for (int i = 1; i <= codeLength; i++) { - code |= applyNextByte(codeLength, input.readByte() & 0xFF, i); - } - - return applyType(code, codeLength, type); - } - - /** - * Read an EBML code from data input. - * - * @param input Data input to read bytes from - * @param type Method of sign handling (null is unsigned) - * @return Read EBML code - * @throws IOException On read error - */ - public static long readEbmlInteger(DataInput input, Type type) throws IOException { - int firstByte = input.readByte() & 0xFF; - int codeLength = getCodeLength(firstByte); - - long code = applyFirstByte(firstByte, codeLength); - - for (int i = 2; i <= codeLength; i++) { - code |= applyNextByte(codeLength, input.readByte() & 0xFF, i); - } - - return applyType(code, codeLength, type); - } - - /** - * Read an EBML code from byte buffer. - * - * @param buffer Buffer to read bytes from - * @param type Method of sign handling (null is unsigned) - * @return Read EBML code - */ - public static long readEbmlInteger(ByteBuffer buffer, Type type) { - int firstByte = buffer.get() & 0xFF; - int codeLength = getCodeLength(firstByte); - - long code = applyFirstByte(firstByte, codeLength); - - for (int i = 2; i <= codeLength; i++) { - code |= applyNextByte(codeLength, buffer.get() & 0xFF, i); - } - - return applyType(code, codeLength, type); - } - - private static int getCodeLength(int firstByte) { - int codeLength = Integer.numberOfLeadingZeros(firstByte) - 23; - if (codeLength > 8) { - throw new IllegalStateException("More than 4 bytes for length, probably invalid data"); - } - - return codeLength; - } - - private static long applyFirstByte(long firstByte, int codeLength) { - return (firstByte & (0xFFL >> codeLength)) << ((codeLength - 1) << 3); - } - - private static long applyNextByte(int codeLength, int value, int index) { - return value << ((codeLength - index) << 3); - } - - private static long applyType(long code, int codeLength, Type type) { - if (type != null) { - switch (type) { - case SIGNED: - return signEbmlInteger(code, codeLength); - case LACE_SIGNED: - return laceSignEbmlInteger(code, codeLength); - case UNSIGNED: - default: - return code; - } - } else { - return code; - } - } - - private static long laceSignEbmlInteger(long code, int codeLength) { - switch (codeLength) { - case 1: - return code - 63; - case 2: - return code - 8191; - case 3: - return code - 1048575; - case 4: - return code - 134217727; - default: - throw new IllegalStateException("Code length out of bounds."); - } - } - - private static long signEbmlInteger(long code, int codeLength) { - long mask = getSignMask(codeLength); - - if ((code & mask) != 0) { - return code | mask; - } else { - return code; - } - } - - private static long getSignMask(int codeLength) { - switch (codeLength) { - case 1: - return ~0x000000000000003FL; - case 2: - return ~0x0000000000001FFFL; - case 3: - return ~0x00000000000FFFFFL; - case 4: - return ~0x0000000007FFFFFFL; - case 5: - return ~0x00000003FFFFFFFFL; - case 6: - return ~0x000001FFFFFFFFFFL; - case 7: - return ~0x0000FFFFFFFFFFFFL; - case 8: - return ~0x007FFFFFFFFFFFFFL; - default: - throw new IllegalStateException("Code length out of bounds."); - } - } - - /** - * EBML code type (sign handling method). - */ - public enum Type { - /** - * Signed value with first bit marking the sign. - */ - SIGNED, - /** - * Signed value where where sign is applied via subtraction. - */ - LACE_SIGNED, - /** - * Unsigned value. - */ - UNSIGNED - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElement.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElement.java deleted file mode 100644 index 303d7c3..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElement.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska.format; - -/** - * Matroska container element. - */ -public class MatroskaElement { - protected final int level; - protected long id; - protected MatroskaElementType type; - protected long position; - protected int headerSize; - protected int dataSize; - - protected MatroskaElement(int level) { - this.level = level; - } - - /** - * @return The depth of the element in the element tree. - */ - public int getLevel() { - return level; - } - - /** - * @return The EBML code of the element. - */ - public long getId() { - return id; - } - - /** - * @return Element type, Unknown if not listed in the enum. - */ - public MatroskaElementType getType() { - return type; - } - - /** - * @return Absolute position of the element in the file. - */ - public long getPosition() { - return position; - } - - /** - * @return Size of the header in bytes. - */ - public int getHeaderSize() { - return headerSize; - } - - /** - * @return Size of the payload in bytes. - */ - public int getDataSize() { - return dataSize; - } - - /** - * @param type Element type. - * @return True if this element is of the specified type. - */ - public boolean is(MatroskaElementType type) { - return type.id == this.id; - } - - /** - * @param dataType Element data type. - * @return True if the type of the element uses the specified data type. - */ - public boolean is(MatroskaElementType.DataType dataType) { - return dataType == type.dataType; - } - - /** - * @param currentPosition Absolute position to check against. - * @return The number of bytes from the specified position to the end of this element. - */ - public long getRemaining(long currentPosition) { - return (position + headerSize + dataSize) - currentPosition; - } - - /** - * @return The absolute position of the data of this element. - */ - public long getDataPosition() { - return position + headerSize; - } - - /** - * @return A frozen version of the element safe to keep for later use. - */ - public MatroskaElement frozen() { - MatroskaElement element = new MatroskaElement(level); - element.id = id; - element.type = type; - element.position = position; - element.headerSize = headerSize; - element.dataSize = dataSize; - return element; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElementType.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElementType.java deleted file mode 100644 index ef79522..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElementType.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska.format; - -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; - -/** - * Registry of all required element types. This is not the complete set. - */ -@SuppressWarnings("squid:S00115") -public enum MatroskaElementType { - Ebml(DataType.MASTER, new int[]{0x1A, 0x45, 0xDF, 0xA3}), - DocType(DataType.STRING, new int[]{0x42, 0x82}), - Segment(DataType.MASTER, new int[]{0x18, 0x53, 0x80, 0x67}), - SeekHead(DataType.MASTER, new int[]{0x11, 0x4D, 0x9B, 0x74}), - Seek(DataType.MASTER, new int[]{0x4D, 0xBB}), - SeekId(DataType.BINARY, new int[]{0x53, 0xAB}), - SeekPosition(DataType.UNSIGNED_INTEGER, new int[]{0x53, 0xAC}), - Info(DataType.MASTER, new int[]{0x15, 0x49, 0xA9, 0x66}), - Duration(DataType.FLOAT, new int[]{0x44, 0x89}), - TimecodeScale(DataType.UNSIGNED_INTEGER, new int[]{0x2A, 0xD7, 0xB1}), - Cluster(DataType.MASTER, new int[]{0x1F, 0x43, 0xB6, 0x75}), - Timecode(DataType.UNSIGNED_INTEGER, new int[]{0xE7}), - SimpleBlock(DataType.BINARY, new int[]{0xA3}), - BlockGroup(DataType.MASTER, new int[]{0xA0}), - Block(DataType.BINARY, new int[]{0xA1}), - BlockDuration(DataType.UNSIGNED_INTEGER, new int[]{0x9B}), - ReferenceBlock(DataType.SIGNED_INTEGER, new int[]{0xFB}), - Tracks(DataType.MASTER, new int[]{0x16, 0x54, 0xAE, 0x6B}), - TrackEntry(DataType.MASTER, new int[]{0xAE}), - TrackNumber(DataType.UNSIGNED_INTEGER, new int[]{0xD7}), - TrackUid(DataType.UNSIGNED_INTEGER, new int[]{0x73, 0xC5}), - TrackType(DataType.UNSIGNED_INTEGER, new int[]{0x83}), - Name(DataType.UTF8_STRING, new int[]{0x53, 0x6E}), - CodecId(DataType.STRING, new int[]{0x86}), - CodecPrivate(DataType.BINARY, new int[]{0x63, 0xA2}), - Audio(DataType.MASTER, new int[]{0xE1}), - SamplingFrequency(DataType.FLOAT, new int[]{0xB5}), - OutputSamplingFrequency(DataType.FLOAT, new int[]{0x78, 0xB5}), - Channels(DataType.UNSIGNED_INTEGER, new int[]{0x9F}), - BitDepth(DataType.UNSIGNED_INTEGER, new int[]{0x62, 0x64}), - Cues(DataType.MASTER, new int[]{0x1C, 0x53, 0xBB, 0x6B}), - CuePoint(DataType.MASTER, new int[]{0xBB}), - CueTime(DataType.UNSIGNED_INTEGER, new int[]{0xB3}), - CueTrackPositions(DataType.MASTER, new int[]{0xB7}), - CueTrack(DataType.UNSIGNED_INTEGER, new int[]{0xF7}), - CueClusterPosition(DataType.UNSIGNED_INTEGER, new int[]{0xF1}), - Unknown(DataType.BINARY, new int[]{}); - - private static Map mapping; - - /** - * The ID as EBML code bytes. - */ - public final byte[] bytes; - /** - * The ID of the element type. - */ - public final long id; - /** - * Data type of the element type. - */ - public final DataType dataType; - - static { - Map codeMapping = new HashMap<>(); - - for (MatroskaElementType code : MatroskaElementType.class.getEnumConstants()) { - if (code != Unknown) { - codeMapping.put(code.id, code); - } - } - - mapping = codeMapping; - } - - MatroskaElementType(DataType dataType, int[] integers) { - this.dataType = dataType; - this.bytes = asByteArray(integers); - this.id = bytes.length > 0 ? MatroskaEbmlReader.readEbmlInteger(ByteBuffer.wrap(bytes), null) : -1; - } - - /** - * Data type of an element. - */ - public enum DataType { - /** - * Contains child elements. - */ - MASTER, - /** - * Unsigned EBML integer. - */ - UNSIGNED_INTEGER, - /** - * Signed EBML integer. - */ - SIGNED_INTEGER, - /** - * ASCII-encoded string. - */ - STRING, - /** - * UTF8-encoded string. - */ - UTF8_STRING, - /** - * Raw binary data. - */ - BINARY, - /** - * Float (either 4 or 8 byte) - */ - FLOAT, - /** - * Nanosecond timestamp since 2001. - */ - DATE - } - - private static byte[] asByteArray(int[] integers) { - byte[] bytes = new byte[integers.length]; - - for (int i = 0; i < integers.length; i++) { - bytes[i] = (byte) integers[i]; - } - - return bytes; - } - - /** - * @param id Code of the element type to find - * @return The element type, Unknown if not present. - */ - public static MatroskaElementType find(long id) { - MatroskaElementType code = mapping.get(id); - if (code == null) { - code = Unknown; - } - return code; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaFileReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaFileReader.java deleted file mode 100644 index 2fee82c..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaFileReader.java +++ /dev/null @@ -1,216 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska.format; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -/** - * Handles reading of elements and their content from an MKV file. - */ -public class MatroskaFileReader { - private final SeekableInputStream inputStream; - private final DataInput dataInput; - private final MutableMatroskaElement[] levels; - private final MutableMatroskaBlock mutableBlock; - - /** - * @param inputStream Input stream to read from. - */ - public MatroskaFileReader(SeekableInputStream inputStream) { - this.inputStream = inputStream; - this.dataInput = new DataInputStream(inputStream); - this.levels = new MutableMatroskaElement[8]; - this.mutableBlock = new MutableMatroskaBlock(); - } - - /** - * @param parent The parent element to use for bounds checking, null is valid. - * @return The element whose header was read. Null if the parent/file has ended. The contents of this element are only - * valid until the next element at the same level is read, use {@link MatroskaElement#frozen()} to get a - * permanent instance. - * @throws IOException On read error - */ - public MatroskaElement readNextElement(MatroskaElement parent) throws IOException { - long position = inputStream.getPosition(); - long remaining = parent != null ? parent.getRemaining(position) : inputStream.getContentLength() - position; - - if (remaining == 0) { - return null; - } else if (remaining < 0) { - throw new IllegalStateException("Current position is beyond this element"); - } - - long id = MatroskaEbmlReader.readEbmlInteger(dataInput, null); - long dataSize = MatroskaEbmlReader.readEbmlInteger(dataInput, null); - long dataPosition = inputStream.getPosition(); - - int level = parent == null ? 0 : parent.getLevel() + 1; - MutableMatroskaElement element = levels[level]; - - if (element == null) { - element = levels[level] = new MutableMatroskaElement(level); - } - - element.setId(id); - element.setType(MatroskaElementType.find(id)); - element.setPosition(position); - element.setHeaderSize((int) (dataPosition - position)); - element.setDataSize((int) dataSize); - return element; - } - - /** - * Reads one Matroska block header. The data is of the block is not read, but can be read frame by frame using - * {@link MatroskaBlock#getNextFrameBuffer(MatroskaFileReader, int)}. - * - * @param parent The block parent element. - * @param trackFilter The ID of the track to read data for from the block. - * @return An instance of a block if it contains data for the requested track, null otherwise. - * @throws IOException On read error. - */ - public MatroskaBlock readBlockHeader(MatroskaElement parent, int trackFilter) throws IOException { - if (!mutableBlock.parseHeader(this, parent, trackFilter)) { - return null; - } - - return mutableBlock; - } - - /** - * @param element Element to read from - * @return The contents of the element as an integer - * @throws IOException On read error - */ - public int asInteger(MatroskaElement element) throws IOException { - if (element.is(MatroskaElementType.DataType.UNSIGNED_INTEGER)) { - long value = MatroskaEbmlReader.readFixedSizeEbmlInteger(dataInput, element.dataSize, null); - - if (value < 0 || value > Integer.MAX_VALUE) { - throw new ArithmeticException("Cannot convert unsigned value to integer."); - } else { - return (int) value; - } - } else if (element.is(MatroskaElementType.DataType.SIGNED_INTEGER)) { - return Math.toIntExact(MatroskaEbmlReader.readFixedSizeEbmlInteger(dataInput, element.dataSize, MatroskaEbmlReader.Type.SIGNED)); - } else { - throw new IllegalArgumentException("Not an integer element."); - } - } - - /** - * @param element Element to read from - * @return The contents of the element as a long - * @throws IOException On read error - */ - public long asLong(MatroskaElement element) throws IOException { - if (element.is(MatroskaElementType.DataType.UNSIGNED_INTEGER)) { - return MatroskaEbmlReader.readFixedSizeEbmlInteger(dataInput, element.dataSize, null); - } else if (element.is(MatroskaElementType.DataType.SIGNED_INTEGER)) { - return MatroskaEbmlReader.readFixedSizeEbmlInteger(dataInput, element.dataSize, MatroskaEbmlReader.Type.SIGNED); - } else { - throw new IllegalArgumentException("Not an integer element."); - } - } - - /** - * @param element Element to read from - * @return The contents of the element as a float - * @throws IOException On read error - */ - public float asFloat(MatroskaElement element) throws IOException { - if (element.is(MatroskaElementType.DataType.FLOAT)) { - if (element.dataSize == 4) { - return dataInput.readFloat(); - } else if (element.dataSize == 8) { - return (float) dataInput.readDouble(); - } else { - throw new IllegalStateException("Float element has invalid size."); - } - } else { - throw new IllegalArgumentException("Not a float element."); - } - } - - /** - * @param element Element to read from - * @return The contents of the element as a double - * @throws IOException On read error - */ - public double asDouble(MatroskaElement element) throws IOException { - if (element.is(MatroskaElementType.DataType.FLOAT)) { - if (element.dataSize == 4) { - return dataInput.readFloat(); - } else if (element.dataSize == 8) { - return dataInput.readDouble(); - } else { - throw new IllegalStateException("Float element has invalid size."); - } - } else { - throw new IllegalArgumentException("Not a float element."); - } - } - - /** - * @param element Element to read from - * @return The contents of the element as a string - * @throws IOException On read error - */ - public String asString(MatroskaElement element) throws IOException { - if (element.is(MatroskaElementType.DataType.STRING)) { - return new String(asBytes(element), StandardCharsets.US_ASCII); - } else if (element.is(MatroskaElementType.DataType.UTF8_STRING)) { - return new String(asBytes(element), StandardCharsets.UTF_8); - } else { - throw new IllegalArgumentException("Not a string element."); - } - } - - /** - * @param element Element to read from - * @return The contents of the element as a byte array - * @throws IOException On read error - */ - public byte[] asBytes(MatroskaElement element) throws IOException { - byte[] bytes = new byte[element.dataSize]; - dataInput.readFully(bytes); - return bytes; - } - - /** - * @param element Element to skip over - * @throws IOException On read error - */ - public void skip(MatroskaElement element) throws IOException { - long remaining = element.getRemaining(inputStream.getPosition()); - - if (remaining > 0) { - inputStream.skipFully(remaining); - } else if (remaining < 0) { - throw new IllegalStateException("Current position is beyond this element"); - } - } - - /** - * @return Returns the current absolute position of the file. - */ - public long getPosition() { - return inputStream.getPosition(); - } - - /** - * Seeks to the specified position. - * - * @param position The position in bytes. - * @throws IOException On read error - */ - public void seek(long position) throws IOException { - inputStream.seek(position); - } - - public DataInput getDataInput() { - return dataInput; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaFileTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaFileTrack.java deleted file mode 100644 index d74c0bd..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaFileTrack.java +++ /dev/null @@ -1,207 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska.format; - -import java.io.IOException; - -/** - * Describes one track in a matroska file. - */ -public class MatroskaFileTrack { - /** - * Track index/number. - */ - public final int index; - /** - * Type of the track. - */ - public final Type type; - /** - * The unique track UID. - */ - public final long trackUid; - /** - * Name of the track. - */ - public final String name; - /** - * ID of the codec. - */ - public final String codecId; - /** - * Custom data for the codec (header). - */ - public final byte[] codecPrivate; - /** - * Information specific to audio tracks (null for non-audio tracks). - */ - public final AudioDetails audio; - - /** - * @param index Track index/number. - * @param type Type of the track. - * @param trackUid The unique track UID. - * @param name Name of the track. - * @param codecId ID of the codec. - * @param codecPrivate Custom data for the codec (header). - * @param audio Information specific to audio tracks (null for non-audio tracks). - */ - public MatroskaFileTrack(int index, Type type, long trackUid, String name, String codecId, byte[] codecPrivate, AudioDetails audio) { - this.index = index; - this.type = type; - this.trackUid = trackUid; - this.name = name; - this.codecId = codecId; - this.codecPrivate = codecPrivate; - this.audio = audio; - } - - /** - * Track type list. - */ - public enum Type { - VIDEO(1), - AUDIO(2), - COMPLEX(3), - LOGO(0x10), - SUBTITLE(0x11), - BUTTONS(0x12), - CONTROL(0x20); - - /** - * ID which is used in the track type field in the file. - */ - public final long id; - - Type(long id) { - this.id = id; - } - - /** - * @param id ID to look up. - * @return Track type for that ID, null if not found. - */ - public static Type fromId(long id) { - for (Type entry : Type.class.getEnumConstants()) { - if (entry.id == id) { - return entry; - } - } - - return null; - } - } - - /** - * Fields specific to an audio track. - */ - public static class AudioDetails { - /** - * Sampling frequency in Hz. - */ - public final float samplingFrequency; - /** - * Real output sampling frequency in Hz. - */ - public final float outputSamplingFrequency; - /** - * Number of channels in the track. - */ - public final int channels; - /** - * Number of bits per sample. - */ - public final int bitDepth; - - /** - * @param samplingFrequency Sampling frequency in Hz. - * @param outputSamplingFrequency Real output sampling frequency in Hz. - * @param channels Number of channels in the track. - * @param bitDepth Number of bits per sample. - */ - public AudioDetails(float samplingFrequency, float outputSamplingFrequency, int channels, int bitDepth) { - this.samplingFrequency = samplingFrequency; - this.outputSamplingFrequency = outputSamplingFrequency; - this.channels = channels; - this.bitDepth = bitDepth; - } - } - - /** - * @param trackElement The track element - * @param reader Matroska file reader - * @return The parsed track - * @throws IOException On read error - */ - public static MatroskaFileTrack parse(MatroskaElement trackElement, MatroskaFileReader reader) throws IOException { - Builder builder = new Builder(); - MatroskaElement child; - - while ((child = reader.readNextElement(trackElement)) != null) { - if (child.is(MatroskaElementType.TrackNumber)) { - builder.index = reader.asInteger(child); - } else if (child.is(MatroskaElementType.TrackUid)) { - builder.trackUid = reader.asLong(child); - } else if (child.is(MatroskaElementType.TrackType)) { - builder.type = Type.fromId(reader.asInteger(child)); - } else if (child.is(MatroskaElementType.Name)) { - builder.name = reader.asString(child); - } else if (child.is(MatroskaElementType.CodecId)) { - builder.codecId = reader.asString(child); - } else if (child.is(MatroskaElementType.CodecPrivate)) { - builder.codecPrivate = reader.asBytes(child); - } else if (child.is(MatroskaElementType.Audio)) { - builder.audio = parseAudioElement(child, reader); - } - - // Unused fields: DefaultDuration, Language, Video, etc - reader.skip(child); - } - - return builder.build(); - } - - private static AudioDetails parseAudioElement(MatroskaElement audioElement, MatroskaFileReader reader) throws IOException { - AudioBuilder builder = new AudioBuilder(); - MatroskaElement child; - - while ((child = reader.readNextElement(audioElement)) != null) { - if (child.is(MatroskaElementType.SamplingFrequency)) { - builder.samplingFrequency = reader.asFloat(child); - } else if (child.is(MatroskaElementType.OutputSamplingFrequency)) { - builder.outputSamplingFrequency = reader.asFloat(child); - } else if (child.is(MatroskaElementType.Channels)) { - builder.channels = reader.asInteger(child); - } else if (child.is(MatroskaElementType.BitDepth)) { - builder.bitDepth = reader.asInteger(child); - } - - reader.skip(child); - } - - return builder.build(); - } - - private static class Builder { - private int index; - private Type type; - private long trackUid; - private String name; - private String codecId; - private byte[] codecPrivate; - private AudioDetails audio; - - private MatroskaFileTrack build() { - return new MatroskaFileTrack(index, type, trackUid, name, codecId, codecPrivate, audio); - } - } - - private static class AudioBuilder { - private float samplingFrequency; - private float outputSamplingFrequency; - private int channels; - private int bitDepth; - - private AudioDetails build() { - return new AudioDetails(samplingFrequency, outputSamplingFrequency, channels, bitDepth); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MutableMatroskaBlock.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MutableMatroskaBlock.java deleted file mode 100644 index 4a85fd0..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MutableMatroskaBlock.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska.format; - -import java.io.DataInput; -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * An implementation of {@link MatroskaBlock} which can be reused by loading the next block into it by calling - * {@link #parseHeader(MatroskaFileReader, MatroskaElement, int)}. Does not reallocate any objects unless it encounters - * a block with more than twice as many frames as seen before, or a frame more than twice as long as before. - */ -public class MutableMatroskaBlock implements MatroskaBlock { - private int timecode; - private int trackNumber; - private boolean keyFrame; - private int[] frameSizes; - private int frameCount; - private ByteBuffer buffer; - private byte[] bufferArray; - - @Override - public int getTimecode() { - return timecode; - } - - @Override - public int getTrackNumber() { - return trackNumber; - } - - @Override - public boolean isKeyFrame() { - return keyFrame; - } - - @Override - public int getFrameCount() { - return frameCount; - } - - @Override - public ByteBuffer getNextFrameBuffer(MatroskaFileReader reader, int index) throws IOException { - if (index >= frameCount) { - throw new IllegalArgumentException("Frame index out of bounds."); - } - - int frameSize = frameSizes[index]; - - if (buffer == null || frameSize > buffer.capacity()) { - buffer = ByteBuffer.allocate(frameSizes[index] * 2); - bufferArray = buffer.array(); - } - - reader.getDataInput().readFully(bufferArray, 0, frameSize); - - buffer.position(0); - buffer.limit(frameSize); - return buffer; - } - - /** - * Parses the Matroska block header data into the fields of this instance. On success of this method, this instance - * effectively represents that block. - * - * @param reader The reader to use. - * @param element The block EBML element. - * @param trackFilter The ID of the track to read data for from the block. - * @return true of a block if it contains data for the requested track, false otherwise. - * @throws IOException On read error. - */ - public boolean parseHeader(MatroskaFileReader reader, MatroskaElement element, int trackFilter) throws IOException { - DataInput input = reader.getDataInput(); - trackNumber = (int) MatroskaEbmlReader.readEbmlInteger(input, null); - - if (trackFilter >= 0 && trackNumber != trackFilter) { - return false; - } - - timecode = input.readShort(); - - int flags = input.readByte() & 0xFF; - keyFrame = (flags & 0x80) != 0; - - int laceType = (flags & 0x06) >> 1; - - if (laceType != 0) { - setFrameCount((input.readByte() & 0xFF) + 1); - parseLacing(reader, element, laceType); - } else { - setFrameCount(1); - frameSizes[0] = (int) element.getRemaining(reader.getPosition()); - } - - return true; - } - - private void parseLacing(MatroskaFileReader reader, MatroskaElement element, int laceType) throws IOException { - setFrameCount(frameCount); - - switch (laceType) { - case 1: - parseXiphLaceSizes(reader, element); - break; - case 2: - parseFixedLaceSizes(reader, element); - break; - case 3: - default: - parseEbmlLaceSizes(reader, element); - } - } - - private void setFrameCount(int frameCount) { - if (frameSizes == null || frameSizes.length < frameCount) { - frameSizes = new int[frameCount * 2]; - } - - this.frameCount = frameCount; - } - - private void parseXiphLaceSizes(MatroskaFileReader reader, MatroskaElement element) throws IOException { - int sizeTotal = 0; - DataInput input = reader.getDataInput(); - - for (int i = 0; i < frameCount - 1; i++) { - int value; - - do { - value = input.readByte() & 0xFF; - frameSizes[i] += value; - } while (value == 255); - - sizeTotal += frameSizes[i]; - } - - frameSizes[frameCount - 1] = (int) element.getRemaining(reader.getPosition()) - sizeTotal; - } - - private void parseFixedLaceSizes(MatroskaFileReader reader, MatroskaElement element) { - int size = (int) element.getRemaining(reader.getPosition()) / frameCount; - - for (int i = 0; i < frameCount; i++) { - frameSizes[i] = size; - } - } - - private void parseEbmlLaceSizes(MatroskaFileReader reader, MatroskaElement element) throws IOException { - DataInput input = reader.getDataInput(); - - frameSizes[0] = (int) MatroskaEbmlReader.readEbmlInteger(input, null); - int sizeTotal = frameSizes[0]; - - for (int i = 1; i < frameCount - 1; i++) { - frameSizes[i] = frameSizes[i - 1] + (int) MatroskaEbmlReader.readEbmlInteger(input, MatroskaEbmlReader.Type.LACE_SIGNED); - sizeTotal += frameSizes[i]; - } - - frameSizes[frameCount - 1] = (int) element.getRemaining(reader.getPosition()) - sizeTotal; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MutableMatroskaElement.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MutableMatroskaElement.java deleted file mode 100644 index 42b97fa..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MutableMatroskaElement.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.matroska.format; - -/** - * Mutable instance of {@link MatroskaElement} for reducing allocation rate during parsing. - */ -public class MutableMatroskaElement extends MatroskaElement { - protected MutableMatroskaElement(int level) { - super(level); - } - - public void setId(long id) { - this.id = id; - } - - public void setType(MatroskaElementType type) { - this.type = type; - } - - public void setPosition(long position) { - this.position = position; - } - - public void setHeaderSize(int headerSize) { - this.headerSize = headerSize; - } - - public void setDataSize(int dataSize) { - this.dataSize = dataSize; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3AudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3AudioTrack.java deleted file mode 100644 index a687d87..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3AudioTrack.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mp3; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.BaseAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Audio track that handles an MP3 stream - */ -public class Mp3AudioTrack extends BaseAudioTrack { - private static final Logger log = LoggerFactory.getLogger(Mp3AudioTrack.class); - - private final SeekableInputStream inputStream; - - /** - * @param trackInfo Track info - * @param inputStream Input stream for the MP3 file - */ - public Mp3AudioTrack(AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - super(trackInfo); - - this.inputStream = inputStream; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - Mp3TrackProvider provider = new Mp3TrackProvider(localExecutor.getProcessingContext(), inputStream); - - try { - provider.parseHeaders(); - - log.debug("Starting to play MP3 track {}", getIdentifier()); - localExecutor.executeProcessingLoop(provider::provideFrames, provider::seekToTimecode); - } finally { - provider.close(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3ConstantRateSeeker.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3ConstantRateSeeker.java deleted file mode 100644 index 5c262c5..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3ConstantRateSeeker.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mp3; - -import com.sedmelluq.discord.lavaplayer.natives.mp3.Mp3Decoder; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; - -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.natives.mp3.Mp3Decoder.MPEG1_SAMPLES_PER_FRAME; - -/** - * MP3 seeking support for constant bitrate files or in cases where the variable bitrate format used by the file is not - * supported. In case the file is not actually CBR, this being used as a fallback may cause inaccurate seeking. - */ -public class Mp3ConstantRateSeeker implements Mp3Seeker { - private static final int META_TAG_OFFSET = 36; - private static final byte[][] META_TAGS = new byte[][]{ - new byte[]{'I', 'n', 'f', 'o'}, - new byte[]{'L', 'A', 'M', 'E'} - }; - - private final double averageFrameSize; - private final int sampleRate; - private final long firstFramePosition; - private final long contentLength; - - private Mp3ConstantRateSeeker(double averageFrameSize, int sampleRate, long firstFramePosition, long contentLength) { - this.averageFrameSize = averageFrameSize; - this.sampleRate = sampleRate; - this.firstFramePosition = firstFramePosition; - this.contentLength = contentLength; - } - - /** - * @param firstFramePosition Position of the first frame in the file - * @param contentLength Total length of the file - * @param frameBuffer Buffer of the first frame - * @return Constant rate seeker, will always succeed, never null. - */ - public static Mp3ConstantRateSeeker createFromFrame(long firstFramePosition, long contentLength, byte[] frameBuffer) { - int sampleRate = Mp3Decoder.getFrameSampleRate(frameBuffer, 0); - double averageFrameSize = Mp3Decoder.getAverageFrameSize(frameBuffer, 0); - - return new Mp3ConstantRateSeeker(averageFrameSize, sampleRate, firstFramePosition, contentLength); - } - - public static boolean isMetaFrame(byte[] frameBuffer) { - for (byte[] metaTag : META_TAGS) { - if (DataFormatTools.arrayRangeEquals(frameBuffer, META_TAG_OFFSET, metaTag)) { - return true; - } - } - - return false; - } - - @Override - public long getDuration() { - return getMaximumFrameCount() * MPEG1_SAMPLES_PER_FRAME * 1000 / sampleRate; - } - - @Override - public boolean isSeekable() { - return true; - } - - @Override - public long seekAndGetFrameIndex(long timecode, SeekableInputStream inputStream) throws IOException { - long maximumFrameCount = getMaximumFrameCount(); - - long sampleIndex = timecode * sampleRate / 1000; - long frameIndex = Math.min(sampleIndex / MPEG1_SAMPLES_PER_FRAME, maximumFrameCount); - - long seekPosition = (long) (frameIndex * averageFrameSize) - 8; - inputStream.seek(firstFramePosition + seekPosition); - - return frameIndex; - } - - private long getMaximumFrameCount() { - return (long) ((contentLength - firstFramePosition + 8) / averageFrameSize); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3ContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3ContainerProbe.java deleted file mode 100644 index 494c2c1..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3ContainerProbe.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mp3; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.STREAM_SCAN_DISTANCE; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.checkNextBytes; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.supportedFormat; - -/** - * Container detection probe for MP3 format. - */ -public class Mp3ContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(Mp3ContainerProbe.class); - - private static final int[] ID3_TAG = new int[]{0x49, 0x44, 0x33}; - - @Override - public String getName() { - return "mp3"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - boolean invalidMimeType = hints.mimeType != null && !"audio/mpeg".equalsIgnoreCase(hints.mimeType); - boolean invalidFileExtension = hints.fileExtension != null && !"mp3".equalsIgnoreCase(hints.fileExtension); - return hints.present() && !invalidMimeType && !invalidFileExtension; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException { - if (!checkNextBytes(inputStream, ID3_TAG)) { - byte[] frameHeader = new byte[4]; - Mp3FrameReader frameReader = new Mp3FrameReader(inputStream, frameHeader); - if (!frameReader.scanForFrame(STREAM_SCAN_DISTANCE, false)) { - return null; - } - - inputStream.seek(0); - } - - log.debug("Track {} is an MP3 file.", reference.identifier); - - Mp3TrackProvider file = new Mp3TrackProvider(null, inputStream); - - try { - file.parseHeaders(); - - return supportedFormat(this, null, AudioTrackInfoBuilder.create(reference, inputStream) - .apply(file).setIsStream(!file.isSeekable()).build()); - } finally { - file.close(); - } - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - return new Mp3AudioTrack(trackInfo, inputStream); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3FrameReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3FrameReader.java deleted file mode 100644 index 8ecfab6..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3FrameReader.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mp3; - -import com.sedmelluq.discord.lavaplayer.natives.mp3.Mp3Decoder; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.natives.mp3.Mp3Decoder.HEADER_SIZE; - -/** - * Handles reading MP3 frames from a stream. - */ -public class Mp3FrameReader { - private final SeekableInputStream inputStream; - private final DataInput dataInput; - private final byte[] scanBuffer; - private final byte[] frameBuffer; - private int frameSize; - private int frameBufferPosition; - private int scanBufferPosition; - private boolean frameHeaderRead; - - /** - * @param inputStream Input buffer to read from - * @param frameBuffer Array to store the frame data in - */ - public Mp3FrameReader(SeekableInputStream inputStream, byte[] frameBuffer) { - this.inputStream = inputStream; - this.dataInput = new DataInputStream(inputStream); - this.scanBuffer = new byte[16]; - this.frameBuffer = frameBuffer; - } - - /** - * @param bytesToCheck The maximum number of bytes to check before throwing an IllegalStateException - * @param throwOnLimit Whether to throw an exception when maximum number of bytes is reached, but no frame has been - * found and EOF has not been reached. - * @return True if a frame was found, false if EOF was encountered. - * @throws IOException On IO error - * @throws IllegalStateException If the maximum number of bytes to check was reached before a frame was found - */ - public boolean scanForFrame(int bytesToCheck, boolean throwOnLimit) throws IOException { - int bytesInBuffer = scanBufferPosition; - scanBufferPosition = 0; - - if (parseFrameAt(bytesInBuffer)) { - frameHeaderRead = true; - return true; - } - - return runFrameScanLoop(bytesToCheck - bytesInBuffer, bytesInBuffer, throwOnLimit); - } - - private boolean runFrameScanLoop(int bytesToCheck, int bytesInBuffer, boolean throwOnLimit) throws IOException { - while (bytesToCheck > 0) { - for (int i = bytesInBuffer; i < scanBuffer.length && bytesToCheck > 0; i++, bytesToCheck--) { - int next = inputStream.read(); - if (next == -1) { - return false; - } - - scanBuffer[i] = (byte) (next & 0xFF); - - if (parseFrameAt(i + 1)) { - frameHeaderRead = true; - return true; - } - } - - bytesInBuffer = copyScanBufferEndToBeginning(); - } - - if (throwOnLimit) { - throw new IllegalStateException("Mp3 frame not found."); - } - - return false; - } - - private int copyScanBufferEndToBeginning() { - for (int i = 0; i < HEADER_SIZE - 1; i++) { - scanBuffer[i] = scanBuffer[scanBuffer.length - HEADER_SIZE + i + 1]; - } - - return HEADER_SIZE - 1; - } - - private boolean parseFrameAt(int scanOffset) { - if (scanOffset >= HEADER_SIZE && (frameSize = Mp3Decoder.getFrameSize(scanBuffer, scanOffset - HEADER_SIZE)) > 0) { - for (int i = 0; i < HEADER_SIZE; i++) { - frameBuffer[i] = scanBuffer[scanOffset - HEADER_SIZE + i]; - } - - frameBufferPosition = HEADER_SIZE; - return true; - } - - return false; - } - - /** - * Fills the buffer for the current frame. If no frame header has been read previously, it will first scan for the - * sync bytes of the next frame in the stream. - * - * @return False if EOF was encountered while looking for the next frame, true otherwise - * @throws IOException On IO error - */ - public boolean fillFrameBuffer() throws IOException { - if (!frameHeaderRead && !scanForFrame(Integer.MAX_VALUE, true)) { - return false; - } - - dataInput.readFully(frameBuffer, frameBufferPosition, frameSize - frameBufferPosition); - frameBufferPosition = frameSize; - return true; - } - - /** - * Forget the current frame and make next calls look for the next frame. - */ - public void nextFrame() { - frameHeaderRead = false; - frameBufferPosition = 0; - } - - /** - * @return The start position of the current frame in the stream. - */ - public long getFrameStartPosition() { - return inputStream.getPosition() - frameBufferPosition; - } - - /** - * @return Size of the current frame in bytes. - */ - public int getFrameSize() { - return frameSize; - } - - /** - * Append some bytes to the frame sync scan buffer. This must be called when some bytes have been read externally that - * may actually be part of the next frame header. - * - * @param data The buffer to copy from - * @param offset The offset in the buffer - * @param length The length of the region to copy - */ - public void appendToScanBuffer(byte[] data, int offset, int length) { - System.arraycopy(data, offset, scanBuffer, 0, length); - scanBufferPosition = length; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3Seeker.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3Seeker.java deleted file mode 100644 index b2f49d7..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3Seeker.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mp3; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; - -import java.io.IOException; - -/** - * A seeking handler for MP3 files. - */ -public interface Mp3Seeker { - /** - * @return The duration of the file in milliseconds. May be an estimate. - */ - long getDuration(); - - /** - * @return True if the track is seekable. - */ - boolean isSeekable(); - - /** - * @param timecode The timecode that the seek is requested to - * @param inputStream The input stream to perform the seek on - * @return The index of the frame that the seek was performed to - * @throws IOException On IO error - */ - long seekAndGetFrameIndex(long timecode, SeekableInputStream inputStream) throws IOException; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3StreamSeeker.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3StreamSeeker.java deleted file mode 100644 index ef3a1b5..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3StreamSeeker.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mp3; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; - -import java.io.IOException; - -/** - * Seeker for an MP3 stream, which actually does not allow seeking and reports Long.MAX_VALUE as duration. - */ -public class Mp3StreamSeeker implements Mp3Seeker { - @Override - public long getDuration() { - return Long.MAX_VALUE; - } - - @Override - public boolean isSeekable() { - return false; - } - - @Override - public long seekAndGetFrameIndex(long timecode, SeekableInputStream inputStream) throws IOException { - throw new UnsupportedOperationException("Cannot seek on a stream."); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3TrackProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3TrackProvider.java deleted file mode 100644 index e3c5897..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3TrackProvider.java +++ /dev/null @@ -1,395 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mp3; - -import com.sedmelluq.discord.lavaplayer.filter.AudioPipeline; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipelineFactory; -import com.sedmelluq.discord.lavaplayer.filter.PcmFormat; -import com.sedmelluq.discord.lavaplayer.natives.mp3.Mp3Decoder; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoProvider; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static com.sedmelluq.discord.lavaplayer.natives.mp3.Mp3Decoder.MPEG1_SAMPLES_PER_FRAME; - -/** - * Handles parsing MP3 files, seeking and sending the decoded frames to the specified frame consumer. - */ -public class Mp3TrackProvider implements AudioTrackInfoProvider { - private static final byte[] IDV3_TAG = new byte[]{0x49, 0x44, 0x33}; - private static final int IDV3_FLAG_EXTENDED = 0x40; - - private static final String TITLE_TAG = "TIT2"; - private static final String ARTIST_TAG = "TPE1"; - - private static final List knownTextExtensions = Arrays.asList(TITLE_TAG, ARTIST_TAG); - - private final AudioProcessingContext context; - private final SeekableInputStream inputStream; - private final DataInputStream dataInput; - private final Mp3Decoder mp3Decoder; - private final ShortBuffer outputBuffer; - private final ByteBuffer inputBuffer; - private final byte[] frameBuffer; - private final byte[] tagHeaderBuffer; - private final Mp3FrameReader frameReader; - private final Map tags; - - private int sampleRate; - private int channelCount; - private AudioPipeline downstream; - private Mp3Seeker seeker; - - /** - * @param context Configuration and output information for processing. May be null in case no frames are read and this - * instance is only used to retrieve information about the track. - * @param inputStream Stream to read the file from - */ - public Mp3TrackProvider(AudioProcessingContext context, SeekableInputStream inputStream) { - this.context = context; - this.inputStream = inputStream; - this.dataInput = new DataInputStream(inputStream); - this.outputBuffer = ByteBuffer.allocateDirect((int) MPEG1_SAMPLES_PER_FRAME * 4).order(ByteOrder.nativeOrder()).asShortBuffer(); - this.inputBuffer = ByteBuffer.allocateDirect(Mp3Decoder.getMaximumFrameSize()); - this.frameBuffer = new byte[Mp3Decoder.getMaximumFrameSize()]; - this.tagHeaderBuffer = new byte[4]; - this.frameReader = new Mp3FrameReader(inputStream, frameBuffer); - this.mp3Decoder = new Mp3Decoder(); - this.tags = new HashMap<>(); - } - - /** - * Parses file headers to find the first MP3 frame and to get the settings for initialising the filter chain. - * - * @throws IOException On read error - */ - public void parseHeaders() throws IOException { - skipIdv3Tags(); - - if (!frameReader.scanForFrame(2048, true)) { - throw new IllegalStateException("File ended before the first frame was found."); - } - - sampleRate = Mp3Decoder.getFrameSampleRate(frameBuffer, 0); - channelCount = Mp3Decoder.getFrameChannelCount(frameBuffer, 0); - downstream = context != null ? AudioPipelineFactory.create(context, new PcmFormat(channelCount, sampleRate)) : null; - - initialiseSeeker(); - } - - private void initialiseSeeker() throws IOException { - long startPosition = frameReader.getFrameStartPosition(); - frameReader.fillFrameBuffer(); - - seeker = Mp3XingSeeker.createFromFrame(startPosition, inputStream.getContentLength(), frameBuffer); - - if (seeker == null) { - if (inputStream.getContentLength() == Long.MAX_VALUE) { - seeker = new Mp3StreamSeeker(); - } else { - if (context == null) { - // Skip meta frames if this provider is created only for reading metadata. - for (int i = 0; Mp3ConstantRateSeeker.isMetaFrame(frameBuffer) && i < 2; i++) { - frameReader.nextFrame(); - frameReader.fillFrameBuffer(); - } - } - - seeker = Mp3ConstantRateSeeker.createFromFrame(startPosition, inputStream.getContentLength(), frameBuffer); - } - } - } - - /** - * Decodes audio frames and sends them to frame consumer - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - public void provideFrames() throws InterruptedException { - try { - while (true) { - if (!frameReader.fillFrameBuffer()) { - break; - } - - inputBuffer.clear(); - inputBuffer.put(frameBuffer, 0, frameReader.getFrameSize()); - inputBuffer.flip(); - - outputBuffer.clear(); - outputBuffer.limit(channelCount * (int) Mp3Decoder.getSamplesPerFrame(frameBuffer, 0)); - - int produced = mp3Decoder.decode(inputBuffer, outputBuffer); - - if (produced > 0) { - downstream.process(outputBuffer); - } - - frameReader.nextFrame(); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Seeks to the specified timecode. - * - * @param timecode The timecode in milliseconds - */ - public void seekToTimecode(long timecode) { - try { - long frameIndex = seeker.seekAndGetFrameIndex(timecode, inputStream); - long actualTimecode = frameIndex * MPEG1_SAMPLES_PER_FRAME * 1000 / sampleRate; - downstream.seekPerformed(timecode, actualTimecode); - - frameReader.nextFrame(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * @return True if the track is seekable (false for streams for example). - */ - public boolean isSeekable() { - return seeker.isSeekable(); - } - - /** - * @return An estimated duration of the file in milliseconds - */ - public long getDuration() { - return seeker.getDuration(); - } - - /** - * Gets an ID3 tag. These are loaded when parsing headers and only for a fixed list of tags. - * - * @param tagId The FourCC of the tag - * @return The value of the tag if present, otherwise null - */ - public String getIdv3Tag(String tagId) { - return tags.get(tagId); - } - - /** - * Closes resources. - */ - public void close() { - if (downstream != null) { - downstream.close(); - } - - mp3Decoder.close(); - } - - private void skipIdv3Tags() throws IOException { - dataInput.readFully(tagHeaderBuffer, 0, 3); - - for (int i = 0; i < 3; i++) { - if (tagHeaderBuffer[i] != IDV3_TAG[i]) { - frameReader.appendToScanBuffer(tagHeaderBuffer, 0, 3); - return; - } - } - - int majorVersion = dataInput.readByte() & 0xFF; - // Minor version - dataInput.readByte(); - - if (majorVersion < 2 || majorVersion > 5) { - return; - } - - int flags = dataInput.readByte() & 0xFF; - int tagsSize = readSyncProofInteger(); - - long tagsEndPosition = inputStream.getPosition() + tagsSize; - - skipExtendedHeader(flags); - - if (majorVersion < 5) { - parseIdv3Frames(majorVersion, tagsEndPosition); - } - - inputStream.seek(tagsEndPosition); - } - - private int readSyncProofInteger() throws IOException { - return (dataInput.readByte() & 0xFF) << 21 - | (dataInput.readByte() & 0xFF) << 14 - | (dataInput.readByte() & 0xFF) << 7 - | (dataInput.readByte() & 0xFF); - } - - private int readSyncProof3ByteInteger() throws IOException { - return (dataInput.readByte() & 0xFF) << 14 - | (dataInput.readByte() & 0xFF) << 7 - | (dataInput.readByte() & 0xFF); - } - - private void skipExtendedHeader(int flags) throws IOException { - if ((flags & IDV3_FLAG_EXTENDED) != 0) { - int size = readSyncProofInteger(); - - inputStream.seek(inputStream.getPosition() + size - 4); - } - } - - private void parseIdv3Frames(int version, long tagsEndPosition) throws IOException { - FrameHeader header; - - while (inputStream.getPosition() + 10 <= tagsEndPosition && (header = readFrameHeader(version)) != null) { - long nextTagPosition = inputStream.getPosition() + header.size; - - if (header.hasRawFormat() && knownTextExtensions.contains(header.id)) { - String text = parseIdv3TextContent(header.size); - - if (text != null) { - tags.put(header.id, text); - } - } - - inputStream.seek(nextTagPosition); - } - } - - private String parseIdv3TextContent(int size) throws IOException { - int encoding = dataInput.readByte() & 0xFF; - - byte[] data = new byte[size - 1]; - dataInput.readFully(data); - - boolean shortTerminator = data.length > 0 && data[data.length - 1] == 0; - boolean wideTerminator = data.length > 1 && data[data.length - 2] == 0 && shortTerminator; - - switch (encoding) { - case 0: - return new String(data, 0, size - (shortTerminator ? 2 : 1), "ISO-8859-1"); - case 1: - return new String(data, 0, size - (wideTerminator ? 3 : 1), "UTF-16"); - case 2: - return new String(data, 0, size - (wideTerminator ? 3 : 1), "UTF-16BE"); - case 3: - return new String(data, 0, size - (shortTerminator ? 2 : 1), "UTF-8"); - default: - return null; - } - } - - private String readId3v22TagName() throws IOException { - dataInput.readFully(tagHeaderBuffer, 0, 3); - - if (tagHeaderBuffer[0] == 0) { - return null; - } - - String shortName = new String(tagHeaderBuffer, 0, 3, StandardCharsets.ISO_8859_1); - - if ("TT2".equals(shortName)) { - return "TIT2"; - } else if ("TP1".equals(shortName)) { - return "TPE1"; - } else { - return shortName; - } - } - - private String readTagName() throws IOException { - dataInput.readFully(tagHeaderBuffer, 0, 4); - - if (tagHeaderBuffer[0] == 0) { - return null; - } - - return new String(tagHeaderBuffer, 0, 4, StandardCharsets.ISO_8859_1); - } - - private FrameHeader readFrameHeader(int version) throws IOException { - if (version == 2) { - String tagName = readId3v22TagName(); - - if (tagName != null) { - return new FrameHeader(tagName, readSyncProof3ByteInteger(), 0); - } - } else { - String tagName = readTagName(); - - if (tagName != null) { - int size = version == 3 ? dataInput.readInt() : readSyncProofInteger(); - return new FrameHeader(tagName, size, dataInput.readUnsignedShort()); - } - } - - return null; - } - - @Override - public String getTitle() { - return getIdv3Tag(TITLE_TAG); - } - - @Override - public String getAuthor() { - return getIdv3Tag(ARTIST_TAG); - } - - @Override - public Long getLength() { - return getDuration(); - } - - @Override - public String getIdentifier() { - return null; - } - - @Override - public String getUri() { - return null; - } - - private static class FrameHeader { - private final String id; - private final int size; - @SuppressWarnings("unused") - private final boolean tagAlterPreservation; - @SuppressWarnings("unused") - private final boolean fileAlterPreservation; - @SuppressWarnings("unused") - private final boolean readOnly; - @SuppressWarnings("unused") - private final boolean groupingIdentity; - private final boolean compression; - private final boolean encryption; - private final boolean unsynchronization; - private final boolean dataLengthIndicator; - - private FrameHeader(String id, int size, int flags) { - this.id = id; - this.size = size; - this.tagAlterPreservation = (flags & 0x4000) != 0; - this.fileAlterPreservation = (flags & 0x2000) != 0; - this.readOnly = (flags & 0x1000) != 0; - this.groupingIdentity = (flags & 0x0040) != 0; - this.compression = (flags & 0x0008) != 0; - this.encryption = (flags & 0x0004) != 0; - this.unsynchronization = (flags & 0x0002) != 0; - this.dataLengthIndicator = (flags & 0x0001) != 0; - } - - private boolean hasRawFormat() { - return !compression && !encryption && !unsynchronization && !dataLengthIndicator; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3XingSeeker.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3XingSeeker.java deleted file mode 100644 index aaa3c25..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mp3/Mp3XingSeeker.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mp3; - -import com.sedmelluq.discord.lavaplayer.natives.mp3.Mp3Decoder; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import static com.sedmelluq.discord.lavaplayer.natives.mp3.Mp3Decoder.MPEG1_SAMPLES_PER_FRAME; - -/** - * Seeking support for VBR files with Xing header. - */ -public class Mp3XingSeeker implements Mp3Seeker { - private static final Logger log = LoggerFactory.getLogger(Mp3XingSeeker.class); - - private static final int XING_OFFSET = 36; - private static final int ALL_FLAGS = 0x7; - private static final ByteBuffer xingTagBuffer = ByteBuffer.wrap(new byte[]{0x58, 0x69, 0x6E, 0x67}); - - private final long firstFramePosition; - private final long contentLength; - private final long frameCount; - private final long dataSize; - private final byte[] seekMapping; - private final long duration; - - private Mp3XingSeeker(int sampleRate, long firstFramePosition, long contentLength, long frameCount, long dataSize, byte[] seekMapping) { - this.firstFramePosition = firstFramePosition; - this.contentLength = contentLength; - this.frameCount = frameCount; - this.dataSize = dataSize; - this.seekMapping = seekMapping; - this.duration = frameCount * MPEG1_SAMPLES_PER_FRAME * 1000L / sampleRate; - } - - /** - * @param firstFramePosition Position of the first frame in the file - * @param contentLength Total length of the file - * @param frameBuffer Buffer of the first frame - * @return Xing seeker, if its header is found in the first frame and has all the necessary fields - */ - public static Mp3XingSeeker createFromFrame(long firstFramePosition, long contentLength, byte[] frameBuffer) { - ByteBuffer frame = ByteBuffer.wrap(frameBuffer); - - if (frame.getInt(XING_OFFSET) != xingTagBuffer.getInt(0)) { - return null; - } else if ((frame.getInt(XING_OFFSET + 4) & ALL_FLAGS) != ALL_FLAGS) { - log.debug("Xing tag is present, but is missing some required fields."); - return null; - } - - int sampleRate = Mp3Decoder.getFrameSampleRate(frameBuffer, 0); - long frameCount = frame.getInt(XING_OFFSET + 8); - long dataSize = frame.getInt(XING_OFFSET + 12); - - byte[] seekMapping = new byte[100]; - frame.position(XING_OFFSET + 16); - frame.get(seekMapping); - - return new Mp3XingSeeker(sampleRate, firstFramePosition, contentLength, frameCount, dataSize, seekMapping); - } - - @Override - public long getDuration() { - return duration; - } - - @Override - public boolean isSeekable() { - return true; - } - - @Override - public long seekAndGetFrameIndex(long timecode, SeekableInputStream inputStream) throws IOException { - int percentile = (int) (timecode * 100L / duration); - long frameIndex = frameCount * percentile / 100L; - - long seekPosition = Math.min(firstFramePosition + dataSize * (seekMapping[percentile] & 0xFF) / 256, contentLength); - inputStream.seek(seekPosition); - - return frameIndex; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegAacTrackConsumer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegAacTrackConsumer.java deleted file mode 100644 index bc0a4d5..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegAacTrackConsumer.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg; - -import com.sedmelluq.discord.lavaplayer.container.common.AacPacketRouter; -import com.sedmelluq.discord.lavaplayer.natives.aac.AacDecoder; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; -import org.apache.commons.io.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.ClosedByInterruptException; -import java.nio.channels.ReadableByteChannel; - -/** - * Handles processing MP4 AAC frames. Passes the decoded frames to the specified frame consumer. Currently only AAC LC - * format is supported, although the underlying decoder can handler other types as well. - */ -public class MpegAacTrackConsumer implements MpegTrackConsumer { - private static final Logger log = LoggerFactory.getLogger(MpegAacTrackConsumer.class); - - private final MpegTrackInfo track; - private final ByteBuffer inputBuffer; - private final AacPacketRouter packetRouter; - - /** - * @param context Configuration and output information for processing - * @param track The MP4 audio track descriptor - */ - public MpegAacTrackConsumer(AudioProcessingContext context, MpegTrackInfo track) { - this.track = track; - this.inputBuffer = ByteBuffer.allocateDirect(4096); - this.packetRouter = new AacPacketRouter(context, this::configureDecoder); - } - - @Override - public void initialise() { - log.debug("Initialising AAC track with expected frequency {} and channel count {}.", - track.sampleRate, track.channelCount); - } - - @Override - public MpegTrackInfo getTrack() { - return track; - } - - @Override - public void seekPerformed(long requestedTimecode, long providedTimecode) { - packetRouter.seekPerformed(requestedTimecode, providedTimecode); - } - - @Override - public void flush() throws InterruptedException { - packetRouter.flush(); - } - - @Override - public void consume(ReadableByteChannel channel, int length) throws InterruptedException { - int remaining = length; - - while (remaining > 0) { - int chunk = Math.min(remaining, inputBuffer.capacity()); - - inputBuffer.clear(); - inputBuffer.limit(chunk); - - try { - IOUtils.readFully(channel, inputBuffer); - } catch (ClosedByInterruptException e) { - log.trace("Interrupt received while reading channel", e); - - Thread.currentThread().interrupt(); - throw new InterruptedException(); - } catch (IOException e) { - throw new RuntimeException(e); - } - - inputBuffer.flip(); - packetRouter.processInput(inputBuffer); - - remaining -= chunk; - } - } - - @Override - public void close() { - packetRouter.close(); - } - - private void configureDecoder(AacDecoder decoder) { - decoder.configure(AacDecoder.AAC_LC, track.sampleRate, track.channelCount); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegAudioTrack.java deleted file mode 100644 index 172847b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegAudioTrack.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg; - -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.MpegFileTrackProvider; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.BaseAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.FAULT; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio track that handles the processing of MP4 format - */ -public class MpegAudioTrack extends BaseAudioTrack { - private static final Logger log = LoggerFactory.getLogger(MpegAudioTrack.class); - - private final SeekableInputStream inputStream; - - /** - * @param trackInfo Track info - * @param inputStream Input stream for the MP4 file - */ - public MpegAudioTrack(AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - super(trackInfo); - - this.inputStream = inputStream; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) { - MpegFileLoader file = new MpegFileLoader(inputStream); - file.parseHeaders(); - - MpegTrackConsumer trackConsumer = loadAudioTrack(file, localExecutor.getProcessingContext()); - - try { - MpegFileTrackProvider fileReader = file.loadReader(trackConsumer); - if (fileReader == null) { - throw new FriendlyException("Unknown MP4 format.", SUSPICIOUS, null); - } - - accurateDuration.set(fileReader.getDuration()); - - localExecutor.executeProcessingLoop(fileReader::provideFrames, fileReader::seekToTimecode); - } finally { - trackConsumer.close(); - } - } - - protected MpegTrackConsumer loadAudioTrack(MpegFileLoader file, AudioProcessingContext context) { - MpegTrackConsumer trackConsumer = null; - boolean success = false; - - try { - trackConsumer = selectAudioTrack(file.getTrackList(), context); - - if (trackConsumer == null) { - throw new FriendlyException("The audio codec used in the track is not supported.", SUSPICIOUS, null); - } else { - log.debug("Starting to play track with codec {}", trackConsumer.getTrack().codecName); - } - - trackConsumer.initialise(); - success = true; - return trackConsumer; - } catch (Exception e) { - throw ExceptionTools.wrapUnfriendlyExceptions("Something went wrong when loading an MP4 format track.", FAULT, e); - } finally { - if (!success && trackConsumer != null) { - trackConsumer.close(); - } - } - } - - private MpegTrackConsumer selectAudioTrack(List tracks, AudioProcessingContext context) { - for (MpegTrackInfo track : tracks) { - if ("soun".equals(track.handler) && "mp4a".equals(track.codecName)) { - return new MpegAacTrackConsumer(context, track); - } - } - - return null; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegContainerProbe.java deleted file mode 100644 index a8ca3f0..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegContainerProbe.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.MpegFileTrackProvider; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.checkNextBytes; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.supportedFormat; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.unsupportedFormat; - -/** - * Container detection probe for MP4 format. - */ -public class MpegContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(MpegContainerProbe.class); - - private static final int[] ISO_TAG = new int[]{0x00, 0x00, 0x00, -1, 0x66, 0x74, 0x79, 0x70}; - - @Override - public String getName() { - return "mp4"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - return false; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException { - if (!checkNextBytes(inputStream, ISO_TAG)) { - return null; - } - - log.debug("Track {} is an MP4 file.", reference.identifier); - - MpegFileLoader file = new MpegFileLoader(inputStream); - file.parseHeaders(); - - MpegTrackInfo audioTrack = getSupportedAudioTrack(file); - - if (audioTrack == null) { - return unsupportedFormat(this, "No supported audio format in the MP4 file."); - } - - MpegTrackConsumer trackConsumer = new MpegNoopTrackConsumer(audioTrack); - MpegFileTrackProvider fileReader = file.loadReader(trackConsumer); - - if (fileReader == null) { - return unsupportedFormat(this, "MP4 file uses an unsupported format."); - } - - AudioTrackInfo trackInfo = AudioTrackInfoBuilder.create(reference, inputStream) - .setTitle(file.getTextMetadata("Title")) - .setAuthor(file.getTextMetadata("Artist")) - .setLength(fileReader.getDuration()) - .build(); - - return supportedFormat(this, null, trackInfo); - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - return new MpegAudioTrack(trackInfo, inputStream); - } - - private MpegTrackInfo getSupportedAudioTrack(MpegFileLoader file) { - for (MpegTrackInfo track : file.getTrackList()) { - if ("soun".equals(track.handler) && "mp4a".equals(track.codecName)) { - return track; - } - } - - return null; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegFileLoader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegFileLoader.java deleted file mode 100644 index e072bca..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegFileLoader.java +++ /dev/null @@ -1,232 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg; - -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.*; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.fragmented.MpegFragmentedFileTrackProvider; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.standard.MpegStandardFileTrackProvider; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Handles processing an MP4 file for the purpose of streaming one specific track from it. Only performs seeks when - * absolutely necessary, as the stream may be a network connection, in which case each seek may require a new connection. - */ -public class MpegFileLoader { - private final List tracks; - private final MpegFragmentedFileTrackProvider fragmentedFileReader; - private final MpegStandardFileTrackProvider standardFileReader; - private final MpegReader reader; - private final MpegSectionInfo root; - private final Map metadata; - private byte[] lastEventMessage; - - /** - * @param inputStream Stream to read the file from - */ - public MpegFileLoader(SeekableInputStream inputStream) { - this.tracks = new ArrayList<>(); - this.reader = new MpegReader(inputStream); - this.root = new MpegSectionInfo(0, inputStream.getContentLength(), "root"); - this.fragmentedFileReader = new MpegFragmentedFileTrackProvider(reader, root); - this.standardFileReader = new MpegStandardFileTrackProvider(reader); - this.metadata = new HashMap<>(); - } - - /** - * @return List of tracks found in the file - */ - public List getTrackList() { - return tracks; - } - - /** - * Read the headers of the file to get the list of tracks and data required for seeking. - */ - public void parseHeaders() { - try { - final AtomicBoolean movieBoxSeen = new AtomicBoolean(); - - reader.in(root).handle("moov", moov -> { - movieBoxSeen.set(true); - - reader.in(moov).handle("trak", - this::parseTrackInfo - ).handle("mvex", - fragmentedFileReader::parseMovieExtended - ).handle("udta", - this::parseMetadata - ).run(); - }).handleVersioned("emsg", - this::parseEventMessage - ).handleVersioned("sidx", true, - fragmentedFileReader::parseSegmentIndex - ).stopChecker(getRootStopChecker(movieBoxSeen)).run(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * @param name Name of the text metadata field. - * @return Value of the metadata field, or null if no value or not a string. - */ - public String getTextMetadata(String name) { - Object data = metadata.get(name); - return data instanceof String ? (String) data : null; - } - - /** - * @return Payload from the last emsg message encountered. - */ - public byte[] getLastEventMessage() { - return lastEventMessage; - } - - private void parseMetadata(MpegSectionInfo udta) throws IOException { - reader.in(udta).handleVersioned("meta", meta -> { - reader.in(meta).handle("ilst", ilst -> { - MpegSectionInfo entry; - - while ((entry = reader.nextChild(ilst)) != null) { - parseMetadataEntry(entry); - } - }).run(); - }).run(); - } - - private void parseMetadataEntry(MpegSectionInfo entry) throws IOException { - MpegSectionInfo dataHeader = reader.nextChild(entry); - - if (dataHeader != null && "data".equals(dataHeader.type)) { - MpegVersionedSectionInfo data = reader.parseFlags(dataHeader); - - // Skip next 4 bytes - reader.data.readInt(); - - if (data.flags == 1) { - storeMetadata(entry.type, reader.readUtfString((int) data.length - 16)); - } - } - - reader.skip(entry); - } - - private void storeMetadata(String code, Object value) { - String name = getMetadataName(code); - - if (name != null && value != null) { - metadata.put(name, value); - } - } - - private static String getMetadataName(String code) { - switch (code.toLowerCase()) { - case "\u00a9art": - return "Artist"; - case "\u00a9nam": - return "Title"; - default: - return null; - } - } - - private MpegParseStopChecker getRootStopChecker(final AtomicBoolean movieBoxSeen) { - return (child, start) -> { - if (!start && "sidx".equals(child.type)) { - return true; - } else if (start && ("mdat".equals(child.type) || "free".equals(child.type))) { - return movieBoxSeen.get(); - } else { - return false; - } - }; - } - - /** - * @param consumer Track information consumer that the track provider passes the raw packets to. - * @return Track audio provider. - */ - public MpegFileTrackProvider loadReader(MpegTrackConsumer consumer) { - if (fragmentedFileReader.initialise(consumer)) { - return fragmentedFileReader; - } else if (standardFileReader.initialise(consumer)) { - return standardFileReader; - } else { - return null; - } - } - - private void parseTrackInfo(MpegSectionInfo trak) throws IOException { - final MpegTrackInfo.Builder trackInfo = new MpegTrackInfo.Builder(); - - reader.in(trak).handleVersioned("tkhd", tkhd -> { - reader.data.skipBytes(tkhd.version == 1 ? 16 : 8); - - trackInfo.setTrackId(reader.data.readInt()); - }).handle("mdia", mdia -> { - reader.in(mdia).handleVersioned("hdlr", hdlr -> { - reader.data.skipBytes(4); - - trackInfo.setHandler(reader.readFourCC()); - }).handleVersioned("mdhd", mdhd -> - standardFileReader.readMediaHeaders(mdhd, trackInfo.getTrackId()) - ).handle("minf", minf -> { - reader.in(minf).handle("stbl", stbl -> { - MpegReader.Chain chain = reader.in(stbl); - parseTrackCodecInfo(chain, trackInfo); - standardFileReader.attachSampleTableParsers(chain, trackInfo.getTrackId()); - chain.run(); - }).run(); - }).run(); - }).run(); - - tracks.add(trackInfo.build()); - } - - private void parseTrackCodecInfo(MpegReader.Chain chain, MpegTrackInfo.Builder trackInfo) { - chain.handleVersioned("stsd", stsd -> { - int entryCount = reader.data.readInt(); - if (entryCount > 0) { - MpegSectionInfo codec = reader.nextChild(stsd); - trackInfo.setCodecName(codec.type); - - if ("soun".equals(trackInfo.getHandler())) { - parseSoundTrackCodec(codec, trackInfo); - } - } - }); - } - - private void parseSoundTrackCodec(MpegSectionInfo codec, MpegTrackInfo.Builder trackInfo) throws IOException { - reader.parseFlags(codec); - - reader.data.readUnsignedShort(); // data_reference_index - reader.data.readUnsignedShort(); // apple: sound_version - reader.data.skipBytes(8); // reserved - - trackInfo.setChannelCount(reader.data.readUnsignedShort()); - - reader.data.readUnsignedShort(); // sample_size - reader.data.readUnsignedShort(); // apple stuff - - trackInfo.setSampleRate(reader.data.readInt()); - } - - private void parseEventMessage(MpegSectionInfo emsg) throws IOException { - reader.readTerminatedString(); // scheme_id_uri - reader.readTerminatedString(); // value - reader.data.readInt(); // timescale - reader.data.readInt(); // presentation_time_delta - reader.data.readInt(); // event_duration - - int remaining = (int) ((emsg.offset + emsg.length) - reader.seek.getPosition()); - - lastEventMessage = new byte[remaining]; - reader.data.readFully(lastEventMessage); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegNoopTrackConsumer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegNoopTrackConsumer.java deleted file mode 100644 index 7e60265..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegNoopTrackConsumer.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg; - -import java.nio.channels.ReadableByteChannel; - -/** - * No-op MP4 track consumer, for probing purposes. - */ -public class MpegNoopTrackConsumer implements MpegTrackConsumer { - private final MpegTrackInfo trackInfo; - - /** - * @param trackInfo Track info. - */ - public MpegNoopTrackConsumer(MpegTrackInfo trackInfo) { - this.trackInfo = trackInfo; - } - - @Override - public MpegTrackInfo getTrack() { - return trackInfo; - } - - @Override - public void initialise() { - // Nothing to do - } - - @Override - public void seekPerformed(long requestedTimecode, long providedTimecode) { - // Nothing to do - } - - @Override - public void flush() throws InterruptedException { - // Nothing to do - } - - @Override - public void consume(ReadableByteChannel channel, int length) throws InterruptedException { - // Nothing to do - } - - @Override - public void close() { - // Nothing to do - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegTrackConsumer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegTrackConsumer.java deleted file mode 100644 index bbbe3fa..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegTrackConsumer.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg; - -import java.nio.channels.ReadableByteChannel; - -/** - * Consumer for the data of one MP4 track - */ -public interface MpegTrackConsumer { - /** - * @return The associated MP4 track - */ - MpegTrackInfo getTrack(); - - /** - * Initialise the consumer, called before first consume() - */ - void initialise(); - - /** - * Indicates that the next frame is not a direct continuation of the previous one - * - * @param requestedTimecode Timecode in milliseconds to which the seek was requested to - * @param providedTimecode Timecode in milliseconds to which the seek was actually performed to - */ - void seekPerformed(long requestedTimecode, long providedTimecode); - - /** - * Indicates that no more input is coming. Flush any buffers to output. - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void flush() throws InterruptedException; - - /** - * Consume one chunk from the track - * - * @param channel Byte channel to consume from - * @param length Lenth of the chunk in bytes - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void consume(ReadableByteChannel channel, int length) throws InterruptedException; - - /** - * Free all resources - */ - void close(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegTrackInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegTrackInfo.java deleted file mode 100644 index c91e58d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/MpegTrackInfo.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg; - -/** - * Codec information for an MP4 track - */ -public class MpegTrackInfo { - /** - * ID of the track - */ - public final int trackId; - /** - * Handler type (soun for audio) - */ - public final String handler; - /** - * Name of the codec - */ - public final String codecName; - /** - * Number of audio channels - */ - public final int channelCount; - /** - * Sample rate for audio - */ - public final int sampleRate; - - /** - * @param trackId ID of the track - * @param handler Handler type (soun for audio) - * @param codecName Name of the codec - * @param channelCount Number of audio channels - * @param sampleRate Sample rate for audio - */ - public MpegTrackInfo(int trackId, String handler, String codecName, int channelCount, int sampleRate) { - this.trackId = trackId; - this.handler = handler; - this.codecName = codecName; - this.channelCount = channelCount; - this.sampleRate = sampleRate; - } - - /** - * Helper class for constructing a track info instance. - */ - public static class Builder { - private int trackId; - private String handler; - private String codecName; - private int channelCount; - private int sampleRate; - - public void setTrackId(int trackId) { - this.trackId = trackId; - } - - public int getTrackId() { - return trackId; - } - - public String getHandler() { - return handler; - } - - public void setHandler(String handler) { - this.handler = handler; - } - - public void setCodecName(String codecName) { - this.codecName = codecName; - } - - public void setChannelCount(int channelCount) { - this.channelCount = channelCount; - } - - public void setSampleRate(int sampleRate) { - this.sampleRate = sampleRate; - } - - /** - * @return The final track info - */ - public MpegTrackInfo build() { - return new MpegTrackInfo(trackId, handler, codecName, channelCount, sampleRate); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegFileTrackProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegFileTrackProvider.java deleted file mode 100644 index 6c1846a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegFileTrackProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader; - -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegTrackConsumer; - -/** - * Track provider for a type of MP4 file. - */ -public interface MpegFileTrackProvider { - /** - * @param trackConsumer Track consumer which defines the track this will provide and the consumer for packets. - * @return Returns true if it had enough information for initialisation. - */ - boolean initialise(MpegTrackConsumer trackConsumer); - - /** - * @return Total duration of the file in milliseconds - */ - long getDuration(); - - /** - * Provide audio frames to the frame consumer until the end of the track or interruption. - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void provideFrames() throws InterruptedException; - - /** - * Perform a seek to the given timecode (ms). On the next call to provideFrames, the seekPerformed method of frame - * consumer is called with the position where it actually seeked to and the position where the seek was requested to - * as arguments. - * - * @param timecode The timecode to seek to in milliseconds - */ - void seekToTimecode(long timecode); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegParseStopChecker.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegParseStopChecker.java deleted file mode 100644 index 7f1bbdd..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegParseStopChecker.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader; - -/** - * Stop checker which is called before and after parsing each section in an MP4 file to check if parsing should be - * stopped. - */ -public interface MpegParseStopChecker { - /** - * @param child Section before or after which this is called. - * @param start Whether this is called before (true) or after (false). - * @return True to stop, false to continue. - */ - boolean check(MpegSectionInfo child, boolean start); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegReader.java deleted file mode 100644 index 55fdcbb..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegReader.java +++ /dev/null @@ -1,281 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; - -import java.io.ByteArrayOutputStream; -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; - -/** - * Handles reading parts of an MP4 file - */ -public class MpegReader { - /** - * The input as a DataInput - */ - public final DataInput data; - - /** - * The input as a seekable stream - */ - public final SeekableInputStream seek; - - private final byte[] fourCcBuffer; - private final ByteBuffer readAttemptBuffer; - - /** - * @param inputStream Input as a seekable stream - */ - public MpegReader(SeekableInputStream inputStream) { - seek = inputStream; - data = new DataInputStream(inputStream); - fourCcBuffer = new byte[4]; - readAttemptBuffer = ByteBuffer.allocate(4); - } - - /** - * Reads the header of the next child element. Assumes position is at the start of a header or at the end of the section. - * - * @param parent The section from which to read child sections from - * @return The element if there were any more child elements - */ - public MpegSectionInfo nextChild(MpegSectionInfo parent) { - if (parent.offset + parent.length <= seek.getPosition() + 8) { - return null; - } - - try { - long offset = seek.getPosition(); - Integer lengthField = tryReadInt(); - - if (lengthField == null) { - return null; - } - - long length = Integer.toUnsignedLong(lengthField); - return new MpegSectionInfo(offset, length, readFourCC()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Skip to the end of a section. - * - * @param section The section to skip - */ - public void skip(MpegSectionInfo section) { - try { - seek.seek(section.offset + section.length); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Read a FourCC as a string - * - * @return The FourCC string - * @throws IOException When reading the bytes from input fails - */ - public String readFourCC() throws IOException { - data.readFully(fourCcBuffer); - return new String(fourCcBuffer, "ISO-8859-1"); - } - - /** - * Read an UTF string with a specified size. - * - * @param size Size in bytes. - * @return The string read from the stream - * @throws IOException On read error - */ - public String readUtfString(int size) throws IOException { - byte[] bytes = new byte[size]; - data.readFully(bytes); - - return new String(bytes, StandardCharsets.UTF_8); - } - - /** - * Read a null-terminated UTF string. - * - * @return The string read from the stream - * @throws IOException On read error - */ - public String readTerminatedString() throws IOException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - byte nextByte; - - while ((nextByte = data.readByte()) != 0) { - bytes.write(nextByte); - } - - return new String(bytes.toByteArray(), StandardCharsets.UTF_8); - } - - /** - * Parse the flags and version for the specified section - * - * @param section The section where the flags and version should be parsed - * @return The section info with version info - * @throws IOException On a read error - */ - public MpegVersionedSectionInfo parseFlags(MpegSectionInfo section) throws IOException { - return parseFlagsForSection(data, section); - } - - private static MpegVersionedSectionInfo parseFlagsForSection(DataInput in, MpegSectionInfo section) throws IOException { - int versionAndFlags = in.readInt(); - return new MpegVersionedSectionInfo(section, versionAndFlags >>> 24, versionAndFlags & 0xffffff); - } - - private Integer tryReadInt() throws IOException { - int firstByte = seek.read(); - - if (firstByte == -1) { - return null; - } - - readAttemptBuffer.put(0, (byte) firstByte); - data.readFully(readAttemptBuffer.array(), 1, 3); - return readAttemptBuffer.getInt(0); - } - - /** - * Start a child element handling chain - * - * @param parent The parent chain - * @return The chain - */ - public Chain in(MpegSectionInfo parent) { - return new Chain(parent, this); - } - - /** - * Child element processing helper class. - */ - public static class Chain { - private final MpegSectionInfo parent; - private final List handlers; - private final MpegReader reader; - private MpegParseStopChecker stopChecker; - - private Chain(MpegSectionInfo parent, MpegReader reader) { - this.parent = parent; - this.reader = reader; - handlers = new ArrayList<>(); - } - - /** - * @param type The FourCC of the section for which a handler is specified - * @param handler The handler - * @return this - */ - public Chain handle(String type, MpegSectionHandler handler) { - handle(type, false, handler); - return this; - } - - /** - * @param type The FourCC of the section for which a handler is specified - * @param finish Whether to stop reading after this section - * @param handler The handler - * @return this - */ - public Chain handle(String type, boolean finish, MpegSectionHandler handler) { - handlers.add(new Handler(type, finish, handler)); - return this; - } - - /** - * @param type The FourCC of the section for which a handler is specified - * @param handler The handler which expects versioned section info - * @return this - */ - public Chain handleVersioned(String type, MpegVersionedSectionHandler handler) { - handlers.add(new Handler(type, false, handler)); - return this; - } - - /** - * @param type The FourCC of the section for which a handler is specified - * @param finish Whether to stop reading after this section - * @param handler The handler which expects versioned section info - * @return this - */ - public Chain handleVersioned(String type, boolean finish, MpegVersionedSectionHandler handler) { - handlers.add(new Handler(type, finish, handler)); - return this; - } - - /** - * Assign a parsing stop checker to this chain. - * - * @param stopChecker Stop checker. - * @return this - */ - public Chain stopChecker(MpegParseStopChecker stopChecker) { - this.stopChecker = stopChecker; - return this; - } - - /** - * Process the current section with all the handlers specified so far - * - * @throws IOException On read error - */ - public void run() throws IOException { - MpegSectionInfo child; - boolean finished = false; - - while (!finished && (child = reader.nextChild(parent)) != null) { - finished = stopChecker != null && stopChecker.check(child, true); - - if (!finished) { - processHandlers(child); - - finished = stopChecker != null && stopChecker.check(child, false); - } - - reader.skip(child); - } - } - - private void processHandlers(MpegSectionInfo child) throws IOException { - for (Handler handler : handlers) { - if (handler.type.equals(child.type)) { - handleSection(child, handler); - } - } - } - - private boolean handleSection(MpegSectionInfo child, Handler handler) throws IOException { - if (handler.sectionHandler instanceof MpegVersionedSectionHandler) { - MpegVersionedSectionInfo versioned = parseFlagsForSection(reader.data, child); - ((MpegVersionedSectionHandler) handler.sectionHandler).handle(versioned); - } else { - ((MpegSectionHandler) handler.sectionHandler).handle(child); - } - - return !handler.terminator; - } - } - - private static class Handler { - private final String type; - private final boolean terminator; - private final Object sectionHandler; - - private Handler(String type, boolean terminator, Object sectionHandler) { - this.type = type; - this.terminator = terminator; - this.sectionHandler = sectionHandler; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegSectionHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegSectionHandler.java deleted file mode 100644 index 224b766..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegSectionHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader; - -import java.io.IOException; - -/** - * Handles one MPEG section which has no version info - */ -public interface MpegSectionHandler { - /** - * @param child The section - * @throws IOException On read error - */ - void handle(MpegSectionInfo child) throws IOException; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegSectionInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegSectionInfo.java deleted file mode 100644 index 9a49bc7..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegSectionInfo.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader; - -/** - * Information for one MP4 section (aka box) - */ -public class MpegSectionInfo { - /** - * Absolute offset of the section - */ - public final long offset; - /** - * Length of the section - */ - public final long length; - /** - * Type (fourCC) of the section - */ - public final String type; - - /** - * @param offset Absolute offset of the section - * @param length Length of the section - * @param type Type (fourCC) of the section - */ - public MpegSectionInfo(long offset, long length, String type) { - this.offset = offset; - this.length = length; - this.type = type; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegVersionedSectionHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegVersionedSectionHandler.java deleted file mode 100644 index 207ad2f..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegVersionedSectionHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader; - -import java.io.IOException; - -/** - * Handles one MPEG section which has version info - */ -public interface MpegVersionedSectionHandler { - /** - * @param child The versioned section - * @throws IOException On read error - */ - void handle(MpegVersionedSectionInfo child) throws IOException; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegVersionedSectionInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegVersionedSectionInfo.java deleted file mode 100644 index 464931b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/MpegVersionedSectionInfo.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader; - -/** - * Information for one MP4 section (aka box) including version and flags - */ -public class MpegVersionedSectionInfo extends MpegSectionInfo { - /** - * Version of the section - */ - public final int version; - /** - * Flags of the section - */ - public final int flags; - - /** - * @param sectionInfo Basic info for the section - * @param version Version of the section - * @param flags Flags of the section - */ - public MpegVersionedSectionInfo(MpegSectionInfo sectionInfo, int version, int flags) { - super(sectionInfo.offset, sectionInfo.length, sectionInfo.type); - - this.version = version; - this.flags = flags; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegFragmentedFileTrackProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegFragmentedFileTrackProvider.java deleted file mode 100644 index 1e2a878..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegFragmentedFileTrackProvider.java +++ /dev/null @@ -1,235 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader.fragmented; - -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegTrackConsumer; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.MpegFileTrackProvider; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.MpegReader; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.MpegSectionInfo; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.MpegVersionedSectionInfo; -import com.sedmelluq.discord.lavaplayer.tools.io.DetachedByteChannel; - -import java.io.IOException; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Track provider for fragmented MP4 file format. - */ -public class MpegFragmentedFileTrackProvider implements MpegFileTrackProvider { - private final MpegReader reader; - private final MpegSectionInfo root; - - private MpegTrackConsumer consumer; - private boolean isFragmented; - private long totalDuration; - private MpegGlobalSeekInfo globalSeekInfo; - private boolean seeking; - private long minimumTimecode; - - /** - * @param reader MP4-specific reader - * @param root Root section info (synthetic section wrapping the entire file) - */ - public MpegFragmentedFileTrackProvider(MpegReader reader, MpegSectionInfo root) { - this.reader = reader; - this.root = root; - } - - @Override - public boolean initialise(MpegTrackConsumer consumer) { - if (!isFragmented || globalSeekInfo == null) { - return false; - } - - this.consumer = consumer; - return true; - } - - @Override - public void provideFrames() throws InterruptedException { - MpegSectionInfo moof; - - try (ReadableByteChannel channel = new DetachedByteChannel(Channels.newChannel(reader.seek))) { - while ((moof = reader.nextChild(root)) != null) { - if (!"moof".equals(moof.type)) { - reader.skip(moof); - continue; - } - - MpegTrackFragmentHeader fragment = parseTrackMovieFragment(moof, consumer.getTrack().trackId); - MpegSectionInfo mdat = reader.nextChild(root); - - long timecode = fragment.baseTimecode; - reader.seek.seek(moof.offset + fragment.dataOffset); - - for (int i = 0; i < fragment.sampleSizes.length; i++) { - handleSeeking(consumer, timecode); - - consumer.consume(channel, fragment.sampleSizes[i]); - } - - reader.skip(mdat); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void seekToTimecode(long timecode) { - minimumTimecode = timecode * globalSeekInfo.timescale / 1000; - seeking = true; - - int segmentIndex; - - for (segmentIndex = 0; segmentIndex < globalSeekInfo.entries.length - 1; segmentIndex++) { - if (globalSeekInfo.timeOffsets[segmentIndex + 1] > minimumTimecode) { - break; - } - } - - try { - reader.seek.seek(globalSeekInfo.fileOffsets[segmentIndex]); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public long getDuration() { - return totalDuration * 1000 / globalSeekInfo.timescale; - } - - /** - * Handle mvex section. - * - * @param mvex Section header. - * @throws IOException On read error - */ - public void parseMovieExtended(MpegSectionInfo mvex) throws IOException { - reader.in(mvex).handleVersioned("trex", trex -> { - isFragmented = true; - }).run(); - } - - /** - * Handle segment index section. - * - * @param sbix Section header. - * @throws IOException On read error - */ - public void parseSegmentIndex(MpegVersionedSectionInfo sbix) throws IOException { - reader.data.readInt(); // referenceId - int timescale = reader.data.readInt(); - - if (sbix.version == 0) { - reader.data.readInt(); // earliestPresentationTime - reader.data.readInt(); // firstOffset - } else { - reader.data.readLong(); // earliestPresentationTime - reader.data.readLong(); // firstOffset - } - - reader.data.readShort(); // reserved - - MpegSegmentEntry[] entries = new MpegSegmentEntry[reader.data.readUnsignedShort()]; - - for (int i = 0; i < entries.length; i++) { - int typeAndSize = reader.data.readInt(); - int duration = reader.data.readInt(); - reader.data.readInt(); // startsWithSap + sapType + sapDeltaTime - - entries[i] = new MpegSegmentEntry(typeAndSize >>> 31, typeAndSize & 0x7fffffff, duration); - - totalDuration += duration; - } - - globalSeekInfo = new MpegGlobalSeekInfo(timescale, sbix.offset + sbix.length, entries); - } - - private void handleSeeking(MpegTrackConsumer consumer, long timecode) { - if (seeking) { - // Even though sample durations may be available, decoding doesn't work if we don't start from the beginning - // of a fragment. Therefore skipping within the fragment is handled by skipping decoded samples later. - consumer.seekPerformed(minimumTimecode * 1000 / globalSeekInfo.timescale, timecode * 1000 / globalSeekInfo.timescale); - seeking = false; - } - } - - private MpegTrackFragmentHeader parseTrackMovieFragment(MpegSectionInfo moof, int trackId) throws IOException { - final AtomicReference header = new AtomicReference<>(); - - reader.in(moof).handle("traf", traf -> { - final MpegTrackFragmentHeader.Builder builder = new MpegTrackFragmentHeader.Builder(); - - reader.in(traf).handleVersioned("tfhd", tfhd -> { - parseTrackFragmentHeader(tfhd, builder); - }).handleVersioned("tfdt", tfdt -> { - builder.setBaseTimecode((tfdt.version == 1) ? reader.data.readLong() : reader.data.readInt()); - }).handleVersioned("trun", trun -> { - if (builder.getTrackId() == trackId) { - parseTrackRunInfo(trun, builder); - } - }).run(); - - if (builder.getTrackId() == trackId) { - header.set(builder.build()); - } - }).run(); - - return header.get(); - } - - private void parseTrackFragmentHeader(MpegVersionedSectionInfo tfhd, MpegTrackFragmentHeader.Builder builder) throws IOException { - builder.setTrackId(reader.data.readInt()); - - if ((tfhd.flags & 0x000010) != 0) { - // Need to read default sample size, but first must skip the fields before it - if ((tfhd.flags & 0x000001) != 0) { - // Skip baseDataOffset - reader.data.readLong(); - } - - if ((tfhd.flags & 0x000002) != 0) { - // Skip sampleDescriptionIndex - reader.data.readInt(); - } - - if ((tfhd.flags & 0x000008) != 0) { - // Skip defaultSampleDuration - reader.data.readInt(); - } - - builder.setDefaultSampleSize(reader.data.readInt()); - } - } - - private void parseTrackRunInfo(MpegVersionedSectionInfo trun, MpegTrackFragmentHeader.Builder builder) throws IOException { - int sampleCount = reader.data.readInt(); - builder.setDataOffset(((trun.flags & 0x01) != 0) ? reader.data.readInt() : -1); - - if ((trun.flags & 0x04) != 0) { - reader.data.skipBytes(4); // first sample flags - } - - boolean hasDurations = (trun.flags & 0x100) != 0; - boolean hasSizes = (trun.flags & 0x200) != 0; - - builder.createSampleArrays(hasDurations, hasSizes, sampleCount); - - for (int i = 0; i < sampleCount; i++) { - if (hasDurations) { - builder.setDuration(i, reader.data.readInt()); - } - if (hasSizes) { - builder.setSize(i, reader.data.readInt()); - } - if ((trun.flags & 0x400) != 0) { - reader.data.skipBytes(4); - } - if ((trun.flags & 0x800) != 0) { - reader.data.skipBytes(4); - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegGlobalSeekInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegGlobalSeekInfo.java deleted file mode 100644 index 7246481..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegGlobalSeekInfo.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader.fragmented; - -/** - * Describes the seek info for a fragmented MP4 file - */ -public class MpegGlobalSeekInfo { - /** - * The value of the internal timecodes that corresponds to one second - */ - public final int timescale; - /** - * Size and duration information for each segment - */ - public final MpegSegmentEntry[] entries; - /** - * Absolute timecode offset of each segment - */ - public final long[] timeOffsets; - /** - * Absolute file offset of each segment - */ - public final long[] fileOffsets; - - /** - * @param timescale The value of the internal timecodes that corresponds to one second - * @param baseOffset The file offset of the first segment - * @param entries Size and duration information for each segment - */ - public MpegGlobalSeekInfo(int timescale, long baseOffset, MpegSegmentEntry[] entries) { - this.timescale = timescale; - this.entries = entries; - - timeOffsets = new long[entries.length]; - fileOffsets = new long[entries.length]; - fileOffsets[0] = baseOffset; - - for (int i = 1; i < entries.length; i++) { - timeOffsets[i] = timeOffsets[i - 1] + entries[i - 1].duration; - fileOffsets[i] = fileOffsets[i - 1] + entries[i - 1].size; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegSegmentEntry.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegSegmentEntry.java deleted file mode 100644 index 224fcbe..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegSegmentEntry.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader.fragmented; - -/** - * Information about one MP4 segment aka fragment - */ -public class MpegSegmentEntry { - /** - * Type of the segment - */ - public final int type; - /** - * Size in bytes - */ - public final int size; - /** - * Duration using the timescale of the file - */ - public final int duration; - - /** - * @param type Type of the segment - * @param size Size in bytes - * @param duration Duration using the timescale of the file - */ - public MpegSegmentEntry(int type, int size, int duration) { - this.type = type; - this.size = size; - this.duration = duration; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegTrackFragmentHeader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegTrackFragmentHeader.java deleted file mode 100644 index 7d9217a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/fragmented/MpegTrackFragmentHeader.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader.fragmented; - -/** - * Header for an MP4 track in a fragment. - */ -public class MpegTrackFragmentHeader { - /** - * Track ID which this header is for - */ - public final int trackId; - /** - * The timecode at which this track is at the start of this fragment - */ - public final long baseTimecode; - /** - * The offset of the data for this track in this fragment - */ - public final int dataOffset; - /** - * Duration of each sample for this track in this fragment using file timescale - */ - public final int[] sampleDurations; - /** - * Size of each sample for this track in this fragment - */ - public final int[] sampleSizes; - - /** - * @param trackId Track ID which this header is for - * @param baseTimecode The timecode at which this track is at the start of this fragment - * @param dataOffset The offset of the data for this track in this fragment - * @param sampleDurations Duration of each sample for this track in this fragment using file timescale - * @param sampleSizes Size of each sample for this track in this fragment - */ - public MpegTrackFragmentHeader(int trackId, long baseTimecode, int dataOffset, int[] sampleDurations, int[] sampleSizes) { - this.trackId = trackId; - this.baseTimecode = baseTimecode; - this.dataOffset = dataOffset; - this.sampleDurations = sampleDurations; - this.sampleSizes = sampleSizes; - } - - /** - * A helper for building an instance of this class. - */ - public static class Builder { - private int trackId; - private long baseTimecode; - private int dataOffset; - private int defaultSampleSize; - private int sampleCount; - private int[] sampleDurations; - private int[] sampleSizes; - - /** - * Create an empty builder. - */ - public Builder() { - trackId = -1; - } - - /** - * @return Previously assigned track ID, or -1 if not assigned - */ - public int getTrackId() { - return trackId; - } - - public void setTrackId(int trackId) { - this.trackId = trackId; - } - - public void setBaseTimecode(long baseTimecode) { - this.baseTimecode = baseTimecode; - } - - public void setDataOffset(int dataOffset) { - this.dataOffset = dataOffset; - } - - public void setDefaultSampleSize(int defaultSampleSize) { - this.defaultSampleSize = defaultSampleSize; - } - - /** - * Create sample duration and size arrays - * - * @param hasDurations If duration data is present - * @param hasSizes If size data is present - * @param sampleCount Number of samples - */ - public void createSampleArrays(boolean hasDurations, boolean hasSizes, int sampleCount) { - this.sampleCount = sampleCount; - - if (hasDurations) { - sampleDurations = new int[sampleCount]; - } - - if (hasSizes) { - sampleSizes = new int[sampleCount]; - } - } - - /** - * Set the duration of a specific sample - * - * @param i Sample index - * @param value Duration using the file timescale - */ - public void setDuration(int i, int value) { - sampleDurations[i] = value; - } - - /** - * Set the size of a specific sample - * - * @param i Sample index - * @param value Size - */ - public void setSize(int i, int value) { - sampleSizes[i] = value; - } - - /** - * @return The final header - */ - public MpegTrackFragmentHeader build() { - int[] finalSampleSizes = sampleSizes; - - if (defaultSampleSize != 0) { - finalSampleSizes = new int[sampleCount]; - - for (int i = 0; i < sampleCount; i++) { - finalSampleSizes[i] = defaultSampleSize; - } - } - - return new MpegTrackFragmentHeader(trackId, baseTimecode, dataOffset, sampleDurations, finalSampleSizes); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/standard/MpegStandardFileTrackProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/standard/MpegStandardFileTrackProvider.java deleted file mode 100644 index 7fc2970..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpeg/reader/standard/MpegStandardFileTrackProvider.java +++ /dev/null @@ -1,335 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpeg.reader.standard; - -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegTrackConsumer; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.MpegFileTrackProvider; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.MpegReader; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.MpegVersionedSectionInfo; -import com.sedmelluq.discord.lavaplayer.tools.io.DetachedByteChannel; - -import java.io.IOException; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Track provider for the standard (non-fragmented) MP4 file format. - */ -public class MpegStandardFileTrackProvider implements MpegFileTrackProvider { - private final MpegReader reader; - private final List builders = new ArrayList<>(); - private final Map trackTimescales = new HashMap<>(); - private int timescale; - private int currentChunk; - private MpegTrackConsumer consumer; - private TrackSeekInfo seekInfo; - - /** - * @param reader MP4-specific reader - */ - public MpegStandardFileTrackProvider(MpegReader reader) { - this.reader = reader; - this.currentChunk = 0; - } - - @Override - public boolean initialise(MpegTrackConsumer consumer) { - this.consumer = consumer; - - int trackId = consumer.getTrack().trackId; - - if (!trackTimescales.containsKey(trackId)) { - return false; - } - - try { - for (TrackSeekInfoBuilder builder : builders) { - if (builder.trackId == trackId) { - seekInfo = builder.build(); - timescale = trackTimescales.get(trackId); - return true; - } - } - } finally { - builders.clear(); - } - - return false; - } - - @Override - public long getDuration() { - return seekInfo.totalDuration * 1000L / timescale; - } - - @Override - public void provideFrames() throws InterruptedException { - try (ReadableByteChannel channel = new DetachedByteChannel(Channels.newChannel(reader.seek))) { - while (currentChunk < seekInfo.chunkOffsets.length) { - reader.seek.seek(seekInfo.chunkOffsets[currentChunk]); - - int[] samples = seekInfo.chunkSamples[currentChunk]; - for (int i = 0; i < samples.length; i++) { - consumer.consume(channel, samples[i]); - } - - currentChunk++; - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void seekToTimecode(long timecode) { - long scaledTimecode = timecode * timescale / 1000; - int length = seekInfo.chunkOffsets.length; - - if (scaledTimecode >= seekInfo.totalDuration) { - currentChunk = length; - consumer.seekPerformed(timecode, seekInfo.totalDuration * 1000 / timescale); - } else { - for (int i = 0; i < length; i++) { - long nextTimecode = i < length - 1 ? seekInfo.chunkTimecodes[i + 1] : seekInfo.totalDuration; - - if (scaledTimecode < nextTimecode) { - consumer.seekPerformed(timecode, seekInfo.chunkTimecodes[i] * 1000 / timescale); - currentChunk = i; - break; - } - } - } - } - - /** - * Read the mdhd section for a track. - * - * @param mdhd The section header - * @param trackId Track ID - * @throws IOException On read error. - */ - public void readMediaHeaders(MpegVersionedSectionInfo mdhd, int trackId) throws IOException { - int trackTimescale; - - if (mdhd.version == 1) { - reader.data.readLong(); // creation time - reader.data.readLong(); // modification time - trackTimescale = reader.data.readInt(); - reader.data.readLong(); // duration - } else { - reader.data.readInt(); // creation time - reader.data.readInt(); // modification time - trackTimescale = reader.data.readInt(); - reader.data.readInt(); // duration - } - - trackTimescales.put(trackId, trackTimescale); - } - - /** - * Attaches standard format specific handlers to sample table section handle chain. - * - * @param sampleTableChain Sample table child section handler chain. - * @param trackId Track ID - */ - public void attachSampleTableParsers(MpegReader.Chain sampleTableChain, int trackId) { - final TrackSeekInfoBuilder seekInfoBuilder = new TrackSeekInfoBuilder(trackId); - - sampleTableChain - .handleVersioned("stts", stts -> parseTimeToSample(seekInfoBuilder)) - .handleVersioned("stsc", stsc -> parseSampleToChunk(seekInfoBuilder)) - .handleVersioned("stsz", stsz -> parseSampleSizes(seekInfoBuilder)) - .handleVersioned("stco", stco -> parseChunkOffsets32(seekInfoBuilder)) - .handleVersioned("co64", co64 -> parseChunkOffsets64(seekInfoBuilder)); - - builders.add(seekInfoBuilder); - } - - private void parseTimeToSample(TrackSeekInfoBuilder seekInfoBuilder) throws IOException { - int entries = reader.data.readInt(); - seekInfoBuilder.sampleTimeCounts = new int[entries]; - seekInfoBuilder.sampleTimeDeltas = new int[entries]; - seekInfoBuilder.presence |= 1; - - for (int i = 0; i < entries; i++) { - seekInfoBuilder.sampleTimeCounts[i] = reader.data.readInt(); - seekInfoBuilder.sampleTimeDeltas[i] = reader.data.readInt(); - } - } - - private void parseSampleToChunk(TrackSeekInfoBuilder seekInfoBuilder) throws IOException { - int entries = reader.data.readInt(); - seekInfoBuilder.sampleChunkingFirst = new int[entries]; - seekInfoBuilder.sampleChunkingCount = new int[entries]; - seekInfoBuilder.presence |= 2; - - for (int i = 0; i < entries; i++) { - seekInfoBuilder.sampleChunkingFirst[i] = reader.data.readInt(); - seekInfoBuilder.sampleChunkingCount[i] = reader.data.readInt(); - reader.data.readInt(); - } - } - - private void parseSampleSizes(TrackSeekInfoBuilder seekInfoBuilder) throws IOException { - seekInfoBuilder.sampleSize = reader.data.readInt(); - seekInfoBuilder.sampleCount = reader.data.readInt(); - seekInfoBuilder.presence |= 4; - - if (seekInfoBuilder.sampleSize == 0) { - seekInfoBuilder.sampleSizes = new int[seekInfoBuilder.sampleCount]; - - for (int i = 0; i < seekInfoBuilder.sampleCount; i++) { - seekInfoBuilder.sampleSizes[i] = reader.data.readInt(); - } - } - } - - private void parseChunkOffsets32(TrackSeekInfoBuilder seekInfoBuilder) throws IOException { - int chunks = reader.data.readInt(); - seekInfoBuilder.chunkOffsets = new long[chunks]; - seekInfoBuilder.presence |= 8; - - for (int i = 0; i < chunks; i++) { - seekInfoBuilder.chunkOffsets[i] = reader.data.readInt(); - } - } - - private void parseChunkOffsets64(TrackSeekInfoBuilder seekInfoBuilder) throws IOException { - int chunks = reader.data.readInt(); - seekInfoBuilder.chunkOffsets = new long[chunks]; - seekInfoBuilder.presence |= 8; - - for (int i = 0; i < chunks; i++) { - seekInfoBuilder.chunkOffsets[i] = reader.data.readLong(); - } - } - - private static class TrackSeekInfo { - private final long totalDuration; - private final long[] chunkOffsets; - private final long[] chunkTimecodes; - private final int[][] chunkSamples; - - private TrackSeekInfo(long totalDuration, long[] chunkOffsets, long[] chunkTimecodes, int[][] chunkSamples) { - this.totalDuration = totalDuration; - this.chunkOffsets = chunkOffsets; - this.chunkTimecodes = chunkTimecodes; - this.chunkSamples = chunkSamples; - } - } - - private static class TrackSeekInfoBuilder { - private final int trackId; - private int presence; - private int[] sampleTimeCounts; - private int[] sampleTimeDeltas; - private int[] sampleChunkingFirst; - private int[] sampleChunkingCount; - private long[] chunkOffsets; - private int sampleSize; - private int sampleCount; - private int[] sampleSizes; - - private TrackSeekInfoBuilder(int trackId) { - this.trackId = trackId; - } - - private TrackSeekInfo build() { - if (presence != 15) { - return null; - } - - long[] chunkTimecodes = new long[chunkOffsets.length]; - int[][] chunkSamples = new int[chunkOffsets.length][]; - - SampleChunkingIterator chunkingIterator = new SampleChunkingIterator(sampleChunkingFirst, sampleChunkingCount); - SampleDurationIterator durationIterator = new SampleDurationIterator(sampleTimeCounts, sampleTimeDeltas); - - int sampleOffset = 0; - long timeOffset = 0; - - for (int chunk = 0; chunk < chunkOffsets.length; chunk++) { - int chunkSampleCount = chunkingIterator.nextSampleCount(); - - chunkSamples[chunk] = buildChunkSampleSizes(chunkSampleCount, sampleOffset, sampleSize, sampleSizes); - chunkTimecodes[chunk] = timeOffset; - - timeOffset += calculateChunkDuration(chunkSampleCount, durationIterator); - sampleOffset += chunkSampleCount; - } - - return new TrackSeekInfo(timeOffset, chunkOffsets, chunkTimecodes, chunkSamples); - } - - private static int[] buildChunkSampleSizes(int sampleCount, int sampleOffset, int sampleSize, int[] sampleSizes) { - int[] chunkSampleSizes = new int[sampleCount]; - - if (sampleSize != 0) { - for (int i = 0; i < sampleCount; i++) { - chunkSampleSizes[i] = sampleSize; - } - } else { - System.arraycopy(sampleSizes, sampleOffset, chunkSampleSizes, 0, sampleCount); - } - - return chunkSampleSizes; - } - - private static int calculateChunkDuration(int sampleCount, SampleDurationIterator durationIterator) { - int duration = 0; - - for (int i = 0; i < sampleCount; i++) { - duration += durationIterator.nextSampleDuration(); - } - - return duration; - } - } - - private static class SampleChunkingIterator { - private final int[] sampleChunkingFirst; - private final int[] sampleChunkingCount; - private int chunkIndex = 1; - private int entryIndex = 0; - - private SampleChunkingIterator(int[] sampleChunkingFirst, int[] sampleChunkingCount) { - this.sampleChunkingFirst = sampleChunkingFirst; - this.sampleChunkingCount = sampleChunkingCount; - } - - private int nextSampleCount() { - int result = sampleChunkingCount[entryIndex]; - chunkIndex++; - - if (entryIndex + 1 < sampleChunkingFirst.length && chunkIndex == sampleChunkingFirst[entryIndex + 1]) { - entryIndex++; - } - - return result; - } - } - - private static class SampleDurationIterator { - private final int[] sampleTimeCounts; - private final int[] sampleTimeDeltas; - private int relativeSampleIndex = 0; - private int entryIndex = 0; - - private SampleDurationIterator(int[] sampleTimeCounts, int[] sampleTimeDeltas) { - this.sampleTimeCounts = sampleTimeCounts; - this.sampleTimeDeltas = sampleTimeDeltas; - } - - private int nextSampleDuration() { - int result = sampleTimeDeltas[entryIndex]; - - if (entryIndex + 1 < sampleTimeCounts.length && ++relativeSampleIndex >= sampleTimeCounts[entryIndex]) { - entryIndex++; - } - - return result; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegAdtsAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegAdtsAudioTrack.java deleted file mode 100644 index 198d1f6..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegAdtsAudioTrack.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpegts; - -import com.sedmelluq.discord.lavaplayer.container.adts.AdtsAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; - -import java.io.InputStream; - -import static com.sedmelluq.discord.lavaplayer.container.mpegts.MpegTsElementaryInputStream.ADTS_ELEMENTARY_STREAM; - -public class MpegAdtsAudioTrack extends DelegatedAudioTrack { - private final InputStream inputStream; - - /** - * @param trackInfo Track info - */ - public MpegAdtsAudioTrack(AudioTrackInfo trackInfo, InputStream inputStream) { - super(trackInfo); - - this.inputStream = inputStream; - } - - @Override - public void process(LocalAudioTrackExecutor executor) throws Exception { - MpegTsElementaryInputStream elementaryInputStream = new MpegTsElementaryInputStream(inputStream, ADTS_ELEMENTARY_STREAM); - PesPacketInputStream pesPacketInputStream = new PesPacketInputStream(elementaryInputStream); - processDelegate(new AdtsAudioTrack(trackInfo, pesPacketInputStream), executor); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegAdtsContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegAdtsContainerProbe.java deleted file mode 100644 index aca5903..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegAdtsContainerProbe.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpegts; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.adts.AdtsStreamReader; -import com.sedmelluq.discord.lavaplayer.tools.io.SavedHeadSeekableInputStream; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.supportedFormat; -import static com.sedmelluq.discord.lavaplayer.container.mpegts.MpegTsElementaryInputStream.ADTS_ELEMENTARY_STREAM; - -public class MpegAdtsContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(MpegAdtsContainerProbe.class); - - @Override - public String getName() { - return "mpegts-adts"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - boolean invalidFileExtension = hints.fileExtension != null && !"ts".equalsIgnoreCase(hints.fileExtension); - return hints.present() && !invalidFileExtension; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) - throws IOException { - - SavedHeadSeekableInputStream head = inputStream instanceof SavedHeadSeekableInputStream ? - (SavedHeadSeekableInputStream) inputStream : null; - - if (head != null) { - head.setAllowDirectReads(false); - } - - MpegTsElementaryInputStream tsStream = new MpegTsElementaryInputStream(inputStream, ADTS_ELEMENTARY_STREAM); - PesPacketInputStream pesStream = new PesPacketInputStream(tsStream); - AdtsStreamReader reader = new AdtsStreamReader(pesStream); - - try { - if (reader.findPacketHeader() != null) { - log.debug("Track {} is an MPEG-TS stream with an ADTS track.", reference.identifier); - - return supportedFormat(this, null, - AudioTrackInfoBuilder.create(reference, inputStream) - .apply(tsStream.getLoadedMetadata()) - .build() - ); - } - } catch (IndexOutOfBoundsException ignored) { - // TS stream read too far and still did not find required elementary stream - SavedHeadSeekableInputStream throws - // this because we disabled reads past the loaded "head". - } finally { - if (head != null) { - head.setAllowDirectReads(true); - } - } - - return null; - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - return new MpegAdtsAudioTrack(trackInfo, inputStream); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegTsElementaryInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegTsElementaryInputStream.java deleted file mode 100644 index 213b742..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/MpegTsElementaryInputStream.java +++ /dev/null @@ -1,332 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpegts; - -import com.sedmelluq.discord.lavaplayer.tools.io.BitBufferReader; -import com.sedmelluq.discord.lavaplayer.tools.io.GreedyInputStream; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; - -/** - * Input stream which takes in a stream providing MPEG TS data and outputs a single track from it specified by the - * elementary data type. - */ -public class MpegTsElementaryInputStream extends InputStream { - private static final Logger log = LoggerFactory.getLogger(MpegTsElementaryInputStream.class); - - public static final int ADTS_ELEMENTARY_STREAM = 0x0F; - - private static final int PID_UNKNOWN = -1; - private static final int PID_NOT_PRESENT = -2; - - private static final int PACKET_IDENTIFIER_SDT = 0x11; - - private static final int TS_PACKET_SIZE = 188; - - private final InputStream inputStream; - private final int elementaryDataType; - private final byte[] packet; - private final ByteBuffer packetBuffer; - private final BitBufferReader bufferReader; - private int elementaryStreamIdentifier; - private int programMapIdentifier; - private boolean elementaryDataInPacket; - private boolean streamEndReached; - - private String serviceProviderName; - private String serviceName; - - /** - * @param inputStream Underlying input stream - * @param elementaryDataType ID of the media type to pass upstream - */ - public MpegTsElementaryInputStream(InputStream inputStream, int elementaryDataType) { - this.inputStream = new GreedyInputStream(inputStream); - this.elementaryDataType = elementaryDataType; - this.packet = new byte[TS_PACKET_SIZE]; - this.packetBuffer = ByteBuffer.wrap(packet); - this.bufferReader = new BitBufferReader(packetBuffer); - this.elementaryStreamIdentifier = PID_UNKNOWN; - this.programMapIdentifier = PID_UNKNOWN; - } - - public AudioTrackInfoProvider getLoadedMetadata() { - return new AudioTrackInfoProvider() { - @Override - public String getTitle() { - return serviceName; - } - - @Override - public String getAuthor() { - return serviceProviderName; - } - - @Override - public Long getLength() { - return null; - } - - @Override - public String getIdentifier() { - return null; - } - - @Override - public String getUri() { - return null; - } - }; - } - - @Override - public int read() throws IOException { - if (!findElementaryData()) { - return -1; - } - - int result = packetBuffer.get() & 0xFF; - - checkElementaryDataEnd(); - return result; - } - - @Override - public int read(byte[] buffer, int offset, int length) throws IOException { - if (!findElementaryData()) { - return -1; - } - - int chunk = Math.min(length, packetBuffer.remaining()); - packetBuffer.get(buffer, offset, chunk); - - checkElementaryDataEnd(); - - return chunk; - } - - private boolean findElementaryData() throws IOException { - if (!elementaryDataInPacket) { - while (processPacket()) { - if (elementaryDataInPacket) { - return true; - } - } - } - - return elementaryDataInPacket; - } - - private void checkElementaryDataEnd() { - if (packetBuffer.remaining() == 0) { - elementaryDataInPacket = false; - } - } - - private boolean processPacket() throws IOException { - if (!isContinuable()) { - return false; - } else if (inputStream.read(packet) < packet.length) { - streamEndReached = true; - return false; - } - - packetBuffer.clear(); - bufferReader.readRemainingBits(); - - int identifier = verifyPacket(bufferReader, packetBuffer); - if (identifier == -1) { - return false; - } - - processPacketContent(identifier); - return isContinuable(); - } - - private void processPacketContent(int identifier) { - if (identifier == 0 || identifier == programMapIdentifier) { - if (identifier == 0) { - programMapIdentifier = PID_NOT_PRESENT; - } - - processProgramPacket(); - } else if (identifier == elementaryStreamIdentifier) { - elementaryDataInPacket = true; - } else if (identifier == PACKET_IDENTIFIER_SDT) { - try { - parseSdtTable(); - } catch (RuntimeException e) { - log.warn("Exception when parsing MPEG-TS SDT table.", e); - } - } - } - - private void parseSdtTable() { - bufferReader.asLong(20); - int sectionLength = bufferReader.asInteger(12); - bufferReader.asLong(64); - - if (sectionLength > 0) { - bufferReader.asLong(28); - int loopLength = bufferReader.asInteger(12); - - if (loopLength > 0) { - int descriptorTag = bufferReader.asInteger(8); - - if (descriptorTag == 0x48) { - bufferReader.asLong(16); - - serviceProviderName = parseSdtAsciiString(); - serviceName = parseSdtAsciiString(); - } - } - } - } - - private String parseSdtAsciiString() { - int length = packetBuffer.get() & 0xFF; - - if (length > 0) { - byte[] textBytes = new byte[length]; - packetBuffer.get(textBytes); - - return new String(textBytes, 0, textBytes.length, StandardCharsets.US_ASCII); - } else { - return null; - } - } - - private boolean isContinuable() { - return !streamEndReached || programMapIdentifier != PID_NOT_PRESENT && elementaryStreamIdentifier != PID_NOT_PRESENT; - } - - private void processProgramPacket() { - discardPointerField(); - - while (packetBuffer.hasRemaining()) { - int tableIdentifier = packetBuffer.get() & 0xFF; - if (tableIdentifier == 0xFF) { - break; - } - - int sectionInfo = bufferReader.asInteger(6); - int sectionLength = bufferReader.asInteger(10); - int position = packetBuffer.position(); - bufferReader.readRemainingBits(); - - if (tableIdentifier == 0) { - processPatTable(sectionInfo); - } else if (tableIdentifier == 2) { - processPmtTable(sectionInfo, sectionLength); - } - - packetBuffer.position(position + sectionLength); - } - } - - private boolean processPatPmtCommon(int sectionInfo) { - if (sectionInfo != 0x2C) { - return false; - } - - // Table syntax section, boring. - bufferReader.asLong(40); - return true; - } - - private void processPatTable(int sectionInfo) { - if (!processPatPmtCommon(sectionInfo)) { - return; - } - - // Program number - bufferReader.asLong(16); - - if (bufferReader.asLong(3) == 0x07) { - programMapIdentifier = bufferReader.asInteger(13); - } - } - - private void processPmtTable(int sectionInfo, int sectionLength) { - int endPosition = packetBuffer.position() + sectionLength; - - if (!processPatPmtCommon(sectionInfo) || bufferReader.asInteger(3) != 0x07) { - return; - } - - // Clock packet identifier (PCR PID) - bufferReader.asLong(13); - // Reserved bits (must be 1111) and program info length unused bits (must be 00) - if (bufferReader.asLong(6) != 0x3C) { - return; - } - - // Skip program descriptors - int programInfoLength = bufferReader.asInteger(10); - packetBuffer.position(packetBuffer.position() + programInfoLength); - - processElementaryStreams(endPosition); - } - - private void processElementaryStreams(int endPosition) { - elementaryStreamIdentifier = PID_NOT_PRESENT; - - while (packetBuffer.position() < endPosition - 4) { - int streamType = bufferReader.asInteger(8); - // Reserved bits (must be 111) - bufferReader.asInteger(3); - - int streamPid = bufferReader.asInteger(13); - // 4 reserved bits (1111) and 2 ES Info length unused bits (00) - bufferReader.asLong(6); - - int infoLength = bufferReader.asInteger(10); - packetBuffer.position(packetBuffer.position() + infoLength); - - if (streamType == elementaryDataType) { - elementaryStreamIdentifier = streamPid; - } - } - } - - private void discardPointerField() { - int pointerField = packetBuffer.get(); - - for (int i = 0; i < pointerField; i++) { - packetBuffer.get(); - } - } - - private static int verifyPacket(BitBufferReader reader, ByteBuffer rawBuffer) { - if (reader.asLong(8) != 'G') { - return -1; - } - - // Not important for this case - reader.asLong(3); - - int identifier = reader.asInteger(13); - long scrambling = reader.asLong(2); - - // Adaptation - long adaptation = reader.asLong(2); - - if (scrambling != 0) { - return -1; - } - - // Continuity counter - reader.asLong(4); - - if (adaptation == 2 || adaptation == 3) { - int adaptationSize = reader.asInteger(8); - rawBuffer.position(rawBuffer.position() + adaptationSize); - } - - return identifier; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/PesPacketInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/PesPacketInputStream.java deleted file mode 100644 index 49d8812..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/mpegts/PesPacketInputStream.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.mpegts; - -import com.sedmelluq.discord.lavaplayer.tools.io.GreedyInputStream; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; - -/** - * Input stream which takes in a stream providing PES-wrapped media packets and outputs provides the raw content of it - * upstream. - */ -public class PesPacketInputStream extends InputStream { - private static final byte[] SYNC_BYTES = new byte[]{0x00, 0x00, 0x01}; - - private final InputStream inputStream; - private final byte[] lengthBufferBytes; - private final ByteBuffer lengthBuffer; - private int packetBytesLeft; - - /** - * @param inputStream Underlying input stream. - */ - public PesPacketInputStream(InputStream inputStream) { - this.inputStream = new GreedyInputStream(inputStream); - this.lengthBufferBytes = new byte[2]; - this.lengthBuffer = ByteBuffer.wrap(lengthBufferBytes); - } - - private boolean makeBytesAvailable() throws IOException { - if (packetBytesLeft > 0) { - return true; - } - - int streamByte; - int matched = 0; - boolean packetFound = false; - - while (!packetFound && (streamByte = inputStream.read()) != -1) { - if (streamByte == SYNC_BYTES[matched]) { - if (++matched == SYNC_BYTES.length) { - matched = 0; - packetFound = processPacketHeader(); - } - } else { - matched = 0; - } - } - - return packetFound; - } - - private boolean processPacketHeader() throws IOException { - // No need to check stream ID value - if (inputStream.read() == -1 || inputStream.read(lengthBufferBytes) != lengthBufferBytes.length) { - return false; - } - - int length = lengthBuffer.getShort(0); - if (inputStream.skip(2) != 2) { - return false; - } - - int headerLength = inputStream.read(); - if (headerLength == -1 || inputStream.skip(headerLength) != headerLength) { - return false; - } - - packetBytesLeft = length - 3 - headerLength; - return packetBytesLeft > 0; - } - - @Override - public int read() throws IOException { - if (!makeBytesAvailable()) { - return -1; - } - - int result = inputStream.read(); - if (result >= 0) { - packetBytesLeft--; - } - - return result; - } - - @Override - public int read(byte[] buffer, int offset, int length) throws IOException { - if (!makeBytesAvailable()) { - return -1; - } - - int chunk = Math.min(packetBytesLeft, length); - int result = inputStream.read(buffer, offset, chunk); - if (result > 0) { - packetBytesLeft -= result; - } - - return result; - } - - @Override - public int available() throws IOException { - return packetBytesLeft; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggAudioTrack.java deleted file mode 100644 index f12209a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggAudioTrack.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg; - -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.BaseAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio track which handles an OGG stream. - */ -public class OggAudioTrack extends BaseAudioTrack { - private static final Logger log = LoggerFactory.getLogger(OggAudioTrack.class); - - private final SeekableInputStream inputStream; - - /** - * @param trackInfo Track info - * @param inputStream Input stream for the OGG stream - */ - public OggAudioTrack(AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - super(trackInfo); - - this.inputStream = inputStream; - } - - @Override - public void process(final LocalAudioTrackExecutor localExecutor) { - OggPacketInputStream packetInputStream = new OggPacketInputStream(inputStream); - - log.debug("Starting to play an OGG stream track {}", getIdentifier()); - - localExecutor.executeProcessingLoop(() -> { - try { - processTrackLoop(packetInputStream, localExecutor.getProcessingContext()); - } catch (IOException e) { - throw new FriendlyException("Stream broke when playing OGG track.", SUSPICIOUS, e); - } - }, null); - } - - private void processTrackLoop(OggPacketInputStream packetInputStream, AudioProcessingContext context) throws IOException, InterruptedException { - OggTrackHandler track = OggTrackLoader.loadTrackHandler(packetInputStream); - - if (track == null) { - throw new IOException("Stream terminated before the first packet."); - } - - while (track != null) { - try { - track.initialise(context); - track.provideFrames(); - } finally { - track.close(); - } - - track = OggTrackLoader.loadTrackHandler(packetInputStream); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggCodecHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggCodecHandler.java deleted file mode 100644 index 44a0fbb..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggCodecHandler.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg; - -import com.sedmelluq.discord.lavaplayer.tools.io.DirectBufferStreamBroker; - -import java.io.IOException; - -public interface OggCodecHandler { - boolean isMatchingIdentifier(int identifier); - - int getMaximumFirstPacketLength(); - - OggTrackHandler loadTrackHandler(OggPacketInputStream stream, DirectBufferStreamBroker broker) throws IOException; - - OggMetadata loadMetadata(OggPacketInputStream stream, DirectBufferStreamBroker broker) throws IOException; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggContainerProbe.java deleted file mode 100644 index a33164d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggContainerProbe.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.checkNextBytes; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.supportedFormat; -import static com.sedmelluq.discord.lavaplayer.container.ogg.OggPacketInputStream.OGG_PAGE_HEADER; - -/** - * Container detection probe for OGG stream. - */ -public class OggContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(OggContainerProbe.class); - - @Override - public String getName() { - return "ogg"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - return false; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream stream) throws IOException { - if (!checkNextBytes(stream, OGG_PAGE_HEADER)) { - return null; - } - - log.debug("Track {} is an OGG stream.", reference.identifier); - - AudioTrackInfoBuilder infoBuilder = AudioTrackInfoBuilder.create(reference, stream).setIsStream(true); - - try { - collectStreamInformation(stream, infoBuilder); - } catch (Exception e) { - log.warn("Failed to collect additional information on OGG stream.", e); - } - - return supportedFormat(this, null, infoBuilder.build()); - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - return new OggAudioTrack(trackInfo, inputStream); - } - - private void collectStreamInformation(SeekableInputStream stream, AudioTrackInfoBuilder infoBuilder) throws IOException { - OggPacketInputStream packetInputStream = new OggPacketInputStream(stream); - OggMetadata metadata = OggTrackLoader.loadMetadata(packetInputStream); - - if (metadata != null) { - infoBuilder.apply(metadata); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggMetadata.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggMetadata.java deleted file mode 100644 index 20f4326..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggMetadata.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg; - -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoProvider; - -import java.util.Collections; -import java.util.Map; - -/** - * Audio track info provider based on OGG metadata map. - */ -public class OggMetadata implements AudioTrackInfoProvider { - public static final OggMetadata EMPTY = new OggMetadata(Collections.emptyMap(), Long.MAX_VALUE); - - private static final String TITLE_FIELD = "TITLE"; - private static final String ARTIST_FIELD = "ARTIST"; - - private final Map tags; - - /** - * @param tags Map of OGG metadata with OGG-specific keys. - */ - public OggMetadata(Map tags, Long length) { - this.tags = tags; - } - - @Override - public String getTitle() { - return tags.get(TITLE_FIELD); - } - - @Override - public String getAuthor() { - return tags.get(ARTIST_FIELD); - } - - @Override - public Long getLength() { - return null; - } - - @Override - public String getIdentifier() { - return null; - } - - @Override - public String getUri() { - return null; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPacketInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPacketInputStream.java deleted file mode 100644 index f75ab82..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPacketInputStream.java +++ /dev/null @@ -1,336 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.tools.io.StreamTools; - -import java.io.*; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.checkNextBytes; - -/** - * This provides a stream for OGG packets where the stream is always bounded to the current packet, and the next packet - * can be started with startNewPacket(). The same way it is bound to a specific track and the next track can be started - * with startNewTrack() when the previous one has ended (startNewPacket() has returned false). - */ -public class OggPacketInputStream extends InputStream { - static final int[] OGG_PAGE_HEADER = new int[]{0x4F, 0x67, 0x67, 0x53}; - - private static final int SHORT_SCAN = 10240; - private static final int LONG_SCAN = 65307; - - private final SeekableInputStream inputStream; - private final DataInput dataInput; - private final int[] segmentSizes; - - private OggPageHeader pageHeader; - private int bytesLeftInPacket; - private boolean packetContinues; - private int nextPacketSegmentIndex; - private State state; - - /** - * @param inputStream Input stream to read in as OGG packets - */ - public OggPacketInputStream(SeekableInputStream inputStream) { - this.inputStream = inputStream; - this.dataInput = new DataInputStream(inputStream); - this.segmentSizes = new int[256]; - this.state = State.TRACK_BOUNDARY; - } - - /** - * Load the next track from the stream. This is only valid when the stream is in a track boundary state. - * - * @return True if next track is present in the stream, false if the stream has terminated. - */ - public boolean startNewTrack() { - if (state == State.TERMINATED) { - return false; - } else if (state != State.TRACK_BOUNDARY) { - throw new IllegalStateException("Cannot load the next track while the previous one has not been consumed."); - } - - pageHeader = null; - state = State.PACKET_BOUNDARY; - return true; - } - - /** - * Load the next packet from the stream. This is only valid when the stream is in a packet boundary state. - * - * @return True if next packet is present in the track. State is PACKET_READ. - * False if the track is finished. State is either TRACK_BOUNDARY or TERMINATED. - * @throws IOException On read error. - */ - public boolean startNewPacket() throws IOException { - if (state == State.TRACK_BOUNDARY) { - return false; - } else if (state != State.PACKET_BOUNDARY) { - throw new IllegalStateException("Cannot start a new packet while the previous one has not been consumed."); - } - - if ((pageHeader == null || nextPacketSegmentIndex == pageHeader.segmentCount) && !loadNextNonEmptyPage()) { - return false; - } - - if (!initialisePacket()) { - return loadNextNonEmptyPage(); - } - - return true; - } - - public boolean isPacketComplete() { - return state == State.PACKET_READ; - } - - private boolean readPageHeader() throws IOException { - if (!checkNextBytes(inputStream, OGG_PAGE_HEADER, false)) { - if (inputStream.read() == -1) { - return false; - } - - throw new IllegalStateException("Stream is not positioned at a page header."); - } else if ((dataInput.readByte() & 0xFF) != 0) { - throw new IllegalStateException("Unknown OGG stream version."); - } - - int flags = dataInput.readByte() & 0xFF; - long position = Long.reverseBytes(dataInput.readLong()); - int streamIdentifier = Integer.reverseBytes(dataInput.readInt()); - int pageSequence = Integer.reverseBytes(dataInput.readInt()); - int checksum = Integer.reverseBytes(dataInput.readInt()); - int segmentCount = dataInput.readByte() & 0xFF; - long byteStreamPosition = inputStream.getPosition() - 27; - - pageHeader = new OggPageHeader(flags, position, streamIdentifier, pageSequence, checksum, segmentCount, - byteStreamPosition); - - for (int i = 0; i < segmentCount; i++) { - segmentSizes[i] = dataInput.readByte() & 0xFF; - } - - return true; - } - - /** - * Load pages until a non-empty page is reached. Valid to call in states PACKET_BOUNDARY (page starts a new packet) or - * PACKET_READ (page starts with a continuation). - * - * @return True if a page belonging to the same track was loaded, state is PACKET_READ. - * False if the next page cannot be loaded because the current one ended the track, state is TRACK_BOUNDARY - * or TERMINATED. - * @throws IOException On read error. - */ - private boolean loadNextNonEmptyPage() throws IOException { - do { - if (!loadNextPage()) { - return false; - } - } while (pageHeader.segmentCount == 0); - - return true; - } - - /** - * Load the next page from the stream. Valid to call in states PACKET_BOUNDARY (page starts a new packet) or - * PACKET_READ (page starts with a continuation). - * - * @return True if a page belonging to the same track was loaded, state is PACKET_READ. - * False if the next page cannot be loaded because the current one ended the track, state is TRACK_BOUNDARY - * or TERMINATED. - * @throws IOException On read error. - */ - private boolean loadNextPage() throws IOException { - if (pageHeader != null && pageHeader.isLastPage) { - if (packetContinues) { - throw new IllegalStateException("Track finished in the middle of a packet."); - } - - state = State.TRACK_BOUNDARY; - return false; - } - - if (!readPageHeader()) { - if (packetContinues) { - throw new IllegalStateException("Stream ended in the middle of a packet."); - } - return false; - } - - nextPacketSegmentIndex = 0; - state = State.PACKET_READ; - return true; - } - - /** - * Initialise the (remainder of the) current packet in the stream. This may be called either to initialise a new - * packet or a continuation of the previous one. Call only in state PACKET_READ. - * - * @return Returns false if the remaining size of the packet was zero, state is PACKET_BOUNDARY. - * Returns true if the initialised packet has any bytes in it, state is PACKET_READ. - */ - private boolean initialisePacket() { - while (nextPacketSegmentIndex < pageHeader.segmentCount) { - int size = segmentSizes[nextPacketSegmentIndex++]; - bytesLeftInPacket += size; - - if (size < 255) { - // Anything below 255 is also a packet end marker. - if (bytesLeftInPacket == 0) { - // We reached packet end without getting any additional bytes, set state to packet boundary - state = State.PACKET_BOUNDARY; - return false; - } - - // We reached packet end and got some more bytes. - packetContinues = false; - return true; - } - } - - // Packet does not end within this page. - packetContinues = true; - return true; - } - - @Override - public int read() throws IOException { - if (bytesLeftInPacket == 0) { - return -1; - } - - int value = inputStream.read(); - if (value == -1) { - return -1; - } - - if (--bytesLeftInPacket == 0) { - continuePacket(); - } - - return value; - } - - @Override - public int read(byte[] buffer, int initialOffset, int length) throws IOException { - int currentOffset = initialOffset; - int maximumOffset = initialOffset + length; - - // Terminates when we have read as much as we needed - while (currentOffset < maximumOffset) { - // If there is nothing left in the current packet, stream is in EOF state - if (bytesLeftInPacket == 0) { - return -1; - } - - // Limit the read size to the number of bytes that are definitely still left in the packet - int chunk = Math.min(maximumOffset - currentOffset, bytesLeftInPacket); - int read = inputStream.read(buffer, currentOffset, chunk); - - if (read == -1) { - // EOF in the underlying stream before the end of a packet. Throw an exception, the consumer should not need - // to check for partial packets. - throw new EOFException("Underlying stream ended before the end of a packet."); - } - - currentOffset += read; - bytesLeftInPacket -= read; - - if (bytesLeftInPacket == 0) { - // We got everything from our chunk of size min(leftInPacket, requested) and also exhausted the bytes that we - // know the packet had left. Check if the packet continues so we could continue fetching from the same packet. - // Otherwise, bugger out. - - if (!continuePacket()) { - break; - } - } else if (read < chunk) { - // The underlying stream cannot provide more right now. Let it rest. - return currentOffset - initialOffset; - } - } - - return currentOffset - initialOffset; - } - - @Override - public int available() throws IOException { - if (state != State.PACKET_READ) { - return 0; - } - - return Math.min(inputStream.available(), bytesLeftInPacket); - } - - /** - * If it is possible to seek backwards on this stream, and the length of the stream is known, seeks to the end of the - * track to determine the stream length both in bytes and samples. - * - * @param sampleRate Sample rate of the track in this stream. - * @return OGG stream size information. - * @throws IOException On read error. - */ - public OggStreamSizeInfo seekForSizeInfo(int sampleRate) throws IOException { - if (!inputStream.canSeekHard()) { - return null; - } - - long savedPosition = inputStream.getPosition(); - - OggStreamSizeInfo sizeInfo = scanForSizeInfo(SHORT_SCAN, sampleRate); - - if (sizeInfo == null) { - sizeInfo = scanForSizeInfo(LONG_SCAN, sampleRate); - } - - inputStream.seek(savedPosition); - return sizeInfo; - } - - private OggStreamSizeInfo scanForSizeInfo(int tailLength, int sampleRate) throws IOException { - if (pageHeader == null) { - return null; - } - - long absoluteOffset = Math.max(pageHeader.byteStreamPosition, inputStream.getContentLength() - tailLength); - inputStream.seek(absoluteOffset); - - byte[] data = new byte[tailLength]; - int dataLength = StreamTools.readUntilEnd(inputStream, data, 0, data.length); - - return new OggPageScanner(absoluteOffset, data, dataLength).scanForSizeInfo(pageHeader.byteStreamPosition, - sampleRate); - } - - /** - * Process request for more bytes for the packet. Call only when the state is PACKET_READ. - * - * @return Returns false if no more bytes for the packet are available, state is PACKET_BOUNDARY. - * Returns true if more bytes were fetched for this packet, state is PACKET_READ. - * @throws IOException On read error. - */ - private boolean continuePacket() throws IOException { - if (!packetContinues) { - // We have reached the end of the packet. - state = State.PACKET_BOUNDARY; - return false; - } - - // Load more segments for this packet from the next page. - if (!loadNextNonEmptyPage()) { - throw new IllegalStateException("Track or stream end reached within an incomplete packet."); - } else if (!initialisePacket()) { - return false; - } - - return true; - } - - private enum State { - TRACK_BOUNDARY, - PACKET_BOUNDARY, - PACKET_READ, - TERMINATED - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPageHeader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPageHeader.java deleted file mode 100644 index 4e93489..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPageHeader.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg; - -/** - * Header of an OGG stream page. - */ -public class OggPageHeader { - public static final int FLAG_CONTINUATION = 0x01; - public static final int FLAG_FIRST_PAGE = 0x02; - public static final int FLAG_LAST_PAGE = 0x04; - - /** - * If this page starts in the middle of a packet that was left incomplete in the previous page. - */ - public final boolean isContinuation; - /** - * If this is the first page of the track. - */ - public final boolean isFirstPage; - /** - * If this is the last page of the track. - */ - public final boolean isLastPage; - /** - * The absolute position in the number of samples of this packet relative to the track start. - */ - public final long absolutePosition; - /** - * Unique identifier of this track in the stream. - */ - public final int streamIdentifier; - /** - * The index of the page within a track. - */ - public final int pageSequence; - /** - * The checksum of the page. - */ - public final int pageChecksum; - /** - * Number of segments in the page. - */ - public final int segmentCount; - /** - * The absolute position of the start of this page in the underlying bytestream. - */ - public final long byteStreamPosition; - - /** - * @param flags Page flags. - * @param absolutePosition The absolute position in the number of samples of this packet relative to the track start. - * @param streamIdentifier Unique identifier of this track in the stream. - * @param pageSequence The index of the page within a track. - * @param checksum The checksum of the page. - * @param segmentCount Number of segments in the page. - * @param byteStreamPosition The absolute position in bytes of this page in the stream. - */ - public OggPageHeader(int flags, long absolutePosition, int streamIdentifier, int pageSequence, int checksum, - int segmentCount, long byteStreamPosition) { - - this.isContinuation = (flags & FLAG_CONTINUATION) != 0; - this.isFirstPage = (flags & FLAG_FIRST_PAGE) != 0; - this.isLastPage = (flags & FLAG_LAST_PAGE) != 0; - this.absolutePosition = absolutePosition; - this.streamIdentifier = streamIdentifier; - this.pageSequence = pageSequence; - this.pageChecksum = checksum; - this.segmentCount = segmentCount; - this.byteStreamPosition = byteStreamPosition; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPageScanner.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPageScanner.java deleted file mode 100644 index ef1a4aa..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggPageScanner.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg; - -import java.nio.ByteBuffer; - -/** - * Scanner for determining OGG stream information by seeking around in it. - */ -public class OggPageScanner { - private static final int OGG_PAGE_HEADER_INT = ByteBuffer.wrap(new byte[]{0x4F, 0x67, 0x67, 0x53}).getInt(0); - - private final long absoluteOffset; - private final byte[] data; - private final int dataLength; - - private int flags; - private long reversedPosition; - private int pageSize; - private long byteStreamPosition; - - /** - * @param absoluteOffset Current position of the stream in bytes. - * @param data Byte array with data starting at that position. - * @param dataLength Length of data. - */ - public OggPageScanner(long absoluteOffset, byte[] data, int dataLength) { - this.absoluteOffset = absoluteOffset; - this.data = data; - this.dataLength = dataLength; - } - - /** - * @param firstPageOffset Absolute position of the first page in the stream. - * @param sampleRate Sample rate of the track in the stream. - * @return If the data contains the header of the last page in the OGG stream, then stream size information, - * otherwise null. - */ - public OggStreamSizeInfo scanForSizeInfo(long firstPageOffset, int sampleRate) { - ByteBuffer buffer = ByteBuffer.wrap(data, 0, dataLength); - int head = buffer.getInt(0); - - for (int i = 0; i < dataLength - 27; i++) { - if (head == OGG_PAGE_HEADER_INT) { - buffer.position(i); - - if (attemptReadHeader(buffer)) { - do { - if ((flags & OggPageHeader.FLAG_LAST_PAGE) != 0) { - return new OggStreamSizeInfo((byteStreamPosition - firstPageOffset) + pageSize, - Long.reverseBytes(reversedPosition), firstPageOffset, byteStreamPosition, sampleRate); - } - } while (attemptReadHeader(buffer)); - } - } - - head <<= 8; - head |= data[i + 4] & 0xFF; - } - - return null; - } - - private boolean attemptReadHeader(ByteBuffer buffer) { - int start = buffer.position(); - - if (buffer.limit() < start + 27) { - return false; - } else if (buffer.getInt(start) != OGG_PAGE_HEADER_INT) { - return false; - } else if (buffer.get(start + 4) != 0) { - return false; - } - - int segmentCount = buffer.get(start + 26) & 0xFF; - int minimumCapacity = start + segmentCount + 27; - - if (buffer.limit() < minimumCapacity) { - return false; - } - - int segmentBase = start + 27; - - for (int i = 0; i < segmentCount; i++) { - minimumCapacity += buffer.get(segmentBase + i) & 0xFF; - } - - if (buffer.limit() < minimumCapacity) { - return false; - } - - flags = buffer.get(start + 5) & 0xFF; - reversedPosition = buffer.getLong(start + 6); - byteStreamPosition = absoluteOffset + start; - pageSize = minimumCapacity; - - buffer.position(minimumCapacity); - return true; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggStreamSizeInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggStreamSizeInfo.java deleted file mode 100644 index cb77888..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggStreamSizeInfo.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg; - -/** - * Describes the size information of an OGG stream. - */ -public class OggStreamSizeInfo { - /** - * Total number of bytes in the stream. - */ - public final long totalBytes; - /** - * Total number of samples in the stream. - */ - public final long totalSamples; - /** - * Absolute offset of the first page in the stream. - */ - public final long firstPageOffset; - /** - * Absolute offset of the last page in the stream. - */ - public final long lastPageOffset; - /** - * Sample rate of the track in this stream, useful for calculating duration in milliseconds. - */ - public final int sampleRate; - - /** - * @param totalBytes See {@link #totalBytes}. - * @param totalSamples See {@link #totalSamples}. - * @param firstPageOffset See {@link #firstPageOffset}. - * @param lastPageOffset See {@link #lastPageOffset}. - * @param sampleRate See {@link #sampleRate}. - */ - public OggStreamSizeInfo(long totalBytes, long totalSamples, long firstPageOffset, long lastPageOffset, - int sampleRate) { - - this.totalBytes = totalBytes; - this.totalSamples = totalSamples; - this.firstPageOffset = firstPageOffset; - this.lastPageOffset = lastPageOffset; - this.sampleRate = sampleRate; - } - - /** - * @return Duration calculated from size info in milliseconds (rounded down). - */ - public long getDuration() { - return totalSamples * 1000 / sampleRate; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggTrackHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggTrackHandler.java deleted file mode 100644 index deeed5c..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggTrackHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg; - -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.io.IOException; - -/** - * A handler for a specific codec for an OGG stream. - */ -public interface OggTrackHandler { - /** - * Initialises the track stream. - * - * @param context Configuration and output information for processing - * @throws IOException On read error. - */ - void initialise(AudioProcessingContext context) throws IOException; - - /** - * Decodes audio frames and sends them to frame consumer. - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void provideFrames() throws InterruptedException; - - /** - * Seeks to the specified timecode. - * - * @param timecode The timecode in milliseconds - */ - void seekToTimecode(long timecode); - - /** - * Free all resources associated to processing the track. - */ - void close(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggTrackLoader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggTrackLoader.java deleted file mode 100644 index 6d59650..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/OggTrackLoader.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg; - -import com.sedmelluq.discord.lavaplayer.container.ogg.flac.OggFlacCodecHandler; -import com.sedmelluq.discord.lavaplayer.container.ogg.opus.OggOpusCodecHandler; -import com.sedmelluq.discord.lavaplayer.container.ogg.vorbis.OggVorbisCodecHandler; -import com.sedmelluq.discord.lavaplayer.tools.io.DirectBufferStreamBroker; - -import java.io.IOException; -import java.util.stream.Stream; - -/** - * Track loader for an OGG packet stream. Automatically detects the track codec and loads the specific track handler. - */ -public class OggTrackLoader { - private static final OggCodecHandler[] TRACK_PROVIDERS = new OggCodecHandler[]{ - new OggOpusCodecHandler(), - new OggFlacCodecHandler(), - new OggVorbisCodecHandler() - }; - - private static final int MAXIMUM_FIRST_PACKET_LENGTH = Stream.of(TRACK_PROVIDERS) - .mapToInt(OggCodecHandler::getMaximumFirstPacketLength).max().getAsInt(); - - /** - * @param packetInputStream OGG packet input stream - * @return The track handler detected from this packet input stream. Returns null if the stream ended. - * @throws IOException On read error - * @throws IllegalStateException If the track uses an unknown codec. - */ - public static OggTrackHandler loadTrackHandler(OggPacketInputStream packetInputStream) throws IOException { - CodecDetection result = detectCodec(packetInputStream); - return result != null ? result.provider.loadTrackHandler(packetInputStream, result.broker) : null; - } - - public static OggMetadata loadMetadata(OggPacketInputStream packetInputStream) throws IOException { - CodecDetection result = detectCodec(packetInputStream); - return result != null ? result.provider.loadMetadata(packetInputStream, result.broker) : null; - } - - private static CodecDetection detectCodec(OggPacketInputStream stream) throws IOException { - if (!stream.startNewTrack() || !stream.startNewPacket()) { - return null; - } - - DirectBufferStreamBroker broker = new DirectBufferStreamBroker(1024); - int maximumLength = MAXIMUM_FIRST_PACKET_LENGTH + 1; - - if (!broker.consumeNext(stream, maximumLength, maximumLength)) { - throw new IOException("First packet is too large for any known OGG codec."); - } - - int headerIdentifier = broker.getBuffer().getInt(); - - for (OggCodecHandler trackProvider : TRACK_PROVIDERS) { - if (trackProvider.isMatchingIdentifier(headerIdentifier)) { - return new CodecDetection(trackProvider, broker); - } - } - - throw new IllegalStateException("Unsupported track in OGG stream."); - } - - private static class CodecDetection { - private final OggCodecHandler provider; - private final DirectBufferStreamBroker broker; - - private CodecDetection(OggCodecHandler provider, DirectBufferStreamBroker broker) { - this.provider = provider; - this.broker = broker; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/flac/OggFlacCodecHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/flac/OggFlacCodecHandler.java deleted file mode 100644 index 1e338da..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/flac/OggFlacCodecHandler.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg.flac; - -import com.sedmelluq.discord.lavaplayer.container.flac.*; -import com.sedmelluq.discord.lavaplayer.container.ogg.*; -import com.sedmelluq.discord.lavaplayer.tools.io.ByteBufferInputStream; -import com.sedmelluq.discord.lavaplayer.tools.io.DirectBufferStreamBroker; - -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * Loader for an OGG FLAC track from an OGG packet stream. - */ -public class OggFlacCodecHandler implements OggCodecHandler { - private static final int FLAC_IDENTIFIER = ByteBuffer.wrap(new byte[]{0x7F, 'F', 'L', 'A'}).getInt(); - - private static final int NATIVE_FLAC_HEADER_OFFSET = 9; - private static final int NATIVE_FLAC_HEADER = ByteBuffer.wrap(new byte[]{'f', 'L', 'a', 'C'}).getInt(); - - @Override - public boolean isMatchingIdentifier(int identifier) { - return identifier == FLAC_IDENTIFIER; - } - - @Override - public int getMaximumFirstPacketLength() { - return NATIVE_FLAC_HEADER_OFFSET + 4 + FlacMetadataHeader.LENGTH + FlacStreamInfo.LENGTH; - } - - @Override - public OggTrackHandler loadTrackHandler(OggPacketInputStream stream, DirectBufferStreamBroker broker) throws IOException { - return new OggFlacTrackHandler(load(stream, broker), stream); - } - - @Override - public OggMetadata loadMetadata(OggPacketInputStream stream, DirectBufferStreamBroker broker) throws IOException { - FlacTrackInfo info = load(stream, broker); - return new OggMetadata(info.tags, detectLength(info, stream)); - } - - private FlacTrackInfo load(OggPacketInputStream stream, DirectBufferStreamBroker broker) throws IOException { - ByteBuffer buffer = broker.getBuffer(); - - if (buffer.getInt(NATIVE_FLAC_HEADER_OFFSET) != NATIVE_FLAC_HEADER) { - throw new IllegalStateException("Native flac header not found."); - } - - buffer.position(NATIVE_FLAC_HEADER_OFFSET + 4); - - return readHeaders(buffer, stream); - } - - private Long detectLength(FlacTrackInfo info, OggPacketInputStream stream) throws IOException { - OggStreamSizeInfo sizeInfo; - - if (info.stream.sampleCount > 0) { - sizeInfo = new OggStreamSizeInfo(0, info.stream.sampleCount, 0, 0, info.stream.sampleRate); - } else { - sizeInfo = stream.seekForSizeInfo(info.stream.sampleRate); - } - - return sizeInfo != null ? sizeInfo.getDuration() : null; - } - - private FlacTrackInfo readHeaders(ByteBuffer firstPacketBuffer, OggPacketInputStream packetInputStream) throws IOException { - FlacStreamInfo streamInfo = FlacMetadataReader.readStreamInfoBlock(new DataInputStream(new ByteBufferInputStream(firstPacketBuffer))); - FlacTrackInfoBuilder trackInfoBuilder = new FlacTrackInfoBuilder(streamInfo); - - DataInputStream dataInputStream = new DataInputStream(packetInputStream); - - boolean hasMoreMetadata = trackInfoBuilder.getStreamInfo().hasMetadataBlocks; - - while (hasMoreMetadata) { - if (!packetInputStream.startNewPacket()) { - throw new IllegalStateException("Track ended when more metadata was expected."); - } - - hasMoreMetadata = FlacMetadataReader.readMetadataBlock(dataInputStream, packetInputStream, trackInfoBuilder); - } - - return trackInfoBuilder.build(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/flac/OggFlacTrackHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/flac/OggFlacTrackHandler.java deleted file mode 100644 index 45b47d4..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/flac/OggFlacTrackHandler.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg.flac; - -import com.sedmelluq.discord.lavaplayer.container.flac.FlacTrackInfo; -import com.sedmelluq.discord.lavaplayer.container.flac.frame.FlacFrameReader; -import com.sedmelluq.discord.lavaplayer.container.ogg.OggPacketInputStream; -import com.sedmelluq.discord.lavaplayer.container.ogg.OggTrackHandler; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipeline; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipelineFactory; -import com.sedmelluq.discord.lavaplayer.filter.PcmFormat; -import com.sedmelluq.discord.lavaplayer.tools.io.BitStreamReader; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.io.IOException; - -/** - * OGG stream handler for FLAC codec. - */ -public class OggFlacTrackHandler implements OggTrackHandler { - private final FlacTrackInfo info; - private final OggPacketInputStream packetInputStream; - private final BitStreamReader bitStreamReader; - private final int[] decodingBuffer; - private final int[][] rawSampleBuffers; - private final short[][] sampleBuffers; - private AudioPipeline downstream; - - /** - * @param info FLAC track info - * @param packetInputStream OGG packet input stream - */ - public OggFlacTrackHandler(FlacTrackInfo info, OggPacketInputStream packetInputStream) { - this.info = info; - this.packetInputStream = packetInputStream; - this.bitStreamReader = new BitStreamReader(packetInputStream); - this.decodingBuffer = new int[FlacFrameReader.TEMPORARY_BUFFER_SIZE]; - this.rawSampleBuffers = new int[info.stream.channelCount][]; - this.sampleBuffers = new short[info.stream.channelCount][]; - - for (int i = 0; i < rawSampleBuffers.length; i++) { - rawSampleBuffers[i] = new int[info.stream.maximumBlockSize]; - sampleBuffers[i] = new short[info.stream.maximumBlockSize]; - } - } - - @Override - public void initialise(AudioProcessingContext context) { - downstream = AudioPipelineFactory.create(context, - new PcmFormat(info.stream.channelCount, info.stream.sampleRate)); - } - - @Override - public void provideFrames() throws InterruptedException { - try { - while (packetInputStream.startNewPacket()) { - int sampleCount = readFlacFrame(); - - if (sampleCount == 0) { - throw new IllegalStateException("Not enough bytes in packet."); - } - - downstream.process(sampleBuffers, 0, sampleCount); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private int readFlacFrame() throws IOException { - return FlacFrameReader.readFlacFrame(packetInputStream, bitStreamReader, info.stream, rawSampleBuffers, sampleBuffers, decodingBuffer); - } - - @Override - public void seekToTimecode(long timecode) { - throw new UnsupportedOperationException(); - } - - @Override - public void close() { - if (downstream != null) { - downstream.close(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/opus/OggOpusCodecHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/opus/OggOpusCodecHandler.java deleted file mode 100644 index 30447c0..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/opus/OggOpusCodecHandler.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg.opus; - -import com.sedmelluq.discord.lavaplayer.container.ogg.*; -import com.sedmelluq.discord.lavaplayer.container.ogg.vorbis.VorbisCommentParser; -import com.sedmelluq.discord.lavaplayer.tools.io.DirectBufferStreamBroker; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Collections; -import java.util.Map; - -/** - * Loader for Opus track providers from an OGG stream. - */ -public class OggOpusCodecHandler implements OggCodecHandler { - private static final int OPUS_IDENTIFIER = ByteBuffer.wrap(new byte[]{'O', 'p', 'u', 's'}).getInt(); - private static final int HEAD_TAG_HALF = ByteBuffer.wrap(new byte[]{'H', 'e', 'a', 'd'}).getInt(); - - private static final int OPUS_TAG_HALF = ByteBuffer.wrap(new byte[]{'O', 'p', 'u', 's'}).getInt(); - private static final int TAGS_TAG_HALF = ByteBuffer.wrap(new byte[]{'T', 'a', 'g', 's'}).getInt(); - - private static final int MAX_COMMENTS_SAVED_LENGTH = 1024 * 60; // 60 KB - private static final int MAX_COMMENTS_READ_LENGTH = 1024 * 1024 * 120; // 120 MB - - @Override - public boolean isMatchingIdentifier(int identifier) { - return identifier == OPUS_IDENTIFIER; - } - - @Override - public int getMaximumFirstPacketLength() { - return 276; - } - - @Override - public OggTrackHandler loadTrackHandler(OggPacketInputStream stream, DirectBufferStreamBroker broker) throws IOException { - ByteBuffer firstPacket = broker.getBuffer(); - verifyFirstPacket(firstPacket); - - loadCommentsHeader(stream, broker, true); - - int channelCount = firstPacket.get(9) & 0xFF; - return new OggOpusTrackHandler(stream, broker, channelCount, getSampleRate(firstPacket)); - } - - @Override - public OggMetadata loadMetadata(OggPacketInputStream stream, DirectBufferStreamBroker broker) throws IOException { - ByteBuffer firstPacket = broker.getBuffer(); - verifyFirstPacket(firstPacket); - - loadCommentsHeader(stream, broker, false); - - return new OggMetadata( - parseTags(broker.getBuffer(), broker.isTruncated()), - detectLength(stream, getSampleRate(firstPacket)) - ); - } - - private Map parseTags(ByteBuffer tagBuffer, boolean truncated) { - if (tagBuffer.getInt() != OPUS_TAG_HALF || tagBuffer.getInt() != TAGS_TAG_HALF) { - return Collections.emptyMap(); - } - - return VorbisCommentParser.parse(tagBuffer, truncated); - } - - private Long detectLength(OggPacketInputStream stream, int sampleRate) throws IOException { - OggStreamSizeInfo sizeInfo = stream.seekForSizeInfo(sampleRate); - - if (sizeInfo != null) { - return sizeInfo.totalSamples * 1000 / sizeInfo.sampleRate; - } else { - return null; - } - } - - private void verifyFirstPacket(ByteBuffer firstPacket) { - if (firstPacket.getInt(4) != HEAD_TAG_HALF) { - throw new IllegalStateException("First packet is not an OpusHead."); - } - } - - private int getSampleRate(ByteBuffer firstPacket) { - return Integer.reverseBytes(firstPacket.getInt(12)); - } - - private void loadCommentsHeader(OggPacketInputStream stream, DirectBufferStreamBroker broker, boolean skip) - throws IOException { - - if (!stream.startNewPacket()) { - throw new IllegalStateException("No OpusTags packet in track."); - } else if (!broker.consumeNext(stream, skip ? 0 : MAX_COMMENTS_SAVED_LENGTH, MAX_COMMENTS_READ_LENGTH)) { - if (!stream.isPacketComplete()) { - throw new IllegalStateException("Opus comments header packet longer than allowed."); - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/opus/OggOpusTrackHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/opus/OggOpusTrackHandler.java deleted file mode 100644 index 9942e06..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/opus/OggOpusTrackHandler.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg.opus; - -import com.sedmelluq.discord.lavaplayer.container.common.OpusPacketRouter; -import com.sedmelluq.discord.lavaplayer.container.ogg.OggPacketInputStream; -import com.sedmelluq.discord.lavaplayer.container.ogg.OggTrackHandler; -import com.sedmelluq.discord.lavaplayer.tools.io.DirectBufferStreamBroker; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * OGG stream handler for Opus codec. - */ -public class OggOpusTrackHandler implements OggTrackHandler { - private final OggPacketInputStream packetInputStream; - private final DirectBufferStreamBroker broker; - private final int channelCount; - private final int sampleRate; - private OpusPacketRouter opusPacketRouter; - - /** - * @param packetInputStream OGG packet input stream - * @param broker Broker for loading stream data into direct byte buffer. - * @param channelCount Number of channels in the track. - * @param sampleRate Sample rate of the track. - */ - public OggOpusTrackHandler(OggPacketInputStream packetInputStream, DirectBufferStreamBroker broker, int channelCount, - int sampleRate) { - - this.packetInputStream = packetInputStream; - this.broker = broker; - this.channelCount = channelCount; - this.sampleRate = sampleRate; - } - - @Override - public void initialise(AudioProcessingContext context) { - opusPacketRouter = new OpusPacketRouter(context, sampleRate, channelCount); - } - - @Override - public void provideFrames() throws InterruptedException { - try { - while (packetInputStream.startNewPacket()) { - broker.consumeNext(packetInputStream, Integer.MAX_VALUE, Integer.MAX_VALUE); - - ByteBuffer buffer = broker.getBuffer(); - - if (buffer.remaining() > 0) { - opusPacketRouter.process(buffer); - } - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void seekToTimecode(long timecode) { - throw new UnsupportedOperationException(); - } - - @Override - public void close() { - if (opusPacketRouter != null) { - opusPacketRouter.close(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/OggVorbisCodecHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/OggVorbisCodecHandler.java deleted file mode 100644 index 6821d3c..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/OggVorbisCodecHandler.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg.vorbis; - -import com.sedmelluq.discord.lavaplayer.container.ogg.OggCodecHandler; -import com.sedmelluq.discord.lavaplayer.container.ogg.OggMetadata; -import com.sedmelluq.discord.lavaplayer.container.ogg.OggPacketInputStream; -import com.sedmelluq.discord.lavaplayer.container.ogg.OggTrackHandler; -import com.sedmelluq.discord.lavaplayer.tools.io.DirectBufferStreamBroker; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Arrays; - -public class OggVorbisCodecHandler implements OggCodecHandler { - private static final int VORBIS_IDENTIFIER = ByteBuffer.wrap(new byte[]{0x01, 'v', 'o', 'r'}).getInt(); - - // These are arbitrary - there is no limit specified in Vorbis specification, Opus limit used as reference. - private static final int MAX_COMMENTS_SAVED_LENGTH = 1024 * 128; // 128 KB - private static final int MAX_COMMENTS_READ_LENGTH = 1024 * 1024 * 120; // 120 MB - - private static final byte[] COMMENT_PACKET_START = new byte[]{0x03, 'v', 'o', 'r', 'b', 'i', 's'}; - - @Override - public boolean isMatchingIdentifier(int identifier) { - return identifier == VORBIS_IDENTIFIER; - } - - @Override - public int getMaximumFirstPacketLength() { - return 64; - } - - @Override - public OggTrackHandler loadTrackHandler(OggPacketInputStream stream, DirectBufferStreamBroker broker) throws IOException { - byte[] infoPacket = broker.extractBytes(); - loadCommentsHeader(stream, broker, true); - return new OggVorbisTrackHandler(infoPacket, stream, broker); - } - - @Override - public OggMetadata loadMetadata(OggPacketInputStream stream, DirectBufferStreamBroker broker) throws IOException { - loadCommentsHeader(stream, broker, false); - - ByteBuffer commentsPacket = broker.getBuffer(); - byte[] packetStart = new byte[COMMENT_PACKET_START.length]; - commentsPacket.get(packetStart); - - if (!Arrays.equals(packetStart, COMMENT_PACKET_START)) { - return OggMetadata.EMPTY; - } - - return new OggMetadata(VorbisCommentParser.parse(commentsPacket, broker.isTruncated()), null); - } - - private void loadCommentsHeader(OggPacketInputStream stream, DirectBufferStreamBroker broker, boolean skip) - throws IOException { - - if (!stream.startNewPacket()) { - throw new IllegalStateException("No comments packet in track."); - } else if (!broker.consumeNext(stream, skip ? 0 : MAX_COMMENTS_SAVED_LENGTH, MAX_COMMENTS_READ_LENGTH)) { - if (!stream.isPacketComplete()) { - throw new IllegalStateException("Vorbis comments header packet longer than allowed."); - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/OggVorbisTrackHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/OggVorbisTrackHandler.java deleted file mode 100644 index 2ec9646..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/OggVorbisTrackHandler.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg.vorbis; - -import com.sedmelluq.discord.lavaplayer.container.ogg.OggPacketInputStream; -import com.sedmelluq.discord.lavaplayer.container.ogg.OggTrackHandler; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipeline; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipelineFactory; -import com.sedmelluq.discord.lavaplayer.filter.PcmFormat; -import com.sedmelluq.discord.lavaplayer.natives.vorbis.VorbisDecoder; -import com.sedmelluq.discord.lavaplayer.tools.io.DirectBufferStreamBroker; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * OGG stream handler for Vorbis codec. - */ -public class OggVorbisTrackHandler implements OggTrackHandler { - private static final int PCM_BUFFER_SIZE = 4096; - - private final byte[] infoPacket; - private final OggPacketInputStream packetInputStream; - private final DirectBufferStreamBroker broker; - private final VorbisDecoder decoder; - private final int sampleRate; - private float[][] channelPcmBuffers; - private AudioPipeline downstream; - - /** - * @param packetInputStream OGG packet input stream - * @param broker Broker for loading stream data into direct byte buffer, it has already loaded the first two packets - * (info and comments) and should be in the state where we should request the next - the setup packet. - */ - public OggVorbisTrackHandler(byte[] infoPacket, OggPacketInputStream packetInputStream, - DirectBufferStreamBroker broker) { - - this.infoPacket = infoPacket; - this.packetInputStream = packetInputStream; - this.broker = broker; - this.decoder = new VorbisDecoder(); - - ByteBuffer infoBuffer = ByteBuffer.wrap(infoPacket); - this.sampleRate = Integer.reverseBytes(infoBuffer.getInt(12)); - - int channelCount = infoBuffer.get(11) & 0xFF; - channelPcmBuffers = new float[channelCount][]; - - for (int i = 0; i < channelPcmBuffers.length; i++) { - channelPcmBuffers[i] = new float[PCM_BUFFER_SIZE]; - } - } - - @Override - public void initialise(AudioProcessingContext context) throws IOException { - ByteBuffer infoBuffer = ByteBuffer.allocateDirect(infoPacket.length); - infoBuffer.put(infoPacket); - infoBuffer.flip(); - - if (!packetInputStream.startNewPacket()) { - throw new IllegalStateException("End of track before header setup header."); - } - - broker.consumeNext(packetInputStream, Integer.MAX_VALUE, Integer.MAX_VALUE); - decoder.initialise(infoBuffer, broker.getBuffer()); - - broker.resetAndCompact(); - - downstream = AudioPipelineFactory.create(context, new PcmFormat(decoder.getChannelCount(), sampleRate)); - } - - @Override - public void provideFrames() throws InterruptedException { - try { - while (packetInputStream.startNewPacket()) { - broker.consumeNext(packetInputStream, Integer.MAX_VALUE, Integer.MAX_VALUE); - provideFromBuffer(broker.getBuffer()); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void provideFromBuffer(ByteBuffer buffer) throws InterruptedException { - decoder.input(buffer); - int output; - - do { - output = decoder.output(channelPcmBuffers); - - if (output > 0) { - downstream.process(channelPcmBuffers, 0, output); - } - } while (output == PCM_BUFFER_SIZE); - } - - @Override - public void seekToTimecode(long timecode) { - throw new UnsupportedOperationException(); - } - - @Override - public void close() { - if (downstream != null) { - downstream.close(); - } - - decoder.close(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/VorbisCommentParser.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/VorbisCommentParser.java deleted file mode 100644 index 4145590..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/ogg/vorbis/VorbisCommentParser.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.ogg.vorbis; - -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; - -import static java.nio.charset.StandardCharsets.UTF_8; - -public class VorbisCommentParser { - public static Map parse(ByteBuffer tagBuffer, boolean truncated) { - Map tags = new HashMap<>(); - - int vendorLength = Integer.reverseBytes(tagBuffer.getInt()); - if (vendorLength < 0) { - throw new IllegalStateException("Ogg comments vendor length is negative."); - } - - tagBuffer.position(tagBuffer.position() + vendorLength); - - int itemCount = Integer.reverseBytes(tagBuffer.getInt()); - - for (int itemIndex = 0; itemIndex < itemCount; itemIndex++) { - if (tagBuffer.remaining() < Integer.BYTES) { - if (!truncated) { - throw new IllegalArgumentException("Invalid tag buffer - tag size field out of bounds."); - } else { - // The buffer is truncated, it may cut off at an arbitrary point. - break; - } - } - - int itemLength = Integer.reverseBytes(tagBuffer.getInt()); - - if (itemLength < 0) { - throw new IllegalStateException("Ogg comments tag item length is negative."); - } else if (tagBuffer.remaining() < itemLength) { - if (!truncated) { - throw new IllegalArgumentException("Invalid tag buffer - tag size field out of bounds."); - } else { - // The buffer is truncated, it may cut off at an arbitrary point. - break; - } - } - - byte[] data = new byte[itemLength]; - tagBuffer.get(data); - - storeTagToMap(tags, data); - } - - return tags; - } - - private static void storeTagToMap(Map tags, byte[] data) { - for (int i = 0; i < data.length; i++) { - if (data[i] == '=') { - tags.put(new String(data, 0, i, UTF_8), new String(data, i + 1, data.length - i - 1, UTF_8)); - break; - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/HlsStreamSegmentUrlProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/HlsStreamSegmentUrlProvider.java deleted file mode 100644 index 93f1de6..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/HlsStreamSegmentUrlProvider.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.playlists; - -import com.sedmelluq.discord.lavaplayer.source.stream.ExtendedM3uParser; -import com.sedmelluq.discord.lavaplayer.source.stream.M3uStreamSegmentUrlProvider; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.List; - -import static com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools.fetchResponseLines; - -public class HlsStreamSegmentUrlProvider extends M3uStreamSegmentUrlProvider { - private static final Logger log = LoggerFactory.getLogger(HlsStreamSegmentUrlProvider.class); - - private final String streamListUrl; - private volatile String segmentPlaylistUrl; - - public HlsStreamSegmentUrlProvider(String streamListUrl, String segmentPlaylistUrl) { - this.streamListUrl = streamListUrl; - this.segmentPlaylistUrl = segmentPlaylistUrl; - } - - @Override - protected String getQualityFromM3uDirective(ExtendedM3uParser.Line directiveLine) { - return "default"; - } - - @Override - protected String fetchSegmentPlaylistUrl(HttpInterface httpInterface) throws IOException { - if (segmentPlaylistUrl != null) { - return segmentPlaylistUrl; - } - - HttpUriRequest request = new HttpGet(streamListUrl); - List streams = loadChannelStreamsList(fetchResponseLines(httpInterface, request, - "HLS stream list")); - - if (streams.isEmpty()) { - throw new IllegalStateException("No streams listed in HLS stream list."); - } - - ChannelStreamInfo stream = streams.get(0); - - log.debug("Chose stream with url {}", stream.quality, stream.url); - segmentPlaylistUrl = stream.url; - return segmentPlaylistUrl; - } - - @Override - protected HttpUriRequest createSegmentGetRequest(String url) { - return new HttpGet(url); - } - - public static String findHlsEntryUrl(String[] lines) { - List streams = new HlsStreamSegmentUrlProvider(null, null) - .loadChannelStreamsList(lines); - - return streams.isEmpty() ? null : streams.get(0).url; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/HlsStreamTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/HlsStreamTrack.java deleted file mode 100644 index 9260c1c..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/HlsStreamTrack.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.playlists; - -import com.sedmelluq.discord.lavaplayer.source.stream.M3uStreamAudioTrack; -import com.sedmelluq.discord.lavaplayer.source.stream.M3uStreamSegmentUrlProvider; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; - -public class HlsStreamTrack extends M3uStreamAudioTrack { - private final HlsStreamSegmentUrlProvider segmentUrlProvider; - private final HttpInterfaceManager httpInterfaceManager; - - /** - * @param trackInfo Track info - * @param httpInterfaceManager - */ - public HlsStreamTrack(AudioTrackInfo trackInfo, String streamUrl, HttpInterfaceManager httpInterfaceManager, - boolean isInnerUrl) { - - super(trackInfo); - - segmentUrlProvider = isInnerUrl ? - new HlsStreamSegmentUrlProvider(null, streamUrl) : - new HlsStreamSegmentUrlProvider(streamUrl, null); - - this.httpInterfaceManager = httpInterfaceManager; - } - - @Override - protected M3uStreamSegmentUrlProvider getSegmentUrlProvider() { - return segmentUrlProvider; - } - - @Override - protected HttpInterface getHttpInterface() { - return httpInterfaceManager.getInterface(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/M3uPlaylistContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/M3uPlaylistContainerProbe.java deleted file mode 100644 index a59b9b7..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/M3uPlaylistContainerProbe.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.playlists; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDescriptor; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.tools.io.ThreadLocalHttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.checkNextBytes; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.*; - -/** - * Probe for M3U playlist. - */ -public class M3uPlaylistContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(M3uPlaylistContainerProbe.class); - - private static final String TYPE_HLS_OUTER = "hls-outer"; - private static final String TYPE_HLS_INNER = "hls-inner"; - - private static final int[] M3U_HEADER_TAG = new int[]{'#', 'E', 'X', 'T', 'M', '3', 'U'}; - private static final int[] M3U_ENTRY_TAG = new int[]{'#', 'E', 'X', 'T', 'I', 'N', 'F'}; - - private final HttpInterfaceManager httpInterfaceManager = new ThreadLocalHttpInterfaceManager( - HttpClientTools - .createSharedCookiesHttpBuilder() - .setRedirectStrategy(new HttpClientTools.NoRedirectsStrategy()), - HttpClientTools.DEFAULT_REQUEST_CONFIG - ); - - @Override - public String getName() { - return "m3u"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - return false; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException { - if (!checkNextBytes(inputStream, M3U_HEADER_TAG) && !checkNextBytes(inputStream, M3U_ENTRY_TAG)) { - return null; - } - - log.debug("Track {} is an M3U playlist file.", reference.identifier); - String[] lines = DataFormatTools.streamToLines(inputStream, StandardCharsets.UTF_8); - - String hlsStreamUrl = HlsStreamSegmentUrlProvider.findHlsEntryUrl(lines); - - if (hlsStreamUrl != null) { - AudioTrackInfoBuilder infoBuilder = AudioTrackInfoBuilder.create(reference, inputStream); - AudioReference httpReference = HttpAudioSourceManager.getAsHttpReference(reference); - - if (httpReference != null) { - return supportedFormat(this, TYPE_HLS_OUTER, infoBuilder.setIdentifier(httpReference.identifier).build()); - } else { - return refer(this, new AudioReference(hlsStreamUrl, infoBuilder.getTitle(), - new MediaContainerDescriptor(this, TYPE_HLS_INNER))); - } - } - - MediaContainerDetectionResult result = loadSingleItemPlaylist(lines); - if (result != null) { - return result; - } - - return unsupportedFormat(this, "The playlist file contains no links."); - } - - private MediaContainerDetectionResult loadSingleItemPlaylist(String[] lines) { - String trackTitle = null; - - for (String line : lines) { - if (line.startsWith("#EXTINF")) { - trackTitle = extractTitleFromInfo(line); - } else if (!line.startsWith("#") && line.length() > 0) { - if (line.startsWith("http://") || line.startsWith("https://") || line.startsWith("icy://")) { - return refer(this, new AudioReference(line.trim(), trackTitle)); - } - - trackTitle = null; - } - } - - return null; - } - - private String extractTitleFromInfo(String infoLine) { - String[] splitInfo = infoLine.split(",", 2); - return splitInfo.length == 2 ? splitInfo[1] : null; - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - if (parameters.equals(TYPE_HLS_INNER)) { - return new HlsStreamTrack(trackInfo, trackInfo.identifier, httpInterfaceManager, true); - } else if (parameters.equals(TYPE_HLS_OUTER)) { - return new HlsStreamTrack(trackInfo, trackInfo.identifier, httpInterfaceManager, false); - } else { - throw new IllegalArgumentException("Unsupported parameters: " + parameters); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/PlainPlaylistContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/PlainPlaylistContainerProbe.java deleted file mode 100644 index 1e93b11..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/PlainPlaylistContainerProbe.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.playlists; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.STREAM_SCAN_DISTANCE; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.matchNextBytesAsRegex; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.refer; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.unsupportedFormat; - -/** - * Probe for a playlist containing the raw link without any format. - */ -public class PlainPlaylistContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(PlainPlaylistContainerProbe.class); - - private static final Pattern linkPattern = Pattern.compile("^(?:https?|icy)://.*"); - - @Override - public String getName() { - return "plain"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - return false; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException { - if (!matchNextBytesAsRegex(inputStream, STREAM_SCAN_DISTANCE, linkPattern, StandardCharsets.UTF_8)) { - return null; - } - - log.debug("Track {} is a plain playlist file.", reference.identifier); - return loadFromLines(DataFormatTools.streamToLines(inputStream, StandardCharsets.UTF_8)); - } - - private MediaContainerDetectionResult loadFromLines(String[] lines) { - for (String line : lines) { - Matcher matcher = linkPattern.matcher(line); - - if (matcher.matches()) { - return refer(this, new AudioReference(matcher.group(0), null)); - } - } - - return unsupportedFormat(this, "The playlist file contains no links."); - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - throw new UnsupportedOperationException(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/PlsPlaylistContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/PlsPlaylistContainerProbe.java deleted file mode 100644 index 47eb79d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/playlists/PlsPlaylistContainerProbe.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.playlists; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.UNKNOWN_TITLE; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.checkNextBytes; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.refer; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.unsupportedFormat; - -/** - * Probe for PLS playlist. - */ -public class PlsPlaylistContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(PlsPlaylistContainerProbe.class); - - private static final int[] PLS_HEADER = new int[]{'[', -1, 'l', 'a', 'y', 'l', 'i', 's', 't', ']'}; - - private static Pattern filePattern = Pattern.compile("\\s*File([0-9]+)=((?:https?|icy)://.*)\\s*"); - private static Pattern titlePattern = Pattern.compile("\\s*Title([0-9]+)=(.*)\\s*"); - - @Override - public String getName() { - return "pls"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - return false; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException { - if (!checkNextBytes(inputStream, PLS_HEADER)) { - return null; - } - - log.debug("Track {} is a PLS playlist file.", reference.identifier); - return loadFromLines(DataFormatTools.streamToLines(inputStream, StandardCharsets.UTF_8)); - } - - private MediaContainerDetectionResult loadFromLines(String[] lines) { - Map trackFiles = new HashMap<>(); - Map trackTitles = new HashMap<>(); - - for (String line : lines) { - Matcher fileMatcher = filePattern.matcher(line); - - if (fileMatcher.matches()) { - trackFiles.put(fileMatcher.group(1), fileMatcher.group(2)); - continue; - } - - Matcher titleMatcher = titlePattern.matcher(line); - if (titleMatcher.matches()) { - trackTitles.put(titleMatcher.group(1), titleMatcher.group(2)); - } - } - - for (Map.Entry entry : trackFiles.entrySet()) { - String title = trackTitles.get(entry.getKey()); - return refer(this, new AudioReference(entry.getValue(), title != null ? title : UNKNOWN_TITLE)); - } - - return unsupportedFormat(this, "The playlist file contains no links."); - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - throw new UnsupportedOperationException(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavAudioTrack.java deleted file mode 100644 index bf65652..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavAudioTrack.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.wav; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.BaseAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Audio track that handles a WAV stream - */ -public class WavAudioTrack extends BaseAudioTrack { - private static final Logger log = LoggerFactory.getLogger(WavAudioTrack.class); - - private final SeekableInputStream inputStream; - - /** - * @param trackInfo Track info - * @param inputStream Input stream for the WAV file - */ - public WavAudioTrack(AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - super(trackInfo); - - this.inputStream = inputStream; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - WavTrackProvider trackProvider = new WavFileLoader(inputStream).loadTrack(localExecutor.getProcessingContext()); - - try { - log.debug("Starting to play WAV track {}", getIdentifier()); - localExecutor.executeProcessingLoop(trackProvider::provideFrames, trackProvider::seekToTimecode); - } finally { - trackProvider.close(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavContainerProbe.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavContainerProbe.java deleted file mode 100644 index b72ccef..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavContainerProbe.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.wav; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerHints; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.*; -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.supportedFormat; -import static com.sedmelluq.discord.lavaplayer.container.wav.WavFileLoader.WAV_RIFF_HEADER; -import static com.sedmelluq.discord.lavaplayer.tools.DataFormatTools.defaultOnNull; - -/** - * Container detection probe for WAV format. - */ -public class WavContainerProbe implements MediaContainerProbe { - private static final Logger log = LoggerFactory.getLogger(WavContainerProbe.class); - - @Override - public String getName() { - return "wav"; - } - - @Override - public boolean matchesHints(MediaContainerHints hints) { - return false; - } - - @Override - public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException { - if (!checkNextBytes(inputStream, WAV_RIFF_HEADER)) { - return null; - } - - log.debug("Track {} is a WAV file.", reference.identifier); - - WavFileInfo fileInfo = new WavFileLoader(inputStream).parseHeaders(); - - return supportedFormat(this, null, new AudioTrackInfo( - defaultOnNull(reference.title, UNKNOWN_TITLE), - UNKNOWN_ARTIST, - fileInfo.getDuration(), - reference.identifier, - false, - reference.identifier - )); - } - - @Override - public AudioTrack createTrack(String parameters, AudioTrackInfo trackInfo, SeekableInputStream inputStream) { - return new WavAudioTrack(trackInfo, inputStream); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavFileInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavFileInfo.java deleted file mode 100644 index f6306bc..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavFileInfo.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.wav; - -/** - * WAV file format information. - */ -public class WavFileInfo { - /** - * Number of channels. - */ - public final int channelCount; - /** - * Sample rate. - */ - public final int sampleRate; - /** - * Bits per sample (currently only 16 supported). - */ - public final int bitsPerSample; - /** - * Size of a block (one sample for each channel + padding). - */ - public final int blockAlign; - /** - * Number of blocks in the file. - */ - public final long blockCount; - /** - * Starting position of the raw PCM samples in the file. - */ - public final long startOffset; - - /** - * @param channelCount Number of channels. - * @param sampleRate Sample rate. - * @param bitsPerSample Bits per sample (currently only 16 supported). - * @param blockAlign Size of a block (one sample for each channel + padding). - * @param blockCount Number of blocks in the file. - * @param startOffset Starting position of the raw PCM samples in the file. - */ - public WavFileInfo(int channelCount, int sampleRate, int bitsPerSample, int blockAlign, long blockCount, long startOffset) { - this.channelCount = channelCount; - this.sampleRate = sampleRate; - this.bitsPerSample = bitsPerSample; - this.blockAlign = blockAlign; - this.blockCount = blockCount; - this.startOffset = startOffset; - } - - /** - * @return Duration of the file in milliseconds. - */ - public long getDuration() { - return blockCount * 1000L / sampleRate; - } - - /** - * @return The size of padding in a sample block in bytes. - */ - public int getPadding() { - return blockAlign - channelCount * (bitsPerSample >> 3); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavFileLoader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavFileLoader.java deleted file mode 100644 index c338c70..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavFileLoader.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.wav; - -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetection.checkNextBytes; - -/** - * Loads either WAV header information or a WAV track provider from a stream. - */ -public class WavFileLoader { - static final int[] WAV_RIFF_HEADER = new int[]{0x52, 0x49, 0x46, 0x46, -1, -1, -1, -1, 0x57, 0x41, 0x56, 0x45}; - - private final SeekableInputStream inputStream; - - /** - * @param inputStream Input stream to read the WAV data from. This must be positioned right before WAV RIFF header. - */ - public WavFileLoader(SeekableInputStream inputStream) { - this.inputStream = inputStream; - } - - /** - * Parses the headers of the file. - * - * @return Format description of the WAV file - * @throws IOException On read error - */ - public WavFileInfo parseHeaders() throws IOException { - if (!checkNextBytes(inputStream, WAV_RIFF_HEADER, false)) { - throw new IllegalStateException("Not a WAV header."); - } - - InfoBuilder builder = new InfoBuilder(); - DataInput dataInput = new DataInputStream(inputStream); - - while (true) { - String chunkName = readChunkName(dataInput); - long chunkSize = Integer.toUnsignedLong(Integer.reverseBytes(dataInput.readInt())); - - if ("fmt ".equals(chunkName)) { - readFormatChunk(builder, dataInput); - - if (chunkSize > 16) { - inputStream.skipFully(chunkSize - 16); - } - } else if ("data".equals(chunkName)) { - builder.sampleAreaSize = chunkSize; - builder.startOffset = inputStream.getPosition(); - return builder.build(); - } else { - inputStream.skipFully(chunkSize); - } - } - } - - private String readChunkName(DataInput dataInput) throws IOException { - byte[] buffer = new byte[4]; - dataInput.readFully(buffer); - return new String(buffer, StandardCharsets.US_ASCII); - } - - private void readFormatChunk(InfoBuilder builder, DataInput dataInput) throws IOException { - builder.audioFormat = Short.reverseBytes(dataInput.readShort()) & 0xFFFF; - builder.channelCount = Short.reverseBytes(dataInput.readShort()) & 0xFFFF; - builder.sampleRate = Integer.reverseBytes(dataInput.readInt()); - - // Skip bitrate - dataInput.readInt(); - - builder.blockAlign = Short.reverseBytes(dataInput.readShort()) & 0xFFFF; - builder.bitsPerSample = Short.reverseBytes(dataInput.readShort()) & 0xFFFF; - } - - /** - * Initialise a WAV track stream. - * - * @param context Configuration and output information for processing - * @return The WAV track stream which can produce frames. - * @throws IOException On read error - */ - public WavTrackProvider loadTrack(AudioProcessingContext context) throws IOException { - return new WavTrackProvider(context, inputStream, parseHeaders()); - } - - private static class InfoBuilder { - private int audioFormat; - private int channelCount; - private int sampleRate; - private int bitsPerSample; - private int blockAlign; - private long sampleAreaSize; - private long startOffset; - - private WavFileInfo build() { - validateFormat(); - validateAlignment(); - - return new WavFileInfo(channelCount, sampleRate, bitsPerSample, blockAlign, sampleAreaSize / blockAlign, startOffset); - } - - private void validateFormat() { - if (audioFormat != 1) { - throw new IllegalStateException("Invalid audio format " + audioFormat + ", must be 1 (PCM)"); - } else if (channelCount < 1 || channelCount > 16) { - throw new IllegalStateException("Invalid channel count: " + channelCount); - } else if (sampleRate < 100 || sampleRate > 384000) { - throw new IllegalStateException("Invalid sample rate: " + sampleRate); - } else if (bitsPerSample != 16) { - throw new IllegalStateException("Unsupported bits per sample: " + bitsPerSample); - } - } - - private void validateAlignment() { - int minimumBlockAlign = channelCount * (bitsPerSample >> 3); - - if (blockAlign < minimumBlockAlign || blockAlign > minimumBlockAlign + 32) { - throw new IllegalStateException("Block align is not valid: " + blockAlign); - } else if (blockAlign % (bitsPerSample >> 3) != 0) { - throw new IllegalStateException("Block align is not a multiple of bits per sample: " + blockAlign); - } else if (sampleAreaSize < 0) { - throw new IllegalStateException("Negative sample area size: " + sampleAreaSize); - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavTrackProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavTrackProvider.java deleted file mode 100644 index a6e0ba7..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/container/wav/WavTrackProvider.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.container.wav; - -import com.sedmelluq.discord.lavaplayer.filter.AudioPipeline; -import com.sedmelluq.discord.lavaplayer.filter.AudioPipelineFactory; -import com.sedmelluq.discord.lavaplayer.filter.PcmFormat; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -import static java.nio.ByteOrder.LITTLE_ENDIAN; - -/** - * A provider of audio frames from a WAV track. - */ -public class WavTrackProvider { - private static final int BLOCKS_IN_BUFFER = 4096; - - private final SeekableInputStream inputStream; - private final DataInput dataInput; - private final WavFileInfo info; - private final AudioPipeline downstream; - private final short[] buffer; - private final ShortBuffer nioBuffer; - private final byte[] rawBuffer; - - /** - * @param context Configuration and output information for processing - * @param inputStream Input stream to use - * @param info Information about the WAV file - */ - public WavTrackProvider(AudioProcessingContext context, SeekableInputStream inputStream, WavFileInfo info) { - this.inputStream = inputStream; - this.dataInput = new DataInputStream(inputStream); - this.info = info; - this.downstream = AudioPipelineFactory.create(context, new PcmFormat(info.channelCount, info.sampleRate)); - this.buffer = info.getPadding() > 0 ? new short[info.channelCount * BLOCKS_IN_BUFFER] : null; - - ByteBuffer byteBuffer = ByteBuffer.allocate(info.blockAlign * BLOCKS_IN_BUFFER).order(LITTLE_ENDIAN); - this.rawBuffer = byteBuffer.array(); - this.nioBuffer = byteBuffer.asShortBuffer(); - } - - /** - * Seeks to the specified timecode. - * - * @param timecode The timecode in milliseconds - */ - public void seekToTimecode(long timecode) { - try { - long fileOffset = (timecode * info.sampleRate / 1000L) * info.blockAlign + info.startOffset; - inputStream.seek(fileOffset); - downstream.seekPerformed(timecode, timecode); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Reads audio frames and sends them to frame consumer - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - public void provideFrames() throws InterruptedException { - try { - int blockCount; - - while ((blockCount = getNextChunkBlocks()) > 0) { - if (buffer != null) { - processChunkWithPadding(blockCount); - } else { - processChunk(blockCount); - } - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Free all resources associated to processing the track. - */ - public void close() { - downstream.close(); - } - - private void processChunkWithPadding(int blockCount) throws IOException, InterruptedException { - readChunkToBuffer(blockCount); - - int padding = info.getPadding() / 2; - int sampleCount = blockCount * info.channelCount; - int indexInBlock = 0; - - for (int i = 0; i < sampleCount; i++) { - buffer[i] = nioBuffer.get(); - - if (++indexInBlock == info.channelCount) { - nioBuffer.position(nioBuffer.position() + padding); - indexInBlock = 0; - } - } - - downstream.process(buffer, 0, blockCount * info.channelCount); - } - - private void processChunk(int blockCount) throws IOException, InterruptedException { - readChunkToBuffer(blockCount); - downstream.process(nioBuffer); - } - - private void readChunkToBuffer(int blockCount) throws IOException { - int bytesToRead = blockCount * info.blockAlign; - dataInput.readFully(rawBuffer, 0, bytesToRead); - - nioBuffer.position(0); - nioBuffer.limit(bytesToRead / 2); - } - - private int getNextChunkBlocks() { - long endOffset = info.startOffset + info.blockAlign * info.blockCount; - return (int) Math.min((endOffset - inputStream.getPosition()) / info.blockAlign, BLOCKS_IN_BUFFER); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioFilter.java deleted file mode 100644 index 876ea26..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioFilter.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -/** - * A filter for audio samples - */ -public interface AudioFilter { - /** - * Indicates that the next samples are not a continuation from the previous ones and gives the timecode for the - * next incoming sample. - * - * @param requestedTime Timecode in milliseconds to which the seek was requested to - * @param providedTime Timecode in milliseconds to which the seek was actually performed to - */ - void seekPerformed(long requestedTime, long providedTime); - - /** - * Flush everything to output. - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void flush() throws InterruptedException; - - /** - * Free all resources. No more input is expected. - */ - void close(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioFilterChain.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioFilterChain.java deleted file mode 100644 index f6ef08f..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioFilterChain.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import java.util.List; - -/** - * A chain of audio filters. - */ -public class AudioFilterChain { - /** - * The first filter in the stream. Separate field as unlike other filters, this must be an instance of - * {@link UniversalPcmAudioFilter} as the input data may be in any representation. - */ - public final UniversalPcmAudioFilter input; - - /** - * All filters in this chain. - */ - public final List filters; - - /** - * Immutable context/configuration instance that this filter was generated from. May be null. - */ - public final Object context; - - /** - * @param input See {@link #input}. - * @param filters See {@link #filters}. - * @param context See {@link #context}. - */ - public AudioFilterChain(UniversalPcmAudioFilter input, List filters, Object context) { - this.input = input; - this.filters = filters; - this.context = context; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPipeline.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPipeline.java deleted file mode 100644 index 4663e9c..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPipeline.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import java.nio.ShortBuffer; -import java.util.List; - -/** - * Represents an audio pipeline (top-level audio filter chain). - */ -public class AudioPipeline extends CompositeAudioFilter { - private final List filters; - private final UniversalPcmAudioFilter first; - - /** - * @param chain The top-level filter chain. - */ - public AudioPipeline(AudioFilterChain chain) { - this.filters = chain.filters; - this.first = chain.input; - } - - @Override - public void process(float[][] input, int offset, int length) throws InterruptedException { - first.process(input, offset, length); - } - - @Override - public void process(short[] input, int offset, int length) throws InterruptedException { - first.process(input, offset, length); - } - - @Override - public void process(ShortBuffer buffer) throws InterruptedException { - first.process(buffer); - } - - @Override - public void process(short[][] input, int offset, int length) throws InterruptedException { - first.process(input, offset, length); - } - - @Override - protected List getFilters() { - return filters; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPipelineFactory.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPipelineFactory.java deleted file mode 100644 index b747d4e..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPipelineFactory.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import com.sedmelluq.discord.lavaplayer.filter.volume.VolumePostProcessor; -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.format.transcoder.AudioChunkEncoder; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.util.Arrays; -import java.util.Collection; - -/** - * Factory for audio pipelines. Contains helper methods to determine whether an audio pipeline is even required. - */ -public class AudioPipelineFactory { - /** - * @param context Audio processing context to check output format from - * @param inputFormat Input format of the audio - * @return True if no audio processing is currently required with this context and input format combination. - */ - public static boolean isProcessingRequired(AudioProcessingContext context, AudioDataFormat inputFormat) { - return !context.outputFormat.equals(inputFormat) || context.playerOptions.volumeLevel.get() != 100 || - context.playerOptions.filterFactory.get() != null; - } - - /** - * Creates an audio pipeline instance based on provided settings. - * - * @param context Configuration and output information for processing - * @param inputFormat The parameters of the PCM input. - * @return A pipeline which delivers the input to the final frame destination. - */ - public static AudioPipeline create(AudioProcessingContext context, PcmFormat inputFormat) { - int inputChannels = inputFormat.channelCount; - int outputChannels = context.outputFormat.channelCount; - - UniversalPcmAudioFilter end = new FinalPcmAudioFilter(context, createPostProcessors(context)); - FilterChainBuilder builder = new FilterChainBuilder(); - builder.addFirst(end); - - if (context.filterHotSwapEnabled || context.playerOptions.filterFactory.get() != null) { - UserProvidedAudioFilters userFilters = new UserProvidedAudioFilters(context, end); - builder.addFirst(userFilters); - } - - if (inputFormat.sampleRate != context.outputFormat.sampleRate) { - builder.addFirst(new ResamplingPcmAudioFilter(context.configuration, outputChannels, - builder.makeFirstFloat(outputChannels), inputFormat.sampleRate, context.outputFormat.sampleRate)); - } - - if (inputChannels != outputChannels) { - builder.addFirst(new ChannelCountPcmAudioFilter(inputChannels, outputChannels, - builder.makeFirstUniversal(outputChannels))); - } - - return new AudioPipeline(builder.build(null, inputChannels)); - } - - private static Collection createPostProcessors(AudioProcessingContext context) { - AudioChunkEncoder chunkEncoder = context.outputFormat.createEncoder(context.configuration); - - return Arrays.asList( - new VolumePostProcessor(context), - new BufferingPostProcessor(context, chunkEncoder) - ); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPostProcessor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPostProcessor.java deleted file mode 100644 index 7b7583f..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/AudioPostProcessor.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import java.nio.ShortBuffer; - -/** - * Audio chunk post processor. - */ -public interface AudioPostProcessor { - /** - * Receives chunk buffer in its final PCM format with the sample count, sample rate and channel count matching that of - * the output format. - * - * @param timecode Absolute starting timecode of the chunk in milliseconds - * @param buffer PCM buffer of samples in the chunk - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void process(long timecode, ShortBuffer buffer) throws InterruptedException; - - /** - * Frees up all resources this processor is holding internally. - */ - void close(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/BufferingPostProcessor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/BufferingPostProcessor.java deleted file mode 100644 index 85fb312..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/BufferingPostProcessor.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import com.sedmelluq.discord.lavaplayer.format.transcoder.AudioChunkEncoder; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; -import com.sedmelluq.discord.lavaplayer.track.playback.MutableAudioFrame; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -/** - * Post processor which encodes audio chunks and passes them as audio frames to the frame buffer. - */ -public class BufferingPostProcessor implements AudioPostProcessor { - private final AudioProcessingContext context; - private final AudioChunkEncoder encoder; - private final MutableAudioFrame offeredFrame; - private final ByteBuffer outputBuffer; - - /** - * @param context Processing context to determine the destination buffer from. - * @param encoder Encoder to encode the chunk with. - */ - public BufferingPostProcessor(AudioProcessingContext context, AudioChunkEncoder encoder) { - this.encoder = encoder; - this.context = context; - this.offeredFrame = new MutableAudioFrame(); - this.outputBuffer = ByteBuffer.allocateDirect(context.outputFormat.maximumChunkSize()); - - offeredFrame.setFormat(context.outputFormat); - } - - @Override - public void process(long timecode, ShortBuffer buffer) throws InterruptedException { - outputBuffer.clear(); - encoder.encode(buffer, outputBuffer); - - offeredFrame.setTimecode(timecode); - offeredFrame.setVolume(context.playerOptions.volumeLevel.get()); - - offeredFrame.setBuffer(outputBuffer); - context.frameBuffer.consume(offeredFrame); - } - - @Override - public void close() { - encoder.close(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/ChannelCountPcmAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/ChannelCountPcmAudioFilter.java deleted file mode 100644 index 47f327e..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/ChannelCountPcmAudioFilter.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import java.nio.ShortBuffer; - -/** - * For short PCM buffers, guarantees that the output has the required number of channels and that no outgoing - * buffer contains any partial frames. - *

- * For example if the input is three channels, and output is two channels, then: - * in [0, 1, 2, 0, 1, 2, 0, 1] out [0, 1, 0, 1] saved [0, 1] - * in [2, 0, 1, 2] out [0, 1, 0, 1] saved [] - */ -public class ChannelCountPcmAudioFilter implements UniversalPcmAudioFilter { - private final UniversalPcmAudioFilter downstream; - private final int outputChannels; - private final ShortBuffer outputBuffer; - private final int inputChannels; - private final int commonChannels; - private final int channelsToAdd; - private final short[] inputSet; - private final float[][] splitFloatOutput; - private final short[][] splitShortOutput; - private int inputIndex; - - /** - * @param inputChannels Number of input channels - * @param outputChannels Number of output channels - * @param downstream The next filter in line - */ - public ChannelCountPcmAudioFilter(int inputChannels, int outputChannels, UniversalPcmAudioFilter downstream) { - this.downstream = downstream; - this.inputChannels = inputChannels; - this.outputChannels = outputChannels; - this.outputBuffer = ShortBuffer.allocate(2048 * inputChannels); - this.commonChannels = Math.min(outputChannels, inputChannels); - this.channelsToAdd = outputChannels - commonChannels; - this.inputSet = new short[inputChannels]; - this.splitFloatOutput = new float[outputChannels][]; - this.splitShortOutput = new short[outputChannels][]; - this.inputIndex = 0; - } - - @Override - public void process(short[] input, int offset, int length) throws InterruptedException { - if (canPassThrough(length)) { - downstream.process(input, offset, length); - } else { - if (inputChannels == 1 && outputChannels == 2) { - processMonoToStereo(ShortBuffer.wrap(input, offset, length)); - } else { - processNormalizer(ShortBuffer.wrap(input, offset, length)); - } - } - } - - @Override - public void process(ShortBuffer buffer) throws InterruptedException { - if (canPassThrough(buffer.remaining())) { - downstream.process(buffer); - } else { - if (inputChannels == 1 && outputChannels == 2) { - processMonoToStereo(buffer); - } else { - processNormalizer(buffer); - } - } - } - - private void processNormalizer(ShortBuffer buffer) throws InterruptedException { - while (buffer.hasRemaining()) { - inputSet[inputIndex++] = buffer.get(); - - if (inputIndex == inputChannels) { - outputBuffer.put(inputSet, 0, commonChannels); - - for (int i = 0; i < channelsToAdd; i++) { - outputBuffer.put(inputSet[0]); - } - - if (!outputBuffer.hasRemaining()) { - outputBuffer.flip(); - downstream.process(outputBuffer); - outputBuffer.clear(); - } - - inputIndex = 0; - } - } - } - - private void processMonoToStereo(ShortBuffer buffer) throws InterruptedException { - while (buffer.hasRemaining()) { - short sample = buffer.get(); - outputBuffer.put(sample); - outputBuffer.put(sample); - - if (!outputBuffer.hasRemaining()) { - outputBuffer.flip(); - downstream.process(outputBuffer); - outputBuffer.clear(); - } - } - } - - private boolean canPassThrough(int length) { - return inputIndex == 0 && inputChannels == outputChannels && (length % inputChannels) == 0; - } - - @Override - public void process(float[][] input, int offset, int length) throws InterruptedException { - for (int i = 0; i < commonChannels; i++) { - splitFloatOutput[i] = input[i]; - } - - for (int i = commonChannels; i < outputChannels; i++) { - splitFloatOutput[i] = input[0]; - } - - downstream.process(splitFloatOutput, offset, length); - } - - @Override - public void process(short[][] input, int offset, int length) throws InterruptedException { - for (int i = 0; i < commonChannels; i++) { - splitShortOutput[i] = input[i]; - } - - for (int i = commonChannels; i < outputChannels; i++) { - splitShortOutput[i] = input[0]; - } - - downstream.process(splitShortOutput, offset, length); - } - - @Override - public void seekPerformed(long requestedTime, long providedTime) { - outputBuffer.clear(); - } - - @Override - public void flush() throws InterruptedException { - // Nothing to do. - } - - @Override - public void close() { - // Nothing to do. - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/CompositeAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/CompositeAudioFilter.java deleted file mode 100644 index 97ba984..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/CompositeAudioFilter.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -/** - * An audio filter which may consist of a number of other filters. - */ -public abstract class CompositeAudioFilter implements UniversalPcmAudioFilter { - private static final Logger log = LoggerFactory.getLogger(CompositeAudioFilter.class); - - @Override - public void seekPerformed(long requestedTime, long providedTime) { - for (AudioFilter filter : getFilters()) { - try { - filter.seekPerformed(requestedTime, providedTime); - } catch (Exception e) { - log.error("Notifying filter {} of seek failed with exception.", filter.getClass(), e); - } - } - } - - @Override - public void flush() throws InterruptedException { - for (AudioFilter filter : getFilters()) { - try { - filter.flush(); - } catch (Exception e) { - log.error("Flushing filter {} failed with exception.", filter.getClass(), e); - } - } - } - - @Override - public void close() { - for (AudioFilter filter : getFilters()) { - try { - filter.close(); - } catch (Exception e) { - log.error("Closing filter {} failed with exception.", filter.getClass(), e); - } - } - } - - protected abstract List getFilters(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/FilterChainBuilder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/FilterChainBuilder.java deleted file mode 100644 index ab6bedc..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/FilterChainBuilder.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import com.sedmelluq.discord.lavaplayer.filter.converter.ToFloatAudioFilter; -import com.sedmelluq.discord.lavaplayer.filter.converter.ToShortAudioFilter; -import com.sedmelluq.discord.lavaplayer.filter.converter.ToSplitShortAudioFilter; - -import java.util.ArrayList; -import java.util.List; - -/** - * Builder for audio filter chains. - */ -public class FilterChainBuilder { - private final List filters = new ArrayList<>(); - - /** - * @param filter The filter to add as the first one in the chain. - */ - public void addFirst(AudioFilter filter) { - filters.add(filter); - } - - /** - * @return The first chain in the filter. - */ - public AudioFilter first() { - return filters.get(filters.size() - 1); - } - - /** - * @param channelCount Number of input channels expected by the current head of the chain. - * @return The first chain in the filter as a float PCM filter, or if it is not, then adds an adapter filter to the - * beginning and returns that. - */ - public FloatPcmAudioFilter makeFirstFloat(int channelCount) { - AudioFilter first = first(); - - if (first instanceof FloatPcmAudioFilter) { - return (FloatPcmAudioFilter) first; - } else { - return prependUniversalFilter(first, channelCount); - } - } - - /** - * @param channelCount Number of input channels expected by the current head of the chain. - * @return The first chain in the filter as an universal PCM filter, or if it is not, then adds an adapter filter to - * the beginning and returns that. - */ - public UniversalPcmAudioFilter makeFirstUniversal(int channelCount) { - AudioFilter first = first(); - - if (first instanceof UniversalPcmAudioFilter) { - return (UniversalPcmAudioFilter) first; - } else { - return prependUniversalFilter(first, channelCount); - } - } - - /** - * @param context See {@link AudioFilterChain#context}. - * @param channelCount Number of input channels expected by the current head of the chain. - * @return The built filter chain. Adds an adapter to the beginning of the chain if the first filter is not universal. - */ - public AudioFilterChain build(Object context, int channelCount) { - UniversalPcmAudioFilter firstFilter = makeFirstUniversal(channelCount); - return new AudioFilterChain(firstFilter, filters, context); - } - - private UniversalPcmAudioFilter prependUniversalFilter(AudioFilter first, int channelCount) { - UniversalPcmAudioFilter universalInput; - - if (first instanceof SplitShortPcmAudioFilter) { - universalInput = new ToSplitShortAudioFilter((SplitShortPcmAudioFilter) first, channelCount); - } else if (first instanceof FloatPcmAudioFilter) { - universalInput = new ToFloatAudioFilter((FloatPcmAudioFilter) first, channelCount); - } else if (first instanceof ShortPcmAudioFilter) { - universalInput = new ToShortAudioFilter((ShortPcmAudioFilter) first, channelCount); - } else { - throw new RuntimeException("Filter must implement at least one data type."); - } - - addFirst(universalInput); - return universalInput; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/FinalPcmAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/FinalPcmAudioFilter.java deleted file mode 100644 index d807677..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/FinalPcmAudioFilter.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; -import java.util.Collection; - -/** - * Collects buffers of the required chunk size and passes them on to audio post processors. - */ -public class FinalPcmAudioFilter implements UniversalPcmAudioFilter { - private static final Logger log = LoggerFactory.getLogger(FinalPcmAudioFilter.class); - private static final short[] zeroPadding = new short[128]; - - private final AudioDataFormat format; - private final ShortBuffer frameBuffer; - private final Collection postProcessors; - - private long ignoredFrames; - private long timecodeBase; - private long timecodeSampleOffset; - - /** - * @param context Configuration and output information for processing - * @param postProcessors Post processors to pass the final audio buffers to - */ - public FinalPcmAudioFilter(AudioProcessingContext context, Collection postProcessors) { - this.format = context.outputFormat; - this.frameBuffer = ByteBuffer - .allocateDirect(format.totalSampleCount() * 2) - .order(ByteOrder.nativeOrder()) - .asShortBuffer(); - this.postProcessors = postProcessors; - - timecodeBase = 0; - timecodeSampleOffset = 0; - } - - private short decodeSample(float sample) { - return (short) Math.min(Math.max((int) (sample * 32768.f), -32768), 32767); - } - - @Override - public void seekPerformed(long requestedTime, long providedTime) { - frameBuffer.clear(); - ignoredFrames = requestedTime > providedTime ? (requestedTime - providedTime) * format.channelCount * format.sampleRate / 1000L : 0; - timecodeBase = Math.max(requestedTime, providedTime); - timecodeSampleOffset = 0; - - if (ignoredFrames > 0) { - log.debug("Ignoring {} frames due to inaccurate seek (requested {}, provided {}).", ignoredFrames, requestedTime, providedTime); - } - } - - @Override - public void flush() throws InterruptedException { - if (frameBuffer.position() > 0) { - fillFrameBuffer(); - dispatch(); - } - } - - @Override - public void close() { - for (AudioPostProcessor postProcessor : postProcessors) { - postProcessor.close(); - } - } - - private void fillFrameBuffer() { - while (frameBuffer.remaining() >= zeroPadding.length) { - frameBuffer.put(zeroPadding); - } - - while (frameBuffer.remaining() > 0) { - frameBuffer.put((short) 0); - } - } - - @Override - public void process(short[] input, int offset, int length) throws InterruptedException { - for (int i = 0; i < length; i++) { - if (ignoredFrames > 0) { - ignoredFrames--; - } else { - frameBuffer.put(input[offset + i]); - - dispatch(); - } - } - } - - @Override - public void process(short[][] input, int offset, int length) throws InterruptedException { - int secondChannelIndex = Math.min(1, input.length - 1); - - for (int i = 0; i < length; i++) { - if (ignoredFrames > 0) { - ignoredFrames -= format.channelCount; - } else { - frameBuffer.put(input[0][offset + i]); - frameBuffer.put(input[secondChannelIndex][offset + i]); - - dispatch(); - } - } - } - - @Override - public void process(ShortBuffer buffer) throws InterruptedException { - if (ignoredFrames > 0) { - long skipped = Math.min(buffer.remaining(), ignoredFrames); - buffer.position(buffer.position() + (int) skipped); - ignoredFrames -= skipped; - } - - ShortBuffer local = buffer.duplicate(); - - while (buffer.remaining() > 0) { - int chunk = Math.min(buffer.remaining(), frameBuffer.remaining()); - local.position(buffer.position()); - local.limit(local.position() + chunk); - - frameBuffer.put(local); - dispatch(); - - buffer.position(buffer.position() + chunk); - } - } - - @Override - public void process(float[][] buffer, int offset, int length) throws InterruptedException { - int secondChannelIndex = Math.min(1, buffer.length - 1); - - for (int i = 0; i < length; i++) { - if (ignoredFrames > 0) { - ignoredFrames -= 2; - } else { - frameBuffer.put(decodeSample(buffer[0][offset + i])); - frameBuffer.put(decodeSample(buffer[secondChannelIndex][offset + i])); - - dispatch(); - } - } - } - - private void dispatch() throws InterruptedException { - if (!frameBuffer.hasRemaining()) { - long timecode = timecodeBase + timecodeSampleOffset * 1000 / format.sampleRate; - frameBuffer.clear(); - - for (AudioPostProcessor postProcessor : postProcessors) { - postProcessor.process(timecode, frameBuffer); - } - - frameBuffer.clear(); - - timecodeSampleOffset += format.chunkSampleCount; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/FloatPcmAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/FloatPcmAudioFilter.java deleted file mode 100644 index df5889e..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/FloatPcmAudioFilter.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -/** - * Audio filter which accepts floating point PCM samples. - */ -public interface FloatPcmAudioFilter extends AudioFilter { - /** - * @param input An array of samples for each channel - * @param offset Offset in the arrays to start at - * @param length Length of the target sequence in arrays - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void process(float[][] input, int offset, int length) throws InterruptedException; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/PcmFilterFactory.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/PcmFilterFactory.java deleted file mode 100644 index 17e4e3a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/PcmFilterFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; - -import java.util.List; - -/** - * Factory for custom PCM filters. - */ -public interface PcmFilterFactory { - /** - * Builds a filter chain for processing a track. Note that this may be called several times during the playback of a - * single track. All filters should send the output from the filter either to the next filter in the list, or to the - * output filter if it is the last one in the list. Only the process and flush methods should call the next filter, - * all other methods are called individually for each filter anyway. - * - * @param track The track that this chain is built for. - * @param format The output format of the track. At the point where these filters are called, the number of channels - * and the sample rate already matches that of the output format. - * @param output The filter that the last filter in this chain should send its data to. - * @return The list of filters in the built chain. May be empty, but not null. - */ - List buildChain(AudioTrack track, AudioDataFormat format, UniversalPcmAudioFilter output); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/PcmFormat.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/PcmFormat.java deleted file mode 100644 index 6b74565..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/PcmFormat.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -/** - * Describes the properties of PCM data. - */ -public class PcmFormat { - /** - * Number of channels. - */ - public final int channelCount; - /** - * Sample rate (frequency). - */ - public final int sampleRate; - - /** - * @param channelCount See {@link #channelCount}. - * @param sampleRate See {@link #sampleRate}. - */ - public PcmFormat(int channelCount, int sampleRate) { - this.channelCount = channelCount; - this.sampleRate = sampleRate; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/ResamplingPcmAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/ResamplingPcmAudioFilter.java deleted file mode 100644 index 00bac03..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/ResamplingPcmAudioFilter.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import com.sedmelluq.discord.lavaplayer.natives.samplerate.SampleRateConverter; -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; - -/** - * Filter which resamples audio to the specified sample rate - */ -public class ResamplingPcmAudioFilter implements FloatPcmAudioFilter { - private static final int BUFFER_SIZE = 4096; - - private final FloatPcmAudioFilter downstream; - private final SampleRateConverter[] converters; - private final SampleRateConverter.Progress progress = new SampleRateConverter.Progress(); - private final float[][] outputSegments; - - /** - * @param configuration Configuration to use - * @param channels Number of channels in input data - * @param downstream Next filter in chain - * @param sourceRate Source sample rate - * @param targetRate Target sample rate - */ - public ResamplingPcmAudioFilter(AudioConfiguration configuration, int channels, FloatPcmAudioFilter downstream, - int sourceRate, int targetRate) { - - this.downstream = downstream; - converters = new SampleRateConverter[channels]; - outputSegments = new float[channels][]; - - SampleRateConverter.ResamplingType type = getResamplingType(configuration.getResamplingQuality()); - - for (int i = 0; i < channels; i++) { - outputSegments[i] = new float[BUFFER_SIZE]; - converters[i] = new SampleRateConverter(type, 1, sourceRate, targetRate); - } - } - - @Override - public void seekPerformed(long requestedTime, long providedTime) { - for (SampleRateConverter converter : converters) { - converter.reset(); - } - } - - @Override - public void flush() throws InterruptedException { - // Nothing to do. - } - - @Override - public void close() { - for (SampleRateConverter converter : converters) { - converter.close(); - } - } - - @Override - public void process(float[][] input, int offset, int length) throws InterruptedException { - do { - for (int i = 0; i < input.length; i++) { - converters[i].process(input[i], offset, length, outputSegments[i], 0, BUFFER_SIZE, false, progress); - } - - offset += progress.getInputUsed(); - length -= progress.getInputUsed(); - - if (progress.getOutputGenerated() > 0) { - downstream.process(outputSegments, 0, progress.getOutputGenerated()); - } - } while (length > 0 || progress.getOutputGenerated() == BUFFER_SIZE); - } - - private static SampleRateConverter.ResamplingType getResamplingType(AudioConfiguration.ResamplingQuality quality) { - switch (quality) { - case HIGH: - return SampleRateConverter.ResamplingType.SINC_MEDIUM_QUALITY; - case MEDIUM: - return SampleRateConverter.ResamplingType.SINC_FASTEST; - case LOW: - default: - return SampleRateConverter.ResamplingType.LINEAR; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/ShortPcmAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/ShortPcmAudioFilter.java deleted file mode 100644 index 231f8c6..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/ShortPcmAudioFilter.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import java.nio.ShortBuffer; - -/** - * Audio filter which accepts 16-bit signed PCM samples. - */ -public interface ShortPcmAudioFilter extends AudioFilter { - /** - * @param input Array of samples - * @param offset Offset in the array - * @param length Length of the sequence in the array - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void process(short[] input, int offset, int length) throws InterruptedException; - - /** - * @param buffer The buffer of samples - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void process(ShortBuffer buffer) throws InterruptedException; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/SplitShortPcmAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/SplitShortPcmAudioFilter.java deleted file mode 100644 index f2bbd3b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/SplitShortPcmAudioFilter.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -/** - * Audio filter which accepts 16-bit signed PCM samples, with an array per . - */ -public interface SplitShortPcmAudioFilter extends AudioFilter { - /** - * @param input An array of samples for each channel - * @param offset Offset in the array - * @param length Length of the sequence in the array - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void process(short[][] input, int offset, int length) throws InterruptedException; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/UniversalPcmAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/UniversalPcmAudioFilter.java deleted file mode 100644 index 297aae7..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/UniversalPcmAudioFilter.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -/** - * A PCM filter which must be able to correctly process all representations of PCM input data, as specified by the - * methods of the interfaces it extends. - */ -public interface UniversalPcmAudioFilter extends ShortPcmAudioFilter, SplitShortPcmAudioFilter, FloatPcmAudioFilter { -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/UserProvidedAudioFilters.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/UserProvidedAudioFilters.java deleted file mode 100644 index 94012a3..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/UserProvidedAudioFilters.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter; - -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.nio.ShortBuffer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * An composite audio filter for filters provided by a {@link PcmFilterFactory}. Automatically rebuilds the chain - * whenever the filter factory is changed. - */ -public class UserProvidedAudioFilters extends CompositeAudioFilter { - private final AudioProcessingContext context; - private final UniversalPcmAudioFilter nextFilter; - private final boolean hotSwapEnabled; - private AudioFilterChain chain; - - /** - * @param context Configuration and output information for processing - * @param nextFilter The next filter that should be processed after this one. - */ - public UserProvidedAudioFilters(AudioProcessingContext context, UniversalPcmAudioFilter nextFilter) { - this.context = context; - this.nextFilter = nextFilter; - this.hotSwapEnabled = context.filterHotSwapEnabled; - this.chain = buildFragment(context, nextFilter); - } - - private static AudioFilterChain buildFragment(AudioProcessingContext context, - UniversalPcmAudioFilter nextFilter) { - - PcmFilterFactory factory = context.playerOptions.filterFactory.get(); - - if (factory == null) { - return new AudioFilterChain(nextFilter, Collections.emptyList(), null); - } else { - FilterChainBuilder builder = new FilterChainBuilder(); - - List filters = new ArrayList<>(factory.buildChain(null, context.outputFormat, nextFilter)); - - if (filters.isEmpty()) { - return new AudioFilterChain(nextFilter, Collections.emptyList(), null); - } - - Collections.reverse(filters); - - for (AudioFilter filter : filters) { - builder.addFirst(filter); - } - - return builder.build(factory, context.outputFormat.channelCount); - } - } - - @Override - protected List getFilters() { - return chain.filters; - } - - @Override - public void process(float[][] input, int offset, int length) throws InterruptedException { - checkRebuild(); - chain.input.process(input, offset, length); - } - - @Override - public void process(short[] input, int offset, int length) throws InterruptedException { - checkRebuild(); - chain.input.process(input, offset, length); - } - - @Override - public void process(ShortBuffer buffer) throws InterruptedException { - checkRebuild(); - chain.input.process(buffer); - } - - @Override - public void process(short[][] input, int offset, int length) throws InterruptedException { - checkRebuild(); - chain.input.process(input, offset, length); - } - - private void checkRebuild() throws InterruptedException { - if (hotSwapEnabled && context.playerOptions.filterFactory.get() != chain.context) { - flush(); - close(); - chain = buildFragment(context, nextFilter); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ConverterAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ConverterAudioFilter.java deleted file mode 100644 index d4469c0..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ConverterAudioFilter.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter.converter; - -import com.sedmelluq.discord.lavaplayer.filter.UniversalPcmAudioFilter; - -/** - * Base class for converter filters which have no internal state. - */ -public abstract class ConverterAudioFilter implements UniversalPcmAudioFilter { - protected static final int BUFFER_SIZE = 4096; - - @Override - public void seekPerformed(long requestedTime, long providedTime) { - // Nothing to do. - } - - @Override - public void flush() throws InterruptedException { - // Nothing to do. - } - - @Override - public void close() { - // Nothing to do. - } - - protected static short floatToShort(float value) { - return (short) (value * 32768.0f); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToFloatAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToFloatAudioFilter.java deleted file mode 100644 index ae82fe9..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToFloatAudioFilter.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter.converter; - -import com.sedmelluq.discord.lavaplayer.filter.FloatPcmAudioFilter; - -import java.nio.ShortBuffer; - -/** - * Filter which takes in PCM data in any representation and outputs it as float PCM. - */ -public class ToFloatAudioFilter extends ConverterAudioFilter { - private final FloatPcmAudioFilter downstream; - private final int channelCount; - private final float[][] buffers; - - /** - * @param downstream The float PCM filter to pass the output to. - * @param channelCount Number of channels in the PCM data. - */ - public ToFloatAudioFilter(FloatPcmAudioFilter downstream, int channelCount) { - this.downstream = downstream; - this.channelCount = channelCount; - this.buffers = new float[channelCount][]; - - for (int i = 0; i < channelCount; i++) { - this.buffers[i] = new float[BUFFER_SIZE]; - } - } - - @Override - public void process(float[][] input, int offset, int length) throws InterruptedException { - downstream.process(input, offset, length); - } - - @Override - public void process(short[] input, int offset, int length) throws InterruptedException { - int end = offset + length; - - while (end - offset >= channelCount) { - int chunkLength = Math.min((end - offset) / channelCount, BUFFER_SIZE); - - for (int chunkPosition = 0; chunkPosition < chunkLength; chunkPosition++) { - for (int channel = 0; channel < channelCount; channel++) { - buffers[channel][chunkPosition] = shortToFloat(input[offset++]); - } - } - - downstream.process(buffers, 0, chunkLength); - } - } - - @Override - public void process(ShortBuffer buffer) throws InterruptedException { - while (buffer.hasRemaining()) { - int chunkLength = Math.min(buffer.remaining() / channelCount, BUFFER_SIZE); - - if (chunkLength == 0) { - break; - } - - for (int chunkPosition = 0; chunkPosition < chunkLength; chunkPosition++) { - for (int channel = 0; channel < buffers.length; channel++) { - buffers[channel][chunkPosition] = shortToFloat(buffer.get()); - } - } - - downstream.process(buffers, 0, chunkLength); - } - } - - @Override - public void process(short[][] input, int offset, int length) throws InterruptedException { - int end = offset + length; - - while (offset < end) { - int chunkLength = Math.min(end - offset, BUFFER_SIZE); - - for (int channel = 0; channel < buffers.length; channel++) { - for (int chunkPosition = 0; chunkPosition < chunkLength; chunkPosition++) { - buffers[channel][chunkPosition] = shortToFloat(input[channel][offset + chunkPosition]); - } - } - - offset += chunkLength; - downstream.process(buffers, 0, chunkLength); - } - } - - private static float shortToFloat(short value) { - return value / 32768.0f; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToShortAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToShortAudioFilter.java deleted file mode 100644 index 71b4a2a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToShortAudioFilter.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter.converter; - -import com.sedmelluq.discord.lavaplayer.filter.ShortPcmAudioFilter; - -import java.nio.ShortBuffer; - -/** - * Filter which takes in PCM data in any representation and outputs it as short PCM. - */ -public class ToShortAudioFilter extends ConverterAudioFilter { - private final ShortPcmAudioFilter downstream; - private final int channelCount; - private final short[] outputBuffer; - - /** - * @param downstream The short PCM filter to pass the output to. - * @param channelCount Number of channels in the PCM data. - */ - public ToShortAudioFilter(ShortPcmAudioFilter downstream, int channelCount) { - this.downstream = downstream; - this.channelCount = channelCount; - this.outputBuffer = new short[BUFFER_SIZE * channelCount]; - } - - @Override - public void process(float[][] input, int offset, int length) throws InterruptedException { - int end = offset + length; - - while (offset < end) { - int chunkSize = Math.min(BUFFER_SIZE, end - offset); - int writePosition = 0; - - for (int chunkPosition = 0; chunkPosition < chunkSize; chunkPosition++) { - for (int channel = 0; channel < channelCount; channel++) { - outputBuffer[writePosition++] = floatToShort(input[channel][chunkPosition]); - } - } - - offset += chunkSize; - downstream.process(outputBuffer, 0, chunkSize); - } - } - - @Override - public void process(short[] input, int offset, int length) throws InterruptedException { - downstream.process(input, offset, length); - } - - @Override - public void process(ShortBuffer buffer) throws InterruptedException { - downstream.process(buffer); - } - - @Override - public void process(short[][] input, int offset, int length) throws InterruptedException { - int end = offset + length; - - while (offset < end) { - int chunkSize = Math.min(BUFFER_SIZE, end - offset); - int writePosition = 0; - - for (int chunkPosition = 0; chunkPosition < chunkSize; chunkPosition++) { - for (int channel = 0; channel < channelCount; channel++) { - outputBuffer[writePosition++] = input[channel][chunkPosition]; - } - } - - offset += chunkSize; - downstream.process(outputBuffer, 0, chunkSize); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToSplitShortAudioFilter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToSplitShortAudioFilter.java deleted file mode 100644 index c3f23cd..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/converter/ToSplitShortAudioFilter.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter.converter; - -import com.sedmelluq.discord.lavaplayer.filter.SplitShortPcmAudioFilter; - -import java.nio.ShortBuffer; - -/** - * Filter which takes in PCM data in any representation and outputs it as split short PCM. - */ -public class ToSplitShortAudioFilter extends ConverterAudioFilter { - private final SplitShortPcmAudioFilter downstream; - private final int channelCount; - private final short[][] buffers; - - /** - * @param downstream The split short PCM filter to pass the output to. - * @param channelCount Number of channels in the PCM data. - */ - public ToSplitShortAudioFilter(SplitShortPcmAudioFilter downstream, int channelCount) { - this.downstream = downstream; - this.channelCount = channelCount; - this.buffers = new short[channelCount][]; - - for (int i = 0; i < channelCount; i++) { - this.buffers[i] = new short[BUFFER_SIZE]; - } - } - - @Override - public void process(float[][] input, int offset, int length) throws InterruptedException { - int end = offset + length; - - while (offset < end) { - int chunkLength = Math.min(end - offset, BUFFER_SIZE); - - for (int channel = 0; channel < channelCount; channel++) { - for (int chunkPosition = 0; chunkPosition < chunkLength; chunkPosition++) { - buffers[channel][chunkPosition] = floatToShort(input[channel][offset + chunkPosition]); - } - } - - downstream.process(buffers, 0, chunkLength); - } - } - - @Override - public void process(short[] input, int offset, int length) throws InterruptedException { - int end = offset + length; - - while (end - offset >= channelCount) { - int chunkLength = Math.min(end - offset, BUFFER_SIZE * channelCount); - - for (int chunkPosition = 0; chunkPosition < chunkLength; chunkPosition++) { - for (int channel = 0; channel < buffers.length; channel++) { - buffers[channel][chunkPosition] = floatToShort(input[offset++]); - } - } - - downstream.process(buffers, 0, chunkLength); - } - } - - @Override - public void process(ShortBuffer buffer) throws InterruptedException { - while (buffer.hasRemaining()) { - int chunkLength = Math.min(buffer.remaining(), BUFFER_SIZE * channelCount); - - for (int chunkPosition = 0; chunkPosition < chunkLength; chunkPosition++) { - for (int channel = 0; channel < buffers.length; channel++) { - buffers[channel][chunkPosition] = floatToShort(buffer.get()); - } - } - - downstream.process(buffers, 0, chunkLength); - } - } - - @Override - public void process(short[][] input, int offset, int length) throws InterruptedException { - downstream.process(input, offset, length); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/Equalizer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/Equalizer.java deleted file mode 100644 index 200189c..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/Equalizer.java +++ /dev/null @@ -1,174 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter.equalizer; - -import com.sedmelluq.discord.lavaplayer.filter.FloatPcmAudioFilter; -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; - -import java.util.Arrays; - -/** - * An equalizer PCM filter. Applies the equalizer with configuration specified by band multipliers (either set - * externally or using {@link #setGain(int, float)}). - */ -public class Equalizer extends EqualizerConfiguration implements FloatPcmAudioFilter { - /** - * Number of bands in the equalizer. - */ - public static final int BAND_COUNT = 15; - - private static final int SAMPLE_RATE = 48000; - - private final ChannelProcessor[] channels; - private final FloatPcmAudioFilter next; - - private static final Coefficients[] coefficients48000 = { - new Coefficients(9.9847546664e-01f, 7.6226668143e-04f, 1.9984647656e+00f), - new Coefficients(9.9756184654e-01f, 1.2190767289e-03f, 1.9975344645e+00f), - new Coefficients(9.9616261379e-01f, 1.9186931041e-03f, 1.9960947369e+00f), - new Coefficients(9.9391578543e-01f, 3.0421072865e-03f, 1.9937449618e+00f), - new Coefficients(9.9028307215e-01f, 4.8584639242e-03f, 1.9898465702e+00f), - new Coefficients(9.8485897264e-01f, 7.5705136795e-03f, 1.9837962543e+00f), - new Coefficients(9.7588512657e-01f, 1.2057436715e-02f, 1.9731772447e+00f), - new Coefficients(9.6228521814e-01f, 1.8857390928e-02f, 1.9556164694e+00f), - new Coefficients(9.4080933132e-01f, 2.9595334338e-02f, 1.9242054384e+00f), - new Coefficients(9.0702059196e-01f, 4.6489704022e-02f, 1.8653476166e+00f), - new Coefficients(8.5868004289e-01f, 7.0659978553e-02f, 1.7600401337e+00f), - new Coefficients(7.8409610788e-01f, 1.0795194606e-01f, 1.5450725522e+00f), - new Coefficients(6.8332861002e-01f, 1.5833569499e-01f, 1.1426447155e+00f), - new Coefficients(5.5267518228e-01f, 2.2366240886e-01f, 4.0186190803e-01f), - new Coefficients(4.1811888447e-01f, 2.9094055777e-01f, -7.0905944223e-01f) - }; - - /** - * @param channelCount Number of channels in the input. - * @param next The next filter in the chain. - * @param bandMultipliers The band multiplier values. Keeps using this array internally, so the values can be changed - * externally. - */ - public Equalizer(int channelCount, FloatPcmAudioFilter next, float[] bandMultipliers) { - super(bandMultipliers); - this.channels = createProcessors(channelCount, bandMultipliers); - this.next = next; - } - - /** - * @param channelCount Number of channels in the input. - * @param next The next filter in the chain. - */ - public Equalizer(int channelCount, FloatPcmAudioFilter next) { - this(channelCount, next, new float[BAND_COUNT]); - } - - /** - * @param format Audio output format. - * @return true if the output format is compatible for the equalizer (based on sample rate). - */ - public static boolean isCompatible(AudioDataFormat format) { - return format.sampleRate == SAMPLE_RATE; - } - - @Override - public void process(float[][] input, int offset, int length) throws InterruptedException { - for (int channelIndex = 0; channelIndex < channels.length; channelIndex++) { - channels[channelIndex].process(input[channelIndex], offset, offset + length); - } - - next.process(input, offset, length); - } - - @Override - public void seekPerformed(long requestedTime, long providedTime) { - for (int channelIndex = 0; channelIndex < channels.length; channelIndex++) { - channels[channelIndex].reset(); - } - } - - @Override - public void flush() throws InterruptedException { - // Nothing to do here. - } - - @Override - public void close() { - // Nothing to do here. - } - - private static ChannelProcessor[] createProcessors(int channelCount, float[] bandMultipliers) { - ChannelProcessor[] processors = new ChannelProcessor[channelCount]; - - for (int i = 0; i < channelCount; i++) { - processors[i] = new ChannelProcessor(bandMultipliers); - } - - return processors; - } - - private static class ChannelProcessor { - private final float[] history; - private final float[] bandMultipliers; - - private int current; - private int minusOne; - private int minusTwo; - - private ChannelProcessor(float[] bandMultipliers) { - this.history = new float[BAND_COUNT * 6]; - this.bandMultipliers = bandMultipliers; - this.current = 0; - this.minusOne = 2; - this.minusTwo = 1; - } - - private void process(float[] samples, int startIndex, int endIndex) { - for (int sampleIndex = startIndex; sampleIndex < endIndex; sampleIndex++) { - float sample = samples[sampleIndex]; - float result = sample * 0.25f; - - for (int bandIndex = 0; bandIndex < BAND_COUNT; bandIndex++) { - int x = bandIndex * 6; - int y = x + 3; - - Coefficients coefficients = coefficients48000[bandIndex]; - - float bandResult = coefficients.alpha * (sample - history[x + minusTwo]) + - coefficients.gamma * history[y + minusOne] - - coefficients.beta * history[y + minusTwo]; - - history[x + current] = sample; - history[y + current] = bandResult; - - result += bandResult * bandMultipliers[bandIndex]; - } - - samples[sampleIndex] = Math.min(Math.max(result * 4.0f, -1.0f), 1.0f); - - if (++current == 3) { - current = 0; - } - - if (++minusOne == 3) { - minusOne = 0; - } - - if (++minusTwo == 3) { - minusTwo = 0; - } - } - } - - private void reset() { - Arrays.fill(history, 0.0f); - } - } - - private static class Coefficients { - private final float beta; - private final float alpha; - private final float gamma; - - private Coefficients(float beta, float alpha, float gamma) { - this.beta = beta; - this.alpha = alpha; - this.gamma = gamma; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/EqualizerConfiguration.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/EqualizerConfiguration.java deleted file mode 100644 index 4844936..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/EqualizerConfiguration.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter.equalizer; - -/** - * Holder of equalizer configuration. - */ -public class EqualizerConfiguration { - protected final float[] bandMultipliers; - - /** - * @param bandMultipliers The band multiplier values. Keeps using this array internally, so the values can be changed - * externally. - */ - public EqualizerConfiguration(float[] bandMultipliers) { - this.bandMultipliers = bandMultipliers; - } - - /** - * @param band The index of the band. If this is not a valid band index, the method has no effect. - * @param value The multiplier for this band. Default value is 0. Valid values are from -0.25 to 1. -0.25 means that - * the given frequency is completely muted and 0.25 means it is doubled. Note that this may change the - * volume of the output. - */ - public void setGain(int band, float value) { - if (isValidBand(band)) { - bandMultipliers[band] = Math.max(Math.min(value, 1.0f), -0.25f); - } - } - - /** - * @param band The index of the band. - * @return The multiplier for this band. Default value is 0. - */ - public float getGain(int band) { - if (isValidBand(band)) { - return bandMultipliers[band]; - } else { - return 0.0f; - } - } - - private boolean isValidBand(int band) { - return band >= 0 && band < bandMultipliers.length; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/EqualizerFactory.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/EqualizerFactory.java deleted file mode 100644 index 898c836..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/equalizer/EqualizerFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter.equalizer; - -import com.sedmelluq.discord.lavaplayer.filter.AudioFilter; -import com.sedmelluq.discord.lavaplayer.filter.PcmFilterFactory; -import com.sedmelluq.discord.lavaplayer.filter.UniversalPcmAudioFilter; -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; - -import java.util.Collections; -import java.util.List; - -/** - * PCM filter factory which creates a single {@link Equalizer} filter for every track. Useful in case the equalizer is - * the only custom filter used. - */ -public class EqualizerFactory extends EqualizerConfiguration implements PcmFilterFactory { - /** - * Creates a new instance no gains applied initially. - */ - public EqualizerFactory() { - super(new float[Equalizer.BAND_COUNT]); - } - - @Override - public List buildChain(AudioTrack track, AudioDataFormat format, UniversalPcmAudioFilter output) { - if (Equalizer.isCompatible(format)) { - return Collections.singletonList(new Equalizer(format.channelCount, output, bandMultipliers)); - } else { - return Collections.emptyList(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/AudioFrameVolumeChanger.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/AudioFrameVolumeChanger.java deleted file mode 100644 index 201f835..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/AudioFrameVolumeChanger.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter.volume; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.format.transcoder.AudioChunkDecoder; -import com.sedmelluq.discord.lavaplayer.format.transcoder.AudioChunkEncoder; -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameRebuilder; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; -import com.sedmelluq.discord.lavaplayer.track.playback.ImmutableAudioFrame; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; - -/** - * A frame rebuilder to apply a specific volume level to the frames. - */ -public class AudioFrameVolumeChanger implements AudioFrameRebuilder { - private final AudioConfiguration configuration; - private final AudioDataFormat format; - private final int newVolume; - private final ShortBuffer sampleBuffer; - private final PcmVolumeProcessor volumeProcessor; - - private AudioChunkEncoder encoder; - private AudioChunkDecoder decoder; - private int frameIndex; - - private AudioFrameVolumeChanger(AudioConfiguration configuration, AudioDataFormat format, int newVolume) { - this.configuration = configuration; - this.format = format; - this.newVolume = newVolume; - - this.sampleBuffer = ByteBuffer - .allocateDirect(format.totalSampleCount() * 2) - .order(ByteOrder.nativeOrder()) - .asShortBuffer(); - this.volumeProcessor = new PcmVolumeProcessor(100); - } - - @Override - public AudioFrame rebuild(AudioFrame frame) { - if (frame.getVolume() == newVolume) { - return frame; - } - - decoder.decode(frame.getData(), sampleBuffer); - - int targetVolume = newVolume; - - if (++frameIndex < 50) { - targetVolume = (int) ((newVolume - frame.getVolume()) * (frameIndex / 50.0) + frame.getVolume()); - } - - // Volume 0 is stored in the frame with volume 100 buffer - if (targetVolume != 0) { - volumeProcessor.applyVolume(frame.getVolume(), targetVolume, sampleBuffer); - } - - byte[] bytes = encoder.encode(sampleBuffer); - - // One frame per 20ms is consumed. To not spike the CPU usage, reencode only once per 5ms. By the time the buffer is - // fully rebuilt, it is probably near to 3/4 its maximum size. - try { - Thread.sleep(5); - } catch (InterruptedException e) { - // Keep it interrupted, it will trip on the next interruptible operation - Thread.currentThread().interrupt(); - } - - return new ImmutableAudioFrame(frame.getTimecode(), bytes, targetVolume, format); - } - - private void setupLibraries() { - encoder = format.createEncoder(configuration); - decoder = format.createDecoder(); - } - - private void clearLibraries() { - if (encoder != null) { - encoder.close(); - } - - if (decoder != null) { - decoder.close(); - } - } - - /** - * Applies a volume level to the buffered frames of a frame consumer - * - * @param context Configuration and output information for processing - */ - public static void apply(AudioProcessingContext context) { - AudioFrameVolumeChanger volumeChanger = new AudioFrameVolumeChanger(context.configuration, context.outputFormat, - context.playerOptions.volumeLevel.get()); - - try { - volumeChanger.setupLibraries(); - context.frameBuffer.rebuild(volumeChanger); - } finally { - volumeChanger.clearLibraries(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/PcmVolumeProcessor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/PcmVolumeProcessor.java deleted file mode 100644 index 4e4b18b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/PcmVolumeProcessor.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter.volume; - -import java.nio.ShortBuffer; - -/** - * Class used to apply a volume level to short PCM buffers - */ -public class PcmVolumeProcessor { - private int currentVolume = -1; - private int integerMultiplier; - - /** - * @param initialVolume Initial volume level (only useful for getLastVolume() as specified with each call) - */ - public PcmVolumeProcessor(int initialVolume) { - setupMultipliers(initialVolume); - } - - /** - * @return Last volume level used with this processor - */ - public int getLastVolume() { - return currentVolume; - } - - /** - * @param lastVolume Value to explicitly set for the return value of getLastVolume() - */ - public void setLastVolume(int lastVolume) { - currentVolume = lastVolume; - } - - /** - * @param initialVolume The input volume of the samples - * @param targetVolume The target volume of the samples - * @param buffer The buffer containing the samples - */ - public void applyVolume(int initialVolume, int targetVolume, ShortBuffer buffer) { - if (initialVolume != 100 && initialVolume != 0) { - setupMultipliers(initialVolume); - unapplyCurrentVolume(buffer); - } - - setupMultipliers(targetVolume); - applyCurrentVolume(buffer); - } - - private void setupMultipliers(int activeVolume) { - if (currentVolume != activeVolume) { - currentVolume = activeVolume; - - if (activeVolume <= 150) { - float floatMultiplier = (float) Math.tan(activeVolume * 0.0079f); - integerMultiplier = (int) (floatMultiplier * 10000); - } else { - integerMultiplier = 24621 * activeVolume / 150; - } - } - } - - private void applyCurrentVolume(ShortBuffer buffer) { - if (currentVolume == 100) { - return; - } - - int endOffset = buffer.limit(); - - for (int i = buffer.position(); i < endOffset; i++) { - int value = buffer.get(i) * integerMultiplier / 10000; - buffer.put(i, (short) Math.max(-32767, Math.min(32767, value))); - } - } - - private void unapplyCurrentVolume(ShortBuffer buffer) { - if (integerMultiplier == 0) { - return; - } - - int endOffset = buffer.limit(); - - for (int i = buffer.position(); i < endOffset; i++) { - int value = buffer.get(i) * 10000 / integerMultiplier; - buffer.put(i, (short) Math.max(-32767, Math.min(32767, value))); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/VolumePostProcessor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/VolumePostProcessor.java deleted file mode 100644 index 719d3d5..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/filter/volume/VolumePostProcessor.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.filter.volume; - -import com.sedmelluq.discord.lavaplayer.filter.AudioPostProcessor; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; - -import java.nio.ShortBuffer; - -/** - * Audio chunk post processor to apply selected volume. - */ -public class VolumePostProcessor implements AudioPostProcessor { - private final PcmVolumeProcessor volumeProcessor; - private final AudioProcessingContext context; - - /** - * @param context Configuration and output information for processing - */ - public VolumePostProcessor(AudioProcessingContext context) { - this.context = context; - this.volumeProcessor = new PcmVolumeProcessor(context.playerOptions.volumeLevel.get()); - } - - @Override - public void process(long timecode, ShortBuffer buffer) throws InterruptedException { - int currentVolume = context.playerOptions.volumeLevel.get(); - - if (currentVolume != volumeProcessor.getLastVolume()) { - AudioFrameVolumeChanger.apply(context); - } - - // Volume 0 is stored in the frame with volume 100 buffer - if (currentVolume != 0) { - volumeProcessor.applyVolume(100, currentVolume, buffer); - } else { - volumeProcessor.setLastVolume(0); - } - } - - @Override - public void close() { - // Nothing to close here - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioDataFormat.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioDataFormat.java deleted file mode 100644 index 48e9036..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioDataFormat.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format; - -import com.sedmelluq.discord.lavaplayer.format.transcoder.AudioChunkDecoder; -import com.sedmelluq.discord.lavaplayer.format.transcoder.AudioChunkEncoder; -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; - -import java.util.Objects; - -/** - * Describes the format for audio with fixed chunk size. - */ -public abstract class AudioDataFormat { - /** - * Number of channels. - */ - public final int channelCount; - /** - * Sample rate (frequency). - */ - public final int sampleRate; - /** - * Number of samples in one chunk. - */ - public final int chunkSampleCount; - - /** - * @param channelCount Number of channels. - * @param sampleRate Sample rate (frequency). - * @param chunkSampleCount Number of samples in one chunk. - */ - public AudioDataFormat(int channelCount, int sampleRate, int chunkSampleCount) { - this.channelCount = channelCount; - this.sampleRate = sampleRate; - this.chunkSampleCount = chunkSampleCount; - } - - /** - * @return Total number of samples in one frame. - */ - public int totalSampleCount() { - return chunkSampleCount * channelCount; - } - - /** - * @return The duration in milliseconds of one frame in this format. - */ - public long frameDuration() { - return chunkSampleCount * 1000L / sampleRate; - } - - /** - * @return Name of the codec. - */ - public abstract String codecName(); - - /** - * @return Byte array representing a frame of silence in this format. - */ - public abstract byte[] silenceBytes(); - - /** - * @return Generally expected average size of a frame in this format. - */ - public abstract int expectedChunkSize(); - - /** - * @return Maximum size of a frame in this format. - */ - public abstract int maximumChunkSize(); - - /** - * @return Decoder to convert data in this format to short PCM. - */ - public abstract AudioChunkDecoder createDecoder(); - - /** - * @param configuration Configuration to use for encoding. - * @return Encoder to convert data in short PCM format to this format. - */ - public abstract AudioChunkEncoder createEncoder(AudioConfiguration configuration); - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - AudioDataFormat that = (AudioDataFormat) o; - - if (channelCount != that.channelCount) return false; - if (sampleRate != that.sampleRate) return false; - if (chunkSampleCount != that.chunkSampleCount) return false; - return Objects.equals(codecName(), that.codecName()); - } - - @Override - public int hashCode() { - int result = channelCount; - result = 31 * result + sampleRate; - result = 31 * result + chunkSampleCount; - result = 31 * result + codecName().hashCode(); - return result; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioDataFormatTools.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioDataFormatTools.java deleted file mode 100644 index a8f4ce2..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioDataFormatTools.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format; - -import javax.sound.sampled.AudioFormat; - -import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED; - -/** - * Tools to deal with audio data formats. - */ -public class AudioDataFormatTools { - - /** - * @param format Audio data format to convert to JDK audio format - * @return JDK audio format for the specified format. - */ - public static AudioFormat toAudioFormat(AudioDataFormat format) { - if (format instanceof Pcm16AudioDataFormat) { - return new AudioFormat( - PCM_SIGNED, - format.sampleRate, - 16, - format.channelCount, - format.channelCount * 2, - format.sampleRate, - format.codecName().equals(Pcm16AudioDataFormat.CODEC_NAME_BE) - ); - } else { - throw new IllegalStateException("Only PCM is currently supported."); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioPlayerInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioPlayerInputStream.java deleted file mode 100644 index 8d09716..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/AudioPlayerInputStream.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.track.TrackStateListener; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; - -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.nio.ByteBuffer; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * Provides an audio player as an input stream. When nothing is playing, it returns silence instead of blocking. - */ -public class AudioPlayerInputStream extends InputStream { - private final AudioPlayer player; - private final AudioDataFormat format; - private final long timeout; - private final boolean provideSilence; - private ByteBuffer current; - - /** - * @param format Format of the frames expected from the player - * @param player The player to read frames from - * @param timeout Timeout till track stuck event is sent. Each time a new frame is required from the player, it asks - * for a frame with the specified timeout. In case that timeout is reached, the track stuck event is - * sent and if providing silence is enabled, silence is provided as the next frame. - * @param provideSilence True if the stream should return silence instead of blocking in case nothing is playing or - * read times out. - */ - public AudioPlayerInputStream(AudioDataFormat format, AudioPlayer player, long timeout, boolean provideSilence) { - this.format = format; - this.player = player; - this.timeout = timeout; - this.provideSilence = provideSilence; - } - - @Override - public int read() throws IOException { - ensureAvailable(); - return current.get(); - } - - @Override - public int read(byte[] buffer, int offset, int length) throws IOException { - int currentOffset = offset; - - while (currentOffset < length) { - ensureAvailable(); - - int piece = Math.min(current.remaining(), length - currentOffset); - current.get(buffer, currentOffset, piece); - currentOffset += piece; - } - - return currentOffset - offset; - } - - @Override - public int available() throws IOException { - return current != null ? current.remaining() : 0; - } - - @Override - public void close() throws IOException { - player.stopTrack(); - } - - /** - * Create an instance of AudioInputStream using an AudioPlayer as a source. - * - * @param player Format of the frames expected from the player - * @param format The player to read frames from - * @param stuckTimeout Timeout till track stuck event is sent and silence is returned on reading - * @param provideSilence Returns true if the stream should provide silence if no track is being played or when getting - * track frames times out. - * @return An audio input stream usable with JDK sound system - */ - public static AudioInputStream createStream(AudioPlayer player, AudioDataFormat format, long stuckTimeout, boolean provideSilence) { - AudioFormat jdkFormat = AudioDataFormatTools.toAudioFormat(format); - return new AudioInputStream(new AudioPlayerInputStream(format, player, stuckTimeout, provideSilence), jdkFormat, -1); - } - - private void ensureAvailable() throws IOException { - while (available() == 0) { - try { - attemptRetrieveFrame(); - } catch (TimeoutException e) { - notifyTrackStuck(); - } catch (InterruptedException e) { - ExceptionTools.keepInterrupted(e); - throw new InterruptedIOException(); - } - - if (available() == 0 && provideSilence) { - addFrame(format.silenceBytes()); - break; - } - } - } - - private void attemptRetrieveFrame() throws TimeoutException, InterruptedException { - AudioFrame frame = player.provide(timeout, TimeUnit.MILLISECONDS); - - if (frame != null) { - if (!format.equals(frame.getFormat())) { - throw new IllegalStateException("Frame read from the player uses a different format than expected."); - } - - addFrame(frame.getData()); - } else if (!provideSilence) { - Thread.sleep(10); - } - } - - private void addFrame(byte[] data) { - current = ByteBuffer.wrap(data); - } - - private void notifyTrackStuck() { - if (player instanceof TrackStateListener) { - ((TrackStateListener) player).onTrackStuck(player.getPlayingTrack(), timeout); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/OpusAudioDataFormat.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/OpusAudioDataFormat.java deleted file mode 100644 index 96cef2e..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/OpusAudioDataFormat.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format; - -import com.sedmelluq.discord.lavaplayer.format.transcoder.AudioChunkDecoder; -import com.sedmelluq.discord.lavaplayer.format.transcoder.AudioChunkEncoder; -import com.sedmelluq.discord.lavaplayer.format.transcoder.OpusChunkDecoder; -import com.sedmelluq.discord.lavaplayer.format.transcoder.OpusChunkEncoder; -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; - -/** - * An {@link AudioDataFormat} for OPUS. - */ -public class OpusAudioDataFormat extends AudioDataFormat { - public static final String CODEC_NAME = "OPUS"; - - private static final byte[] SILENT_OPUS_FRAME = new byte[]{(byte) 0xFC, (byte) 0xFF, (byte) 0xFE}; - - private final int maximumChunkSize; - private final int expectedChunkSize; - - /** - * @param channelCount Number of channels. - * @param sampleRate Sample rate (frequency). - * @param chunkSampleCount Number of samples in one chunk. - */ - public OpusAudioDataFormat(int channelCount, int sampleRate, int chunkSampleCount) { - super(channelCount, sampleRate, chunkSampleCount); - - this.maximumChunkSize = 32 + 1536 * chunkSampleCount / 960; - this.expectedChunkSize = 32 + 512 * chunkSampleCount / 960; - } - - @Override - public String codecName() { - return CODEC_NAME; - } - - @Override - public byte[] silenceBytes() { - return SILENT_OPUS_FRAME; - } - - @Override - public int expectedChunkSize() { - return expectedChunkSize; - } - - @Override - public int maximumChunkSize() { - return maximumChunkSize; - } - - @Override - public AudioChunkDecoder createDecoder() { - return new OpusChunkDecoder(this); - } - - @Override - public AudioChunkEncoder createEncoder(AudioConfiguration configuration) { - return new OpusChunkEncoder(configuration, this); - } - - @Override - public boolean equals(Object o) { - return this == o || o != null && getClass() == o.getClass() && super.equals(o); - } - - @Override - public int hashCode() { - return super.hashCode(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/Pcm16AudioDataFormat.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/Pcm16AudioDataFormat.java deleted file mode 100644 index 4171456..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/Pcm16AudioDataFormat.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format; - -import com.sedmelluq.discord.lavaplayer.format.transcoder.AudioChunkDecoder; -import com.sedmelluq.discord.lavaplayer.format.transcoder.AudioChunkEncoder; -import com.sedmelluq.discord.lavaplayer.format.transcoder.PcmChunkDecoder; -import com.sedmelluq.discord.lavaplayer.format.transcoder.PcmChunkEncoder; -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; - -/** - * An {@link AudioDataFormat} for 16-bit signed PCM. - */ -public class Pcm16AudioDataFormat extends AudioDataFormat { - public static final String CODEC_NAME_BE = "PCM_S16_BE"; - public static final String CODEC_NAME_LE = "PCM_S16_LE"; - - private final boolean bigEndian; - private final byte[] silenceBytes; - - /** - * @param channelCount Number of channels. - * @param sampleRate Sample rate (frequency). - * @param chunkSampleCount Number of samples in one chunk. - * @param bigEndian Whether the samples are in big-endian format (as opposed to little-endian). - */ - public Pcm16AudioDataFormat(int channelCount, int sampleRate, int chunkSampleCount, boolean bigEndian) { - super(channelCount, sampleRate, chunkSampleCount); - this.bigEndian = bigEndian; - this.silenceBytes = new byte[channelCount * chunkSampleCount * 2]; - } - - @Override - public String codecName() { - return CODEC_NAME_BE; - } - - @Override - public byte[] silenceBytes() { - return silenceBytes; - } - - @Override - public int expectedChunkSize() { - return silenceBytes.length; - } - - @Override - public int maximumChunkSize() { - return silenceBytes.length; - } - - @Override - public AudioChunkDecoder createDecoder() { - return new PcmChunkDecoder(this, bigEndian); - } - - @Override - public AudioChunkEncoder createEncoder(AudioConfiguration configuration) { - return new PcmChunkEncoder(this, bigEndian); - } - - @Override - public boolean equals(Object o) { - return this == o || o != null && getClass() == o.getClass() && super.equals(o); - } - - @Override - public int hashCode() { - return super.hashCode(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/StandardAudioDataFormats.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/StandardAudioDataFormats.java deleted file mode 100644 index 4ea4c36..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/StandardAudioDataFormats.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format; - -/** - * Standard output formats compatible with Discord. - */ -public class StandardAudioDataFormats { - /** - * The Opus configuration used by both Discord and YouTube. Default. - */ - public static final AudioDataFormat DISCORD_OPUS = new OpusAudioDataFormat(2, 48000, 960); - /** - * Signed 16-bit big-endian PCM format matching the parameters used by Discord. - */ - public static final AudioDataFormat DISCORD_PCM_S16_BE = new Pcm16AudioDataFormat(2, 48000, 960, true); - /** - * Signed 16-bit little-endian PCM format matching the parameters used by Discord. - */ - public static final AudioDataFormat DISCORD_PCM_S16_LE = new Pcm16AudioDataFormat(2, 48000, 960, false); - /** - * Signed 16-bit big-endian PCM format matching with the most common sample rate. - */ - public static final AudioDataFormat COMMON_PCM_S16_BE = new Pcm16AudioDataFormat(2, 44100, 960, true); - /** - * Signed 16-bit big-endian PCM format matching with the most common sample rate. - */ - public static final AudioDataFormat COMMON_PCM_S16_LE = new Pcm16AudioDataFormat(2, 44100, 960, false); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/AudioChunkDecoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/AudioChunkDecoder.java deleted file mode 100644 index c74aac4..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/AudioChunkDecoder.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format.transcoder; - -import java.nio.ShortBuffer; - -/** - * Decodes one chunk of audio into internal PCM format. - */ -public interface AudioChunkDecoder { - /** - * @param encoded Encoded bytes - * @param buffer Output buffer for the PCM data - */ - void decode(byte[] encoded, ShortBuffer buffer); - - /** - * Frees up all held resources. - */ - void close(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/AudioChunkEncoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/AudioChunkEncoder.java deleted file mode 100644 index ba6f0b6..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/AudioChunkEncoder.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format.transcoder; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -/** - * Encodes one chunk of audio from internal PCM format. - */ -public interface AudioChunkEncoder { - /** - * @param buffer Input buffer containing the PCM samples. - * @return Encoded bytes - */ - byte[] encode(ShortBuffer buffer); - - /** - * @param buffer Input buffer containing the PCM samples. - * @param out Output buffer to store the encoded bytes in - */ - void encode(ShortBuffer buffer, ByteBuffer out); - - /** - * Frees up all held resources. - */ - void close(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/OpusChunkDecoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/OpusChunkDecoder.java deleted file mode 100644 index 88cf72a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/OpusChunkDecoder.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format.transcoder; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.natives.opus.OpusDecoder; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -/** - * Audio chunk decoder for Opus codec. - */ -public class OpusChunkDecoder implements AudioChunkDecoder { - private final OpusDecoder decoder; - private final ByteBuffer encodedBuffer; - - /** - * @param format Source audio format. - */ - public OpusChunkDecoder(AudioDataFormat format) { - encodedBuffer = ByteBuffer.allocateDirect(4096); - decoder = new OpusDecoder(format.sampleRate, format.channelCount); - } - - @Override - public void decode(byte[] encoded, ShortBuffer buffer) { - encodedBuffer.clear(); - encodedBuffer.put(encoded); - encodedBuffer.flip(); - - buffer.clear(); - decoder.decode(encodedBuffer, buffer); - } - - @Override - public void close() { - decoder.close(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/OpusChunkEncoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/OpusChunkEncoder.java deleted file mode 100644 index c85f31f..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/OpusChunkEncoder.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format.transcoder; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.natives.opus.OpusEncoder; -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -/** - * Audio chunk encoder for Opus codec. - */ -public class OpusChunkEncoder implements AudioChunkEncoder { - private final AudioDataFormat format; - private final OpusEncoder encoder; - private final ByteBuffer encodedBuffer; - - /** - * @param configuration Audio configuration used for configuring the encoder - * @param format Target audio format. - */ - public OpusChunkEncoder(AudioConfiguration configuration, AudioDataFormat format) { - encodedBuffer = ByteBuffer.allocateDirect(format.maximumChunkSize()); - encoder = new OpusEncoder(format.sampleRate, format.channelCount, configuration.getOpusEncodingQuality()); - this.format = format; - } - - @Override - public byte[] encode(ShortBuffer buffer) { - encoder.encode(buffer, format.chunkSampleCount, encodedBuffer); - - byte[] bytes = new byte[encodedBuffer.remaining()]; - encodedBuffer.get(bytes); - return bytes; - } - - @Override - public void encode(ShortBuffer buffer, ByteBuffer outBuffer) { - if (outBuffer.isDirect()) { - encoder.encode(buffer, format.chunkSampleCount, outBuffer); - } else { - encoder.encode(buffer, format.chunkSampleCount, encodedBuffer); - - int length = encodedBuffer.remaining(); - encodedBuffer.get(outBuffer.array(), 0, length); - - outBuffer.position(0); - outBuffer.limit(length); - } - } - - @Override - public void close() { - encoder.close(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/PcmChunkDecoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/PcmChunkDecoder.java deleted file mode 100644 index f712c31..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/PcmChunkDecoder.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format.transcoder; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; - -/** - * Audio chunk decoder for PCM data. - */ -public class PcmChunkDecoder implements AudioChunkDecoder { - private final ByteBuffer encodedAsByte; - private final ShortBuffer encodedAsShort; - - /** - * @param format Source audio format. - * @param bigEndian Whether the samples are in big-endian format (as opposed to little-endian). - */ - public PcmChunkDecoder(AudioDataFormat format, boolean bigEndian) { - this.encodedAsByte = ByteBuffer.allocate(format.maximumChunkSize()); - - if (!bigEndian) { - encodedAsByte.order(ByteOrder.LITTLE_ENDIAN); - } - - this.encodedAsShort = encodedAsByte.asShortBuffer(); - } - - @Override - public void decode(byte[] encoded, ShortBuffer buffer) { - buffer.clear(); - - encodedAsByte.clear(); - encodedAsByte.put(encoded); - - encodedAsShort.clear(); - encodedAsShort.limit(encodedAsByte.position() / 2); - - buffer.put(encodedAsShort); - buffer.rewind(); - } - - @Override - public void close() { - // Nothing to close here - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/PcmChunkEncoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/PcmChunkEncoder.java deleted file mode 100644 index d636339..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/format/transcoder/PcmChunkEncoder.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.format.transcoder; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; - -/** - * Audio chunk encoder for PCM data. - */ -public class PcmChunkEncoder implements AudioChunkEncoder { - private final ByteBuffer encoded; - private final ShortBuffer encodedAsShort; - - /** - * @param format Target audio format. - * @param bigEndian Whether the samples are in big-endian format (as opposed to little-endian). - */ - public PcmChunkEncoder(AudioDataFormat format, boolean bigEndian) { - this.encoded = ByteBuffer.allocate(format.maximumChunkSize()); - - if (!bigEndian) { - encoded.order(ByteOrder.LITTLE_ENDIAN); - } - - this.encodedAsShort = encoded.asShortBuffer(); - } - - @Override - public byte[] encode(ShortBuffer buffer) { - buffer.mark(); - - encodedAsShort.clear(); - encodedAsShort.put(buffer); - - encoded.clear(); - encoded.limit(encodedAsShort.position() * 2); - - byte[] encodedBytes = new byte[encoded.remaining()]; - encoded.get(encodedBytes); - - buffer.reset(); - return encodedBytes; - } - - @Override - public void encode(ShortBuffer buffer, ByteBuffer out) { - buffer.mark(); - - encodedAsShort.clear(); - encodedAsShort.put(buffer); - - out.put(encoded.array(), 0, encodedAsShort.position() * 2); - out.flip(); - - buffer.reset(); - } - - @Override - public void close() { - // Nothing to close here - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/ConnectorNativeLibLoader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/ConnectorNativeLibLoader.java deleted file mode 100644 index 28936e5..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/ConnectorNativeLibLoader.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives; - -import com.sedmelluq.lava.common.natives.NativeLibraryLoader; -import com.sedmelluq.lava.common.natives.architecture.DefaultOperatingSystemTypes; - -/** - * Methods for loading the connector library. - */ -public class ConnectorNativeLibLoader { - private static final NativeLibraryLoader[] loaders = new NativeLibraryLoader[]{ - NativeLibraryLoader.createFiltered(ConnectorNativeLibLoader.class, "libmpg123-0", - it -> it.osType == DefaultOperatingSystemTypes.WINDOWS), - NativeLibraryLoader.create(ConnectorNativeLibLoader.class, "connector") - }; - - /** - * Loads the connector library with its dependencies for the current system - */ - public static void loadConnectorLibrary() { - for (NativeLibraryLoader loader : loaders) { - loader.load(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/aac/AacDecoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/aac/AacDecoder.java deleted file mode 100644 index b90220e..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/aac/AacDecoder.java +++ /dev/null @@ -1,256 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.aac; - -import com.sedmelluq.discord.lavaplayer.tools.io.BitStreamWriter; -import com.sedmelluq.discord.lavaplayer.tools.io.ByteBufferOutputStream; -import com.sedmelluq.lava.common.natives.NativeResourceHolder; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; - -/** - * A wrapper around the native methods of AacDecoder, which uses fdk-aac native library. Supports data with no transport - * layer. The only AAC type verified to work with this is AAC_LC. - */ -public class AacDecoder extends NativeResourceHolder { - private static final int TRANSPORT_NONE = 0; - - private static final ShortBuffer NO_BUFFER = ByteBuffer.allocateDirect(0).asShortBuffer(); - - private static final int ERROR_NOT_ENOUGH_BITS = 4098; - private static final int ERROR_OUTPUT_BUFFER_TOO_SMALL = 8204; - - public static final int AAC_LC = 2; - - private final AacDecoderLibrary library; - private final long instance; - - /** - * Create a new decoder. - */ - public AacDecoder() { - library = AacDecoderLibrary.getInstance(); - instance = library.create(TRANSPORT_NONE); - } - - /** - * Configure the decoder. Must be called before the first decoding. - * - * @param objectType Audio object type as defined for Audio Specific Config: https://wiki.multimedia.cx/index.php?title=MPEG-4_Audio - * @param frequency Frequency of samples in Hz - * @param channels Number of channels. - * @throws IllegalStateException If the decoder has already been closed. - */ - public void configure(int objectType, int frequency, int channels) { - long buffer = encodeConfiguration(objectType, frequency, channels); - - configureRaw(buffer); - } - - /** - * Configure the decoder. Must be called before the first decoding. - * - * @param config Raw ASC format configuration - * @throws IllegalStateException If the decoder has already been closed. - */ - public void configure(byte[] config) { - if (config.length > 8) { - throw new IllegalArgumentException("Cannot process a header larger than size 8"); - } - - long buffer = 0; - for (int i = 0; i < config.length; i++) { - buffer |= config[i] << (i << 3); - } - - configureRaw(buffer); - } - - private synchronized void configureRaw(long buffer) { - checkNotReleased(); - - if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { - buffer = Long.reverseBytes(buffer); - } - - int error; - if ((error = library.configure(instance, buffer)) != 0) { - throw new IllegalStateException("Configuring failed with error " + error); - } - } - - private static long encodeConfiguration(int objectType, int frequency, int channels) { - try { - ByteBuffer buffer = ByteBuffer.allocate(8); - buffer.order(ByteOrder.nativeOrder()); - BitStreamWriter bitWriter = new BitStreamWriter(new ByteBufferOutputStream(buffer)); - - bitWriter.write(objectType, 5); - - int frequencyIndex = getFrequencyIndex(frequency); - bitWriter.write(frequencyIndex, 4); - - if (frequencyIndex == 15) { - bitWriter.write(frequency, 24); - } - - bitWriter.write(channels, 4); - bitWriter.flush(); - - buffer.clear(); - - return buffer.getLong(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static int getFrequencyIndex(int frequency) { - switch (frequency) { - case 96000: - return 0; - case 88200: - return 1; - case 64000: - return 2; - case 48000: - return 3; - case 44100: - return 4; - case 32000: - return 5; - case 24000: - return 6; - case 22050: - return 7; - case 16000: - return 8; - case 12000: - return 9; - case 11025: - return 10; - case 8000: - return 11; - case 7350: - return 12; - default: - return 15; - } - } - - /** - * Fill the internal decoding buffer with the bytes from the buffer. May consume less bytes than the buffer provides. - * - * @param buffer DirectBuffer which contains the bytes to be added. Position and limit are respected and position is - * updated as a result of this operation. - * @return The number of bytes consumed from the provided buffer. - * @throws IllegalArgumentException If the buffer is not a DirectBuffer. - * @throws IllegalStateException If the decoder has already been closed. - */ - public synchronized int fill(ByteBuffer buffer) { - checkNotReleased(); - - if (!buffer.isDirect()) { - throw new IllegalArgumentException("Buffer argument must be a direct buffer."); - } - - int readBytes = library.fill(instance, buffer, buffer.position(), buffer.limit()); - if (readBytes < 0) { - throw new IllegalStateException("Filling decoder failed with error " + (-readBytes)); - } - - buffer.position(buffer.position() + readBytes); - return readBytes; - } - - /** - * Decode a frame of audio into the given buffer. - * - * @param buffer DirectBuffer of signed PCM samples where the decoded frame will be stored. The buffer size must be at - * least of size frameSize * channels * 2. Buffer position and limit are ignored and not - * updated. - * @param flush Whether all the buffered data should be flushed, set to true if no more input is expected. - * @return True if the frame buffer was filled, false if there was not enough input for decoding a full frame. - * @throws IllegalArgumentException If the buffer is not a DirectBuffer. - * @throws IllegalStateException If the decoding library returns an error other than running out of input data. - * @throws IllegalStateException If the decoder has already been closed. - */ - public synchronized boolean decode(ShortBuffer buffer, boolean flush) { - checkNotReleased(); - - if (!buffer.isDirect()) { - throw new IllegalArgumentException("Buffer argument must be a direct buffer."); - } - - int result = library.decode(instance, buffer, buffer.capacity(), flush); - if (result != 0 && result != ERROR_NOT_ENOUGH_BITS) { - throw new IllegalStateException("Error from decoder " + result); - } - - return result == 0; - } - - /** - * @return Correct stream info. The values passed to configure method do not account for SBR and PS and detecting - * these is a part of the decoding process. If there was not enough input for decoding a full frame, null is - * returned. - * @throws IllegalStateException If the decoder result produced an unexpected error. - */ - public synchronized StreamInfo resolveStreamInfo() { - checkNotReleased(); - - int result = library.decode(instance, NO_BUFFER, 0, false); - - if (result == ERROR_NOT_ENOUGH_BITS) { - return null; - } else if (result != ERROR_OUTPUT_BUFFER_TOO_SMALL) { - throw new IllegalStateException("Expected decoding to halt, got: " + result); - } - - long combinedValue = library.getStreamInfo(instance); - if (combinedValue == 0) { - throw new IllegalStateException("Native library failed to detect stream info."); - } - - return new StreamInfo( - (int) (combinedValue >>> 32L), - (int) (combinedValue & 0xFFFF), - (int) ((combinedValue >>> 16L) & 0xFFFF) - ); - } - - @Override - protected void freeResources() { - library.destroy(instance); - } - - /** - * AAC stream information. - */ - public static class StreamInfo { - /** - * Sample rate (adjusted to SBR) of the current stream. - */ - public final int sampleRate; - /** - * Channel count (adjusted to PS) of the current stream. - */ - public final int channels; - /** - * Number of samples per channel per frame. - */ - public final int frameSize; - - /** - * @param sampleRate Sample rate (adjusted to SBR) of the current stream. - * @param channels Channel count (adjusted to PS) of the current stream. - * @param frameSize Number of samples per channel per frame. - */ - public StreamInfo(int sampleRate, int channels, int frameSize) { - this.sampleRate = sampleRate; - this.channels = channels; - this.frameSize = frameSize; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/aac/AacDecoderLibrary.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/aac/AacDecoderLibrary.java deleted file mode 100644 index 2b9e76d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/aac/AacDecoderLibrary.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.aac; - -import com.sedmelluq.discord.lavaplayer.natives.ConnectorNativeLibLoader; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -class AacDecoderLibrary { - private AacDecoderLibrary() { - - } - - static AacDecoderLibrary getInstance() { - ConnectorNativeLibLoader.loadConnectorLibrary(); - return new AacDecoderLibrary(); - } - - native long create(int transportType); - - native void destroy(long instance); - - native int configure(long instance, long bufferData); - - native int fill(long instance, ByteBuffer directBuffer, int offset, int length); - - native int decode(long instance, ShortBuffer directBuffer, int length, boolean flush); - - native long getStreamInfo(long instance); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/mp3/Mp3Decoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/mp3/Mp3Decoder.java deleted file mode 100644 index 7195c80..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/mp3/Mp3Decoder.java +++ /dev/null @@ -1,257 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.mp3; - -import com.sedmelluq.lava.common.natives.NativeResourceHolder; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -/** - * A wrapper around the native methods of OpusDecoderLibrary. - */ -public class Mp3Decoder extends NativeResourceHolder { - public static final long MPEG1_SAMPLES_PER_FRAME = 1152; - public static final long MPEG2_SAMPLES_PER_FRAME = 576; - public static final int HEADER_SIZE = 4; - - private static final int ERROR_NEED_MORE = -10; - private static final int ERROR_NEW_FORMAT = -11; - - private final Mp3DecoderLibrary library; - private final long instance; - - /** - * Create a new instance of mp3 decoder - */ - public Mp3Decoder() { - library = Mp3DecoderLibrary.getInstance(); - instance = library.create(); - - if (instance == 0) { - throw new IllegalStateException("Failed to create a decoder instance"); - } - } - - /** - * Encode the input buffer to output. - * - * @param directInput Input byte buffer - * @param directOutput Output sample buffer - * @return Number of samples written to the output - */ - public int decode(ByteBuffer directInput, ShortBuffer directOutput) { - checkNotReleased(); - - if (!directInput.isDirect() || !directOutput.isDirect()) { - throw new IllegalArgumentException("Arguments must be direct buffers."); - } - - int result = library.decode(instance, directInput, directInput.remaining(), directOutput, directOutput.remaining() * 2); - - while (result == ERROR_NEW_FORMAT) { - result = library.decode(instance, directInput, 0, directOutput, directOutput.remaining() * 2); - } - - if (result == ERROR_NEED_MORE) { - result = 0; - } else if (result < 0) { - throw new IllegalStateException("Decoding failed with error " + result); - } - - directOutput.position(result / 2); - directOutput.flip(); - - return result / 2; - } - - @Override - protected void freeResources() { - library.destroy(instance); - } - - private static int getFrameBitRate(byte[] buffer, int offset) { - return isMpegVersionOne(buffer, offset) ? getFrameBitRateV1(buffer, offset) : getFrameBitRateV2(buffer, offset); - } - - private static int getFrameBitRateV1(byte[] buffer, int offset) { - switch ((buffer[offset + 2] & 0xF0) >>> 4) { - case 1: - return 32000; - case 2: - return 40000; - case 3: - return 48000; - case 4: - return 56000; - case 5: - return 64000; - case 6: - return 80000; - case 7: - return 96000; - case 8: - return 112000; - case 9: - return 128000; - case 10: - return 160000; - case 11: - return 192000; - case 12: - return 224000; - case 13: - return 256000; - case 14: - return 320000; - default: - throw new IllegalArgumentException("Not valid bitrate"); - } - } - - private static int getFrameBitRateV2(byte[] buffer, int offset) { - switch ((buffer[offset + 2] & 0xF0) >>> 4) { - case 1: - return 8000; - case 2: - return 16000; - case 3: - return 24000; - case 4: - return 32000; - case 5: - return 40000; - case 6: - return 48000; - case 7: - return 56000; - case 8: - return 64000; - case 9: - return 80000; - case 10: - return 96000; - case 11: - return 112000; - case 12: - return 128000; - case 13: - return 140000; - case 14: - return 160000; - default: - throw new IllegalArgumentException("Not valid bitrate"); - } - } - - private static int calculateFrameSize(boolean isVersionOne, int bitRate, int sampleRate, boolean hasPadding) { - return (isVersionOne ? 144 : 72) * bitRate / sampleRate + (hasPadding ? 1 : 0); - } - - /** - * Get the sample rate for the current frame - * - * @param buffer Buffer which contains the frame header - * @param offset Offset to the frame header - * @return Sample rate - */ - public static int getFrameSampleRate(byte[] buffer, int offset) { - return isMpegVersionOne(buffer, offset) ? getFrameSampleRateV1(buffer, offset) : getFrameSampleRateV2(buffer, offset); - } - - /** - * Get the number of channels in the current frame - * - * @param buffer Buffer which contains the frame header - * @param offset Offset to the frame header - * @return Number of channels - */ - public static int getFrameChannelCount(byte[] buffer, int offset) { - return (buffer[offset + 3] & 0xC0) == 0xC0 ? 1 : 2; - } - - private static int getFrameSampleRateV1(byte[] buffer, int offset) { - switch ((buffer[offset + 2] & 0x0C) >>> 2) { - case 0: - return 44100; - case 1: - return 48000; - case 2: - return 32000; - default: - throw new IllegalArgumentException("Not valid sample rate"); - } - } - - private static int getFrameSampleRateV2(byte[] buffer, int offset) { - switch ((buffer[offset + 2] & 0x0C) >>> 2) { - case 0: - return 22050; - case 1: - return 24000; - case 2: - return 16000; - default: - throw new IllegalArgumentException("Not valid sample rate"); - } - } - - /** - * Get the frame size of the specified 4 bytes - * - * @param buffer Buffer which contains the frame header - * @param offset Offset to the frame header - * @return Frame size, or zero if not a valid frame header - */ - public static int getFrameSize(byte[] buffer, int offset) { - int first = buffer[offset] & 0xFF; - int second = buffer[offset + 1] & 0xFF; - int third = buffer[offset + 2] & 0xFF; - - boolean invalid = (first != 0xFF || (second & 0xE0) != 0xE0) // Frame sync does not match - || (second & 0x10) != 0x10 // Not MPEG-1 nor MPEG-2, not dealing with this stuff - || (second & 0x06) != 0x02 // Not Layer III, not dealing with this stuff - || (third & 0xF0) == 0x00 // No defined bitrate - || (third & 0xF0) == 0xF0 // Invalid bitrate - || (third & 0x0C) == 0x0C; // Invalid sampling rate - - if (invalid) { - return 0; - } - - int bitRate = getFrameBitRate(buffer, offset); - int sampleRate = getFrameSampleRate(buffer, offset); - boolean hasPadding = (third & 0x02) != 0; - - return calculateFrameSize(isMpegVersionOne(buffer, offset), bitRate, sampleRate, hasPadding); - } - - /** - * Get the average frame size based on this frame - * - * @param buffer Buffer which contains the frame header - * @param offset Offset to the frame header - * @return Average frame size, assuming CBR - */ - public static double getAverageFrameSize(byte[] buffer, int offset) { - int bitRate = getFrameBitRate(buffer, offset); - int sampleRate = getFrameSampleRate(buffer, offset); - - return (isMpegVersionOne(buffer, offset) ? 144.0 : 72.0) * bitRate / sampleRate; - } - - /** - * @param buffer Buffer which contains the frame header - * @param offset Offset to the frame header - * @return Number of samples per frame. - */ - public static long getSamplesPerFrame(byte[] buffer, int offset) { - return isMpegVersionOne(buffer, offset) ? MPEG1_SAMPLES_PER_FRAME : MPEG2_SAMPLES_PER_FRAME; - } - - private static boolean isMpegVersionOne(byte[] buffer, int offset) { - return (buffer[offset + 1] & 0x08) == 0x08; - } - - public static int getMaximumFrameSize() { - return calculateFrameSize(true, 320000, 32000, true); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/mp3/Mp3DecoderLibrary.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/mp3/Mp3DecoderLibrary.java deleted file mode 100644 index 91e1dbe..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/mp3/Mp3DecoderLibrary.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.mp3; - -import com.sedmelluq.discord.lavaplayer.natives.ConnectorNativeLibLoader; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -class Mp3DecoderLibrary { - private Mp3DecoderLibrary() { - - } - - static Mp3DecoderLibrary getInstance() { - ConnectorNativeLibLoader.loadConnectorLibrary(); - return new Mp3DecoderLibrary(); - } - - native long create(); - - native void destroy(long instance); - - native int decode(long instance, ByteBuffer directInput, int inputLength, ShortBuffer directOutput, int outputLengthInBytes); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusDecoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusDecoder.java deleted file mode 100644 index 8614cab..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusDecoder.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.opus; - -import com.sedmelluq.lava.common.natives.NativeResourceHolder; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -/** - * A wrapper around the native methods of OpusDecoderLibrary. - */ -public class OpusDecoder extends NativeResourceHolder { - private final OpusDecoderLibrary library; - private final long instance; - private final int channels; - - /** - * @param sampleRate Input sample rate - * @param channels Channel count - */ - public OpusDecoder(int sampleRate, int channels) { - library = OpusDecoderLibrary.getInstance(); - instance = library.create(sampleRate, channels); - this.channels = channels; - - if (instance == 0) { - throw new IllegalStateException("Failed to create a decoder instance with sample rate " + - sampleRate + " and channel count " + channels); - } - } - - /** - * Encode the input buffer to output. - * - * @param directInput Input byte buffer - * @param directOutput Output sample buffer - * @return Number of bytes written to the output - */ - public int decode(ByteBuffer directInput, ShortBuffer directOutput) { - checkNotReleased(); - - if (!directInput.isDirect() || !directOutput.isDirect()) { - throw new IllegalArgumentException("Arguments must be direct buffers."); - } - - directOutput.clear(); - int result = library.decode(instance, directInput, directInput.remaining(), directOutput, directOutput.remaining() / channels); - - if (result < 0) { - throw new IllegalStateException("Decoding failed with error " + result); - } - - directOutput.position(result * channels); - directOutput.flip(); - - return result; - } - - @Override - protected void freeResources() { - library.destroy(instance); - } - - /** - * Get the frame size from an opus packet - * - * @param sampleRate The sample rate of the packet - * @param buffer The buffer containing the packet - * @param offset Packet offset in the buffer - * @param length Packet length in the buffer - * @return Frame size - */ - public static int getPacketFrameSize(int sampleRate, byte[] buffer, int offset, int length) { - if (length < 1) { - return 0; - } - - int frameCount = getPacketFrameCount(buffer, offset, length); - if (frameCount < 0) { - return 0; - } - - int samples = frameCount * getPacketSamplesPerFrame(sampleRate, buffer[offset]); - if (samples * 25 > sampleRate * 3) { - return 0; - } - - return samples; - } - - private static int getPacketFrameCount(byte[] buffer, int offset, int length) { - switch (buffer[offset] & 0x03) { - case 0: - return 1; - case 3: - return length < 2 ? -1 : buffer[offset + 1] & 0x3F; - default: - return 2; - } - } - - private static int getPacketSamplesPerFrame(int frequency, int firstByte) { - int shiftBits = (firstByte >> 3) & 0x03; - - if ((firstByte & 0x80) != 0) { - return (frequency << shiftBits) / 400; - } else if ((firstByte & 0x60) == 0x60) { - return (firstByte & 0x08) != 0 ? frequency / 50 : frequency / 100; - } else if (shiftBits == 3) { - return frequency * 60 / 1000; - } else { - return (frequency << shiftBits) / 100; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusDecoderLibrary.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusDecoderLibrary.java deleted file mode 100644 index 93a3a9e..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusDecoderLibrary.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.opus; - -import com.sedmelluq.discord.lavaplayer.natives.ConnectorNativeLibLoader; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -class OpusDecoderLibrary { - private OpusDecoderLibrary() { - - } - - static OpusDecoderLibrary getInstance() { - ConnectorNativeLibLoader.loadConnectorLibrary(); - return new OpusDecoderLibrary(); - } - - native long create(int sampleRate, int channels); - - native void destroy(long instance); - - native int decode(long instance, ByteBuffer directInput, int inputSize, ShortBuffer directOutput, int frameSize); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusEncoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusEncoder.java deleted file mode 100644 index e4ae12e..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusEncoder.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.opus; - -import com.sedmelluq.lava.common.natives.NativeResourceHolder; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -/** - * A wrapper around the native methods of OpusEncoderLibrary. - */ -public class OpusEncoder extends NativeResourceHolder { - private final OpusEncoderLibrary library; - private final long instance; - - /** - * @param sampleRate Input sample rate - * @param channels Channel count - * @param quality Encoding quality (0-10) - */ - public OpusEncoder(int sampleRate, int channels, int quality) { - library = OpusEncoderLibrary.getInstance(); - instance = library.create(sampleRate, channels, OpusEncoderLibrary.APPLICATION_AUDIO, quality); - - if (instance == 0) { - throw new IllegalStateException("Failed to create an encoder instance"); - } - } - - /** - * Encode the input buffer to output. - * - * @param directInput Input sample buffer - * @param frameSize Number of samples per channel - * @param directOutput Output byte buffer - * @return Number of bytes written to the output - */ - public int encode(ShortBuffer directInput, int frameSize, ByteBuffer directOutput) { - checkNotReleased(); - - if (!directInput.isDirect() || !directOutput.isDirect()) { - throw new IllegalArgumentException("Arguments must be direct buffers."); - } - - directOutput.clear(); - int result = library.encode(instance, directInput, frameSize, directOutput, directOutput.capacity()); - - if (result < 0) { - throw new IllegalStateException("Encoding failed with error " + result); - } - - directOutput.position(result); - directOutput.flip(); - - return result; - } - - @Override - protected void freeResources() { - library.destroy(instance); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusEncoderLibrary.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusEncoderLibrary.java deleted file mode 100644 index b19a47f..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/opus/OpusEncoderLibrary.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.opus; - -import com.sedmelluq.discord.lavaplayer.natives.ConnectorNativeLibLoader; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -class OpusEncoderLibrary { - static final int APPLICATION_AUDIO = 2049; - - private OpusEncoderLibrary() { - - } - - static OpusEncoderLibrary getInstance() { - ConnectorNativeLibLoader.loadConnectorLibrary(); - return new OpusEncoderLibrary(); - } - - native long create(int sampleRate, int channels, int application, int quality); - - native void destroy(long instance); - - native int encode(long instance, ShortBuffer directInput, int frameSize, ByteBuffer directOutput, int outputCapacity); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/samplerate/SampleRateConverter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/samplerate/SampleRateConverter.java deleted file mode 100644 index 13b1133..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/samplerate/SampleRateConverter.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.samplerate; - -import com.sedmelluq.lava.common.natives.NativeResourceHolder; - -/** - * Sample rate converter backed by libsamplerate - */ -public class SampleRateConverter extends NativeResourceHolder { - private final SampleRateLibrary library; - private final double ratio; - private final long instance; - - /** - * @param type Resampling type - * @param channels Number of channels - * @param sourceRate Source sample rate - * @param targetRate Target sample rate - */ - public SampleRateConverter(ResamplingType type, int channels, int sourceRate, int targetRate) { - ratio = (double) targetRate / (double) sourceRate; - library = SampleRateLibrary.getInstance(); - instance = library.create(type.ordinal(), channels); - - if (instance == 0) { - throw new IllegalStateException("Could not create an instance of sample rate converter."); - } - } - - /** - * Reset the converter, makes sure previous data does not affect next incoming data - */ - public void reset() { - checkNotReleased(); - - library.reset(instance); - } - - /** - * @param input Input buffer - * @param inputOffset Offset for input buffer - * @param inputLength Length for input buffer - * @param output Output buffer - * @param outputOffset Offset for output buffer - * @param outputLength Length for output buffer - * @param endOfInput If this is the last piece of input - * @param progress Instance that is filled with the progress - */ - public void process(float[] input, int inputOffset, int inputLength, float[] output, int outputOffset, int outputLength, boolean endOfInput, Progress progress) { - checkNotReleased(); - - int error = library.process(instance, input, inputOffset, inputLength, output, outputOffset, outputLength, endOfInput, ratio, progress.fields); - - if (error != 0) { - throw new RuntimeException("Failed to convert sample rate, error " + error + "."); - } - } - - @Override - protected void freeResources() { - library.destroy(instance); - } - - /** - * Progress of converting one piece of data - */ - public static class Progress { - private final int[] fields = new int[2]; - - /** - * @return Number of samples used from the input buffer - */ - public int getInputUsed() { - return fields[0]; - } - - /** - * @return Number of samples written to the output buffer - */ - public int getOutputGenerated() { - return fields[1]; - } - } - - /** - * Available resampling types - */ - public enum ResamplingType { - SINC_BEST_QUALITY, - SINC_MEDIUM_QUALITY, - SINC_FASTEST, - ZERO_ORDER_HOLD, - LINEAR - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/samplerate/SampleRateLibrary.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/samplerate/SampleRateLibrary.java deleted file mode 100644 index ece33ed..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/samplerate/SampleRateLibrary.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.samplerate; - -import com.sedmelluq.discord.lavaplayer.natives.ConnectorNativeLibLoader; - -class SampleRateLibrary { - private SampleRateLibrary() { - - } - - static SampleRateLibrary getInstance() { - ConnectorNativeLibLoader.loadConnectorLibrary(); - return new SampleRateLibrary(); - } - - native long create(int type, int channels); - - native void destroy(long instance); - - native void reset(long instance); - - native int process(long instance, float[] in, int inOffset, int inLength, float[] out, int outOffset, int outLength, boolean endOfInput, double sourceRatio, int[] progress); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/statistics/CpuStatistics.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/statistics/CpuStatistics.java deleted file mode 100644 index 93043eb..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/statistics/CpuStatistics.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.statistics; - -import static com.sedmelluq.discord.lavaplayer.natives.statistics.CpuStatisticsLibrary.Timings.*; - -/** - * Provides information about system CPU usage. - */ -public class CpuStatistics { - private static final int TIMINGS_LENGTH = CpuStatisticsLibrary.Timings.class.getEnumConstants().length; - - private final CpuStatisticsLibrary library = CpuStatisticsLibrary.getInstance(); - - /** - * @return Absolute CPU timings at the current moment - */ - public Times getSystemTimes() { - long[] values = new long[TIMINGS_LENGTH]; - library.getSystemTimes(values); - - return new Times( - values[SYSTEM_TOTAL.id()], - values[SYSTEM_USER.id()], - values[SYSTEM_KERNEL.id()], - values[PROCESS_USER.id()], - values[PROCESS_KERNEL.id()] - ); - } - - /** - * CPU timings - */ - public static class Times { - /** - * Total amount of CPU time since system start - */ - public final long systemTotal; - /** - * Total amount of CPU time spent in user mode - */ - public final long systemUser; - /** - * Total amount of CPU time spent in kernel mode - */ - public final long systemKernel; - /** - * Total amount of CPU time this process has spent in user mode - */ - public final long processUser; - /** - * Total amount of CPU time this process has spent in kernel mode - */ - public final long processKernel; - - /** - * @param systemTotal Total amount of CPU time since system start - * @param systemUser Total amount of CPU time spent in user mode - * @param systemKernel Total amount of CPU time spent in kernel mode - * @param processUser Total amount of CPU time this process has spent in user mode - * @param processKernel Total amount of CPU time this process has spent in kernel mode - */ - public Times(long systemTotal, long systemUser, long systemKernel, long processUser, long processKernel) { - this.systemTotal = systemTotal; - this.systemUser = systemUser; - this.systemKernel = systemKernel; - this.processUser = processUser; - this.processKernel = processKernel; - } - - /** - * @return The ratio of used CPU time to total CPU time - */ - public float getSystemUsage() { - if (systemTotal == 0) { - return 0.0f; - } else { - return (float) (systemUser + systemKernel) / systemTotal; - } - } - - /** - * @return The ratio of used CPU time by current process to total CPU time - */ - public float getProcessUsage() { - if (systemTotal == 0) { - return 0.0f; - } else { - return (float) (processUser + processKernel) / systemTotal; - } - } - } - - /** - * @param old Older timing values - * @param current Newer timing values - * @return Difference between two timings - */ - public static Times diff(Times old, Times current) { - return new Times( - current.systemTotal - old.systemTotal, - current.systemUser - old.systemUser, - current.systemKernel - old.systemKernel, - current.processUser - old.processUser, - current.processKernel - old.processKernel - ); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/statistics/CpuStatisticsLibrary.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/statistics/CpuStatisticsLibrary.java deleted file mode 100644 index d7fe6f1..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/statistics/CpuStatisticsLibrary.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.statistics; - -import com.sedmelluq.discord.lavaplayer.natives.ConnectorNativeLibLoader; - -class CpuStatisticsLibrary { - private CpuStatisticsLibrary() { - - } - - static CpuStatisticsLibrary getInstance() { - ConnectorNativeLibLoader.loadConnectorLibrary(); - return new CpuStatisticsLibrary(); - } - - native void getSystemTimes(long[] timingArray); - - enum Timings { - SYSTEM_TOTAL, - SYSTEM_USER, - SYSTEM_KERNEL, - PROCESS_USER, - PROCESS_KERNEL; - - int id() { - return ordinal(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/vorbis/VorbisDecoder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/vorbis/VorbisDecoder.java deleted file mode 100644 index 5892da7..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/vorbis/VorbisDecoder.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.vorbis; - -import com.sedmelluq.lava.common.natives.NativeResourceHolder; - -import java.nio.ByteBuffer; - -/** - * A wrapper around the native methods of AacDecoder, which uses libvorbis native library. - */ -public class VorbisDecoder extends NativeResourceHolder { - private final VorbisDecoderLibrary library; - private final long instance; - private int channelCount = 0; - - /** - * Create an instance. - */ - public VorbisDecoder() { - library = VorbisDecoderLibrary.getInstance(); - instance = library.create(); - } - - /** - * Initialize the decoder by passing in identification and setup header data. See - * https://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-170001.2.6 for definitions. The comment header is not required as - * it is not actually used for decoding setup. - * - * @param infoBuffer Identification header, including the 'vorbis' string. - * @param setupBuffer Setup header (also known as codebook header), including the 'vorbis' string. - */ - public void initialise(ByteBuffer infoBuffer, ByteBuffer setupBuffer) { - checkNotReleased(); - - if (!infoBuffer.isDirect() || !setupBuffer.isDirect()) { - throw new IllegalArgumentException("Buffer argument must be a direct buffer."); - } - - if (!library.initialise(instance, infoBuffer, infoBuffer.position(), infoBuffer.remaining(), setupBuffer, - setupBuffer.position(), setupBuffer.remaining())) { - - throw new IllegalStateException("Could not initialise library."); - } - - channelCount = library.getChannelCount(instance); - } - - /** - * Get the number of channels, valid only after initialisation. - * - * @return Number of channels - */ - public int getChannelCount() { - return channelCount; - } - - /** - * Provide input for the decoder - * - * @param buffer Buffer with the input - */ - public void input(ByteBuffer buffer) { - checkNotReleased(); - - if (!buffer.isDirect()) { - throw new IllegalArgumentException("Buffer argument must be a direct buffer."); - } - - int result = library.input(instance, buffer, buffer.position(), buffer.remaining()); - buffer.position(buffer.position() + buffer.remaining()); - - if (result != 0) { - throw new IllegalStateException("Passing input failed with error " + result + "."); - } - } - - /** - * Fetch output from the decoder - * - * @param channels Channel buffers to fetch the output to - * @return The number of samples fetched for each channel - */ - public int output(float[][] channels) { - checkNotReleased(); - - if (channels.length != channelCount) { - throw new IllegalStateException("Invalid channel float buffer length"); - } - - int result = library.output(instance, channels, channels[0].length); - if (result < 0) { - throw new IllegalStateException("Retrieving output failed"); - } - - return result; - } - - @Override - protected void freeResources() { - library.destroy(instance); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/vorbis/VorbisDecoderLibrary.java b/src/main/java/com/sedmelluq/discord/lavaplayer/natives/vorbis/VorbisDecoderLibrary.java deleted file mode 100644 index f3e4ab9..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/natives/vorbis/VorbisDecoderLibrary.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.natives.vorbis; - -import com.sedmelluq.discord.lavaplayer.natives.ConnectorNativeLibLoader; - -import java.nio.ByteBuffer; - -class VorbisDecoderLibrary { - private VorbisDecoderLibrary() { - - } - - static VorbisDecoderLibrary getInstance() { - ConnectorNativeLibLoader.loadConnectorLibrary(); - return new VorbisDecoderLibrary(); - } - - native long create(); - - native void destroy(long instance); - - native boolean initialise(long instance, ByteBuffer infoBuffer, int infoOffset, int infoLength, - ByteBuffer setupBuffer, int setupOffset, int setupLength); - - native int getChannelCount(long instance); - - native int input(long instance, ByteBuffer directBuffer, int offset, int length); - - native int output(long instance, float[][] channels, int length); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioConfiguration.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioConfiguration.java deleted file mode 100644 index d8ed1c4..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioConfiguration.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.format.StandardAudioDataFormats; -import com.sedmelluq.discord.lavaplayer.track.playback.AllocatingAudioFrameBuffer; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameBufferFactory; - -/** - * Configuration for audio processing. - */ -public class AudioConfiguration { - public static final int OPUS_QUALITY_MAX = 10; - - private volatile ResamplingQuality resamplingQuality; - private volatile int opusEncodingQuality; - private volatile AudioDataFormat outputFormat; - private volatile boolean filterHotSwapEnabled; - private volatile AudioFrameBufferFactory frameBufferFactory; - - /** - * Create a new configuration with default values. - */ - public AudioConfiguration() { - resamplingQuality = ResamplingQuality.LOW; - opusEncodingQuality = OPUS_QUALITY_MAX; - outputFormat = StandardAudioDataFormats.DISCORD_OPUS; - filterHotSwapEnabled = false; - frameBufferFactory = AllocatingAudioFrameBuffer::new; - } - - public ResamplingQuality getResamplingQuality() { - return resamplingQuality; - } - - public void setResamplingQuality(ResamplingQuality resamplingQuality) { - this.resamplingQuality = resamplingQuality; - } - - public int getOpusEncodingQuality() { - return opusEncodingQuality; - } - - public void setOpusEncodingQuality(int opusEncodingQuality) { - this.opusEncodingQuality = Math.max(0, Math.min(opusEncodingQuality, OPUS_QUALITY_MAX)); - } - - public AudioDataFormat getOutputFormat() { - return outputFormat; - } - - public void setOutputFormat(AudioDataFormat outputFormat) { - this.outputFormat = outputFormat; - } - - public boolean isFilterHotSwapEnabled() { - return filterHotSwapEnabled; - } - - public void setFilterHotSwapEnabled(boolean filterHotSwapEnabled) { - this.filterHotSwapEnabled = filterHotSwapEnabled; - } - - public AudioFrameBufferFactory getFrameBufferFactory() { - return frameBufferFactory; - } - - public void setFrameBufferFactory(AudioFrameBufferFactory frameBufferFactory) { - this.frameBufferFactory = frameBufferFactory; - } - - /** - * @return A copy of this configuration. - */ - public AudioConfiguration copy() { - AudioConfiguration copy = new AudioConfiguration(); - copy.setResamplingQuality(resamplingQuality); - copy.setOpusEncodingQuality(opusEncodingQuality); - copy.setOutputFormat(outputFormat); - copy.setFilterHotSwapEnabled(filterHotSwapEnabled); - copy.setFrameBufferFactory(frameBufferFactory); - return copy; - } - - /** - * Resampling quality levels - */ - public enum ResamplingQuality { - HIGH, - MEDIUM, - LOW - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioLoadResultHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioLoadResultHandler.java deleted file mode 100644 index 8ef4c95..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioLoadResultHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player; - -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; - -/** - * Handles the result of loading an item from an audio player manager. - */ -public interface AudioLoadResultHandler { - /** - * Called when the requested item is a track and it was successfully loaded. - * - * @param track The loaded track - */ - void trackLoaded(AudioTrack track); - - /** - * Called when the requested item is a playlist and it was successfully loaded. - * - * @param playlist The loaded playlist - */ - void playlistLoaded(AudioPlaylist playlist); - - /** - * Called when there were no items found by the specified identifier. - */ - void noMatches(); - - /** - * Called when loading an item failed with an exception. - * - * @param exception The exception that was thrown - */ - void loadFailed(FriendlyException exception); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayer.java deleted file mode 100644 index 3637a83..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayer.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player; - -import com.sedmelluq.discord.lavaplayer.filter.PcmFilterFactory; -import com.sedmelluq.discord.lavaplayer.player.event.AudioEventListener; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameProvider; - -/** - * An audio player that is capable of playing audio tracks and provides audio frames from the currently playing track. - */ -public interface AudioPlayer extends AudioFrameProvider { - /** - * @return Currently playing track - */ - AudioTrack getPlayingTrack(); - - /** - * @param track The track to start playing - */ - void playTrack(AudioTrack track); - - /** - * @param track The track to start playing, passing null will stop the current track and return false - * @param noInterrupt Whether to only start if nothing else is playing - * @return True if the track was started - */ - boolean startTrack(AudioTrack track, boolean noInterrupt); - - /** - * Stop currently playing track. - */ - void stopTrack(); - - int getVolume(); - - void setVolume(int volume); - - void setFilterFactory(PcmFilterFactory factory); - - void setFrameBufferDuration(Integer duration); - - /** - * @return Whether the player is paused - */ - boolean isPaused(); - - /** - * @param value True to pause, false to resume - */ - void setPaused(boolean value); - - /** - * Destroy the player and stop playing track. - */ - void destroy(); - - /** - * Add a listener to events from this player. - * - * @param listener New listener - */ - void addListener(AudioEventListener listener); - - /** - * Remove an attached listener using identity comparison. - * - * @param listener The listener to remove - */ - void removeListener(AudioEventListener listener); - - /** - * Check if the player should be "cleaned up" - stopped due to nothing using it, with the given threshold. - * - * @param threshold Threshold in milliseconds to use - */ - void checkCleanup(long threshold); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerLifecycleManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerLifecycleManager.java deleted file mode 100644 index c1bfd1b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerLifecycleManager.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player; - -import com.sedmelluq.discord.lavaplayer.player.event.AudioEvent; -import com.sedmelluq.discord.lavaplayer.player.event.AudioEventListener; -import com.sedmelluq.discord.lavaplayer.player.event.TrackEndEvent; -import com.sedmelluq.discord.lavaplayer.player.event.TrackStartEvent; - -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Triggers cleanup checks on all active audio players at a fixed interval. - */ -public class AudioPlayerLifecycleManager implements Runnable, AudioEventListener { - private static final long CHECK_INTERVAL = 10000; - - private final ConcurrentMap activePlayers; - private final ScheduledExecutorService scheduler; - private final AtomicLong cleanupThreshold; - private final AtomicReference> scheduledTask; - - /** - * @param scheduler Scheduler to use for the cleanup check task - * @param cleanupThreshold Threshold for player cleanup - */ - public AudioPlayerLifecycleManager(ScheduledExecutorService scheduler, AtomicLong cleanupThreshold) { - this.activePlayers = new ConcurrentHashMap<>(); - this.scheduler = scheduler; - this.cleanupThreshold = cleanupThreshold; - this.scheduledTask = new AtomicReference<>(); - } - - /** - * Initialise the scheduled task. - */ - public void initialise() { - ScheduledFuture task = scheduler.scheduleAtFixedRate(this, CHECK_INTERVAL, CHECK_INTERVAL, TimeUnit.MILLISECONDS); - if (!scheduledTask.compareAndSet(null, task)) { - task.cancel(false); - } - } - - /** - * Stop the scheduled task. - */ - public void shutdown() { - ScheduledFuture task = scheduledTask.getAndSet(null); - if (task != null) { - task.cancel(false); - } - } - - @Override - public void onEvent(AudioEvent event) { - if (event instanceof TrackStartEvent) { - activePlayers.put(event.player, event.player); - } else if (event instanceof TrackEndEvent) { - activePlayers.remove(event.player); - } - } - - @Override - public void run() { - for (AudioPlayer player : activePlayers.keySet()) { - player.checkCleanup(cleanupThreshold.get()); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerManager.java deleted file mode 100644 index 4b75e80..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerManager.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player; - -import com.sedmelluq.discord.lavaplayer.remote.RemoteNodeRegistry; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.io.MessageInput; -import com.sedmelluq.discord.lavaplayer.tools.io.MessageOutput; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.DecodedTrackHolder; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.HttpClientBuilder; - -import java.io.IOException; -import java.util.concurrent.Future; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Audio player manager which is used for creating audio players and loading tracks and playlists. - */ -public interface AudioPlayerManager { - - /** - * Shut down the manager. All threads will be stopped, the manager cannot be used any further. All players created - * with this manager will stop and all source managers registered to this manager will also be shut down. - *

- * Every thread created by the audio manager is a daemon thread, so calling this is not required for an application - * to be able to gracefully shut down, however it should be called if the application continues without requiring this - * manager any longer. - */ - void shutdown(); - - /** - * Configure to use remote nodes for playback. On consecutive calls, the connections with previously used nodes will - * be severed and all remotely playing tracks will be stopped first. - * - * @param nodeAddresses The addresses of the remote nodes - */ - void useRemoteNodes(String... nodeAddresses); - - /** - * Enable reporting GC pause length statistics to log (warn level with lengths bad for latency, debug level otherwise) - */ - void enableGcMonitoring(); - - /** - * @param sourceManager The source manager to register, which will be used for subsequent loadItem calls - */ - void registerSourceManager(AudioSourceManager sourceManager); - - /** - * Shortcut for accessing a source manager of a certain class. - * - * @param klass The class of the source manager to return. - * @param The class of the source manager. - * @return The source manager of the specified class, or null if not registered. - */ - T source(Class klass); - - /** - * Schedules loading a track or playlist with the specified identifier. - * - * @param identifier The identifier that a specific source manager should be able to find the track with. - * @param resultHandler A handler to process the result of this operation. It can either end by finding a track, - * finding a playlist, finding nothing or terminating with an exception. - * @return A future for this operation - */ - Future loadItem(final String identifier, final AudioLoadResultHandler resultHandler); - - /** - * Schedules loading a track or playlist with the specified identifier with an ordering key so that items with the - * same ordering key are handled sequentially in the order of calls to this method. - * - * @param orderingKey Object to use as the key for the ordering channel - * @param identifier The identifier that a specific source manager should be able to find the track with. - * @param resultHandler A handler to process the result of this operation. It can either end by finding a track, - * finding a playlist, finding nothing or terminating with an exception. - * @return A future for this operation - */ - Future loadItemOrdered(Object orderingKey, final String identifier, final AudioLoadResultHandler resultHandler); - - /** - * Encode a track into an output stream. If the decoder is not supposed to know the number of tracks in advance, then - * the encoder should call MessageOutput#finish() after all the tracks it wanted to write have been written. This will - * make decodeTrack() return null at that position - * - * @param stream The message stream to write it to. - * @param track The track to encode. - * @throws IOException On IO error. - */ - void encodeTrack(MessageOutput stream, AudioTrack track) throws IOException; - - /** - * Decode a track from an input stream. Null returns value indicates reaching the position where the decoder had - * called MessageOutput#finish(). - * - * @param stream The message stream to read it from. - * @return Holder containing the track if it was successfully decoded. - * @throws IOException On IO error. - */ - DecodedTrackHolder decodeTrack(MessageInput stream) throws IOException; - - /** - * @return Audio processing configuration used for tracks executed by this manager. - */ - AudioConfiguration getConfiguration(); - - /** - * Seek ghosting is the effect where while a seek is in progress, buffered audio from the previous location will be - * served until seek is ready or the buffer is empty. - * - * @return True if seek ghosting is enabled. - */ - boolean isUsingSeekGhosting(); - - /** - * @param useSeekGhosting The new state of seek ghosting - */ - void setUseSeekGhosting(boolean useSeekGhosting); - - /** - * @return The length of the internal buffer for audio in milliseconds. - */ - int getFrameBufferDuration(); - - /** - * @param frameBufferDuration New length of the internal buffer for audio in milliseconds. - */ - void setFrameBufferDuration(int frameBufferDuration); - - /** - * Sets the threshold for how long a track can be stuck until the TrackStuckEvent is sent out. A track is considered - * to be stuck if the player receives requests for audio samples from the track, but the audio frame provider of that - * track has been returning no data for the specified time. - * - * @param trackStuckThreshold The threshold in milliseconds. - */ - void setTrackStuckThreshold(long trackStuckThreshold); - - /** - * Sets the threshold for clearing an audio player when it has not been queried for the specified amount of time. - * - * @param cleanupThreshold The threshold in milliseconds. - */ - void setPlayerCleanupThreshold(long cleanupThreshold); - - /** - * Sets the number of threads used for loading processing item load requests. - * - * @param poolSize Maximum number of concurrent threads used for loading items. - */ - void setItemLoaderThreadPoolSize(int poolSize); - - /** - * @return New audio player. - */ - AudioPlayer createPlayer(); - - /** - * @return Registry of remote nodes currently used. - */ - RemoteNodeRegistry getRemoteNodeRegistry(); - - /** - * @param configurator Function used to reconfigure the request config of all sources which perform HTTP requests. - * Applied to all current and future registered sources. Setting this while sources are already in - * use will close all active connections, so this should be called before the sources have been - * used. - */ - void setHttpRequestConfigurator(Function configurator); - - /** - * @param configurator Function used to reconfigure the HTTP builder of all sources which perform HTTP requests. - * Applied to all current and future registered sources. Setting this while sources are already in - * use will close all active connections, so this should be called before the sources have been - * used. - */ - void setHttpBuilderConfigurator(Consumer configurator); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerOptions.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerOptions.java deleted file mode 100644 index d0ade0b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/AudioPlayerOptions.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player; - -import com.sedmelluq.discord.lavaplayer.filter.PcmFilterFactory; - -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Mutable options of an audio player which may be applied in real-time. - */ -public class AudioPlayerOptions { - /** - * Volume level of the audio, see {@link AudioPlayer#setVolume(int)}. Applied in real-time. - */ - public final AtomicInteger volumeLevel; - /** - * Current PCM filter factory. Applied in real-time. - */ - public final AtomicReference filterFactory; - /** - * Current frame buffer size. If not set, the global default is used. Changing this only affects the next track that - * is started. - */ - public final AtomicReference frameBufferDuration; - - /** - * New instance of player options. By default, frame buffer duration is not set, hence taken from global settings. - */ - public AudioPlayerOptions() { - this.volumeLevel = new AtomicInteger(100); - this.filterFactory = new AtomicReference<>(); - this.frameBufferDuration = new AtomicReference<>(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/DefaultAudioPlayer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/DefaultAudioPlayer.java deleted file mode 100644 index c7f70d9..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/DefaultAudioPlayer.java +++ /dev/null @@ -1,371 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player; - -import com.sedmelluq.discord.lavaplayer.filter.PcmFilterFactory; -import com.sedmelluq.discord.lavaplayer.player.event.*; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; -import com.sedmelluq.discord.lavaplayer.track.InternalAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.TrackStateListener; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameProviderTools; -import com.sedmelluq.discord.lavaplayer.track.playback.MutableAudioFrame; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; - -import static com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason.*; - -/** - * An audio player that is capable of playing audio tracks and provides audio frames from the currently playing track. - */ -public class DefaultAudioPlayer implements AudioPlayer, TrackStateListener { - private static final Logger log = LoggerFactory.getLogger(AudioPlayer.class); - - private volatile InternalAudioTrack activeTrack; - private volatile long lastRequestTime; - private volatile long lastReceiveTime; - private volatile boolean stuckEventSent; - private volatile InternalAudioTrack shadowTrack; - private final AtomicBoolean paused; - private final DefaultAudioPlayerManager manager; - private final List listeners; - private final Object trackSwitchLock; - private final AudioPlayerOptions options; - - /** - * @param manager Audio player manager which this player is attached to - */ - public DefaultAudioPlayer(DefaultAudioPlayerManager manager) { - this.manager = manager; - activeTrack = null; - paused = new AtomicBoolean(); - listeners = new ArrayList<>(); - trackSwitchLock = new Object(); - options = new AudioPlayerOptions(); - } - - /** - * @return Currently playing track - */ - public AudioTrack getPlayingTrack() { - return activeTrack; - } - - /** - * @param track The track to start playing - */ - public void playTrack(AudioTrack track) { - startTrack(track, false); - } - - /** - * @param track The track to start playing, passing null will stop the current track and return false - * @param noInterrupt Whether to only start if nothing else is playing - * @return True if the track was started - */ - public boolean startTrack(AudioTrack track, boolean noInterrupt) { - InternalAudioTrack newTrack = (InternalAudioTrack) track; - InternalAudioTrack previousTrack; - - synchronized (trackSwitchLock) { - previousTrack = activeTrack; - - if (noInterrupt && previousTrack != null) { - return false; - } - - activeTrack = newTrack; - lastRequestTime = System.currentTimeMillis(); - lastReceiveTime = System.nanoTime(); - stuckEventSent = false; - - if (previousTrack != null) { - previousTrack.stop(); - dispatchEvent(new TrackEndEvent(this, previousTrack, newTrack == null ? STOPPED : REPLACED)); - - shadowTrack = previousTrack; - } - } - - if (newTrack == null) { - shadowTrack = null; - return false; - } - - dispatchEvent(new TrackStartEvent(this, newTrack)); - - manager.executeTrack(this, newTrack, manager.getConfiguration(), options); - return true; - } - - /** - * Stop currently playing track. - */ - public void stopTrack() { - stopWithReason(STOPPED); - } - - private void stopWithReason(AudioTrackEndReason reason) { - shadowTrack = null; - - synchronized (trackSwitchLock) { - InternalAudioTrack previousTrack = activeTrack; - activeTrack = null; - - if (previousTrack != null) { - previousTrack.stop(); - dispatchEvent(new TrackEndEvent(this, previousTrack, reason)); - } - } - } - - private AudioFrame provideShadowFrame() { - InternalAudioTrack shadow = shadowTrack; - AudioFrame frame = null; - - if (shadow != null) { - frame = shadow.provide(); - - if (frame != null && frame.isTerminator()) { - shadowTrack = null; - frame = null; - } - } - - return frame; - } - - private boolean provideShadowFrame(MutableAudioFrame targetFrame) { - InternalAudioTrack shadow = shadowTrack; - - if (shadow != null && shadow.provide(targetFrame)) { - if (targetFrame.isTerminator()) { - shadowTrack = null; - return false; - } - - return true; - } - - return false; - } - - @Override - public AudioFrame provide() { - return AudioFrameProviderTools.delegateToTimedProvide(this); - } - - @Override - public AudioFrame provide(long timeout, TimeUnit unit) throws TimeoutException, InterruptedException { - InternalAudioTrack track; - - lastRequestTime = System.currentTimeMillis(); - - if (timeout == 0 && paused.get()) { - return null; - } - - while ((track = activeTrack) != null) { - AudioFrame frame = timeout > 0 ? track.provide(timeout, unit) : track.provide(); - - if (frame != null) { - lastReceiveTime = System.nanoTime(); - shadowTrack = null; - - if (frame.isTerminator()) { - handleTerminator(track); - continue; - } - } else if (timeout == 0) { - checkStuck(track); - - frame = provideShadowFrame(); - } - - return frame; - } - - return null; - } - - @Override - public boolean provide(MutableAudioFrame targetFrame) { - try { - return provide(targetFrame, 0, TimeUnit.MILLISECONDS); - } catch (TimeoutException | InterruptedException e) { - ExceptionTools.keepInterrupted(e); - throw new RuntimeException(e); - } - } - - @Override - public boolean provide(MutableAudioFrame targetFrame, long timeout, TimeUnit unit) - throws TimeoutException, InterruptedException { - - InternalAudioTrack track; - - lastRequestTime = System.currentTimeMillis(); - - if (timeout == 0 && paused.get()) { - return false; - } - - while ((track = activeTrack) != null) { - if (timeout > 0 ? track.provide(targetFrame, timeout, unit) : track.provide(targetFrame)) { - lastReceiveTime = System.nanoTime(); - shadowTrack = null; - - if (targetFrame.isTerminator()) { - handleTerminator(track); - continue; - } - - return true; - } else if (timeout == 0) { - checkStuck(track); - return provideShadowFrame(targetFrame); - } else { - return false; - } - } - - return false; - } - - private void handleTerminator(InternalAudioTrack track) { - synchronized (trackSwitchLock) { - if (activeTrack == track) { - activeTrack = null; - - dispatchEvent(new TrackEndEvent(this, track, track.getActiveExecutor().failedBeforeLoad() ? LOAD_FAILED : FINISHED)); - } - } - } - - private void checkStuck(AudioTrack track) { - if (!stuckEventSent && System.nanoTime() - lastReceiveTime > manager.getTrackStuckThresholdNanos()) { - stuckEventSent = true; - dispatchEvent(new TrackStuckEvent(this, track, TimeUnit.NANOSECONDS.toMillis(manager.getTrackStuckThresholdNanos()))); - } - } - - public int getVolume() { - return options.volumeLevel.get(); - } - - public void setVolume(int volume) { - options.volumeLevel.set(Math.min(1000, Math.max(0, volume))); - } - - public void setFilterFactory(PcmFilterFactory factory) { - options.filterFactory.set(factory); - } - - public void setFrameBufferDuration(Integer duration) { - if (duration != null) { - duration = Math.max(200, duration); - } - - options.frameBufferDuration.set(duration); - } - - /** - * @return Whether the player is paused - */ - public boolean isPaused() { - return paused.get(); - } - - /** - * @param value True to pause, false to resume - */ - public void setPaused(boolean value) { - if (paused.compareAndSet(!value, value)) { - if (value) { - dispatchEvent(new PlayerPauseEvent(this)); - } else { - dispatchEvent(new PlayerResumeEvent(this)); - lastReceiveTime = System.nanoTime(); - } - } - } - - /** - * Destroy the player and stop playing track. - */ - public void destroy() { - stopTrack(); - } - - /** - * Add a listener to events from this player. - * - * @param listener New listener - */ - public void addListener(AudioEventListener listener) { - synchronized (trackSwitchLock) { - listeners.add(listener); - } - } - - /** - * Remove an attached listener using identity comparison. - * - * @param listener The listener to remove - */ - public void removeListener(AudioEventListener listener) { - synchronized (trackSwitchLock) { - for (Iterator iterator = listeners.iterator(); iterator.hasNext(); ) { - if (iterator.next() == listener) { - iterator.remove(); - } - } - } - } - - private void dispatchEvent(AudioEvent event) { - log.debug("Firing an event with class {}", event.getClass().getSimpleName()); - - synchronized (trackSwitchLock) { - for (AudioEventListener listener : listeners) { - try { - listener.onEvent(event); - } catch (Exception e) { - log.error("Handler of event {} threw an exception.", event, e); - } - } - } - } - - @Override - public void onTrackException(AudioTrack track, FriendlyException exception) { - dispatchEvent(new TrackExceptionEvent(this, track, exception)); - } - - @Override - public void onTrackStuck(AudioTrack track, long thresholdMs) { - dispatchEvent(new TrackStuckEvent(this, track, thresholdMs)); - } - - /** - * Check if the player should be "cleaned up" - stopped due to nothing using it, with the given threshold. - * - * @param threshold Threshold in milliseconds to use - */ - public void checkCleanup(long threshold) { - AudioTrack track = getPlayingTrack(); - if (track != null && System.currentTimeMillis() - lastRequestTime >= threshold) { - log.debug("Triggering cleanup on an audio player playing track {}", track); - - stopWithReason(CLEANUP); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/DefaultAudioPlayerManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/DefaultAudioPlayerManager.java deleted file mode 100644 index e1c362f..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/DefaultAudioPlayerManager.java +++ /dev/null @@ -1,484 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player; - -import com.sedmelluq.discord.lavaplayer.remote.RemoteAudioTrackExecutor; -import com.sedmelluq.discord.lavaplayer.remote.RemoteNodeManager; -import com.sedmelluq.discord.lavaplayer.remote.RemoteNodeRegistry; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.ProbingAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.*; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpConfigurable; -import com.sedmelluq.discord.lavaplayer.tools.io.MessageInput; -import com.sedmelluq.discord.lavaplayer.tools.io.MessageOutput; -import com.sedmelluq.discord.lavaplayer.track.*; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioTrackExecutor; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import com.sedmelluq.lava.common.tools.DaemonThreadFactory; -import com.sedmelluq.lava.common.tools.ExecutorTools; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.HttpClientBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Consumer; -import java.util.function.Function; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.FAULT; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * The default implementation of audio player manager. - */ -public class DefaultAudioPlayerManager implements AudioPlayerManager { - private static final int TRACK_INFO_VERSIONED = 1; - private static final int TRACK_INFO_VERSION = 2; - - private static final int DEFAULT_FRAME_BUFFER_DURATION = (int) TimeUnit.SECONDS.toMillis(5); - private static final int DEFAULT_CLEANUP_THRESHOLD = (int) TimeUnit.MINUTES.toMillis(1); - - private static final int MAXIMUM_LOAD_REDIRECTS = 5; - private static final int DEFAULT_LOADER_POOL_SIZE = 10; - private static final int LOADER_QUEUE_CAPACITY = 5000; - - private static final Logger log = LoggerFactory.getLogger(DefaultAudioPlayerManager.class); - - private final List sourceManagers; - private volatile Function httpConfigurator; - private volatile Consumer httpBuilderConfigurator; - - // Executors - private final ExecutorService trackPlaybackExecutorService; - private final ThreadPoolExecutor trackInfoExecutorService; - private final ScheduledExecutorService scheduledExecutorService; - private final OrderedExecutor orderedInfoExecutor; - - // Configuration - private volatile long trackStuckThreshold; - private volatile AudioConfiguration configuration; - private final AtomicLong cleanupThreshold; - private volatile int frameBufferDuration; - private volatile boolean useSeekGhosting; - - // Additional services - private final RemoteNodeManager remoteNodeManager; - private final GarbageCollectionMonitor garbageCollectionMonitor; - private final AudioPlayerLifecycleManager lifecycleManager; - - - /** - * Create a new instance - */ - public DefaultAudioPlayerManager() { - sourceManagers = new ArrayList<>(); - - // Executors - trackPlaybackExecutorService = new ThreadPoolExecutor(1, Integer.MAX_VALUE, 10, TimeUnit.SECONDS, - new SynchronousQueue<>(), new DaemonThreadFactory("playback")); - trackInfoExecutorService = ExecutorTools.createEagerlyScalingExecutor(1, DEFAULT_LOADER_POOL_SIZE, - TimeUnit.SECONDS.toMillis(30), LOADER_QUEUE_CAPACITY, new DaemonThreadFactory("info-loader")); - scheduledExecutorService = Executors.newScheduledThreadPool(1, new DaemonThreadFactory("manager")); - orderedInfoExecutor = new OrderedExecutor(trackInfoExecutorService); - - // Configuration - trackStuckThreshold = TimeUnit.MILLISECONDS.toNanos(10000); - configuration = new AudioConfiguration(); - cleanupThreshold = new AtomicLong(DEFAULT_CLEANUP_THRESHOLD); - frameBufferDuration = DEFAULT_FRAME_BUFFER_DURATION; - useSeekGhosting = true; - - // Additional services - remoteNodeManager = new RemoteNodeManager(this); - garbageCollectionMonitor = new GarbageCollectionMonitor(scheduledExecutorService); - lifecycleManager = new AudioPlayerLifecycleManager(scheduledExecutorService, cleanupThreshold); - lifecycleManager.initialise(); - } - - @Override - public void shutdown() { - remoteNodeManager.shutdown(true); - garbageCollectionMonitor.disable(); - lifecycleManager.shutdown(); - - for (AudioSourceManager sourceManager : sourceManagers) { - sourceManager.shutdown(); - } - - ExecutorTools.shutdownExecutor(trackPlaybackExecutorService, "track playback"); - ExecutorTools.shutdownExecutor(trackInfoExecutorService, "track info"); - ExecutorTools.shutdownExecutor(scheduledExecutorService, "scheduled operations"); - } - - @Override - public void useRemoteNodes(String... nodeAddresses) { - if (nodeAddresses.length > 0) { - remoteNodeManager.initialise(Arrays.asList(nodeAddresses)); - } else { - remoteNodeManager.shutdown(false); - } - } - - @Override - public void enableGcMonitoring() { - garbageCollectionMonitor.enable(); - } - - @Override - public void registerSourceManager(AudioSourceManager sourceManager) { - sourceManagers.add(sourceManager); - - if (sourceManager instanceof HttpConfigurable) { - Function configurator = httpConfigurator; - - if (configurator != null) { - ((HttpConfigurable) sourceManager).configureRequests(configurator); - } - - Consumer builderConfigurator = httpBuilderConfigurator; - - if (builderConfigurator != null) { - ((HttpConfigurable) sourceManager).configureBuilder(builderConfigurator); - } - } - } - - @Override - public T source(Class klass) { - for (AudioSourceManager sourceManager : sourceManagers) { - if (klass.isAssignableFrom(sourceManager.getClass())) { - return (T) sourceManager; - } - } - - return null; - } - - @Override - public Future loadItem(final String identifier, final AudioLoadResultHandler resultHandler) { - try { - return trackInfoExecutorService.submit(createItemLoader(identifier, resultHandler)); - } catch (RejectedExecutionException e) { - return handleLoadRejected(identifier, resultHandler, e); - } - } - - @Override - public Future loadItemOrdered(Object orderingKey, final String identifier, final AudioLoadResultHandler resultHandler) { - try { - return orderedInfoExecutor.submit(orderingKey, createItemLoader(identifier, resultHandler)); - } catch (RejectedExecutionException e) { - return handleLoadRejected(identifier, resultHandler, e); - } - } - - private Future handleLoadRejected(String identifier, AudioLoadResultHandler resultHandler, RejectedExecutionException e) { - FriendlyException exception = new FriendlyException("Cannot queue loading a track, queue is full.", SUSPICIOUS, e); - ExceptionTools.log(log, exception, "queueing item " + identifier); - - resultHandler.loadFailed(exception); - - return ExecutorTools.COMPLETED_VOID; - } - - private Callable createItemLoader(final String identifier, final AudioLoadResultHandler resultHandler) { - return () -> { - boolean[] reported = new boolean[1]; - - try { - if (!checkSourcesForItem(new AudioReference(identifier, null), resultHandler, reported)) { - log.debug("No matches for track with identifier {}.", identifier); - resultHandler.noMatches(); - } - } catch (Throwable throwable) { - if (reported[0]) { - log.warn("Load result handler for {} threw an exception", identifier, throwable); - } else { - dispatchItemLoadFailure(identifier, resultHandler, throwable); - } - - ExceptionTools.rethrowErrors(throwable); - } - - return null; - }; - } - - private void dispatchItemLoadFailure(String identifier, AudioLoadResultHandler resultHandler, Throwable throwable) { - FriendlyException exception = ExceptionTools.wrapUnfriendlyExceptions("Something went wrong when looking up the track", FAULT, throwable); - ExceptionTools.log(log, exception, "loading item " + identifier); - - resultHandler.loadFailed(exception); - } - - @Override - public void encodeTrack(MessageOutput stream, AudioTrack track) throws IOException { - DataOutput output = stream.startMessage(); - output.write(TRACK_INFO_VERSION); - - AudioTrackInfo trackInfo = track.getInfo(); - output.writeUTF(trackInfo.title); - output.writeUTF(trackInfo.author); - output.writeLong(trackInfo.length); - output.writeUTF(trackInfo.identifier); - output.writeBoolean(trackInfo.isStream); - DataFormatTools.writeNullableText(output, trackInfo.uri); - - encodeTrackDetails(track, output); - output.writeLong(track.getPosition()); - - stream.commitMessage(TRACK_INFO_VERSIONED); - } - - @Override - public DecodedTrackHolder decodeTrack(MessageInput stream) throws IOException { - DataInput input = stream.nextMessage(); - if (input == null) { - return null; - } - - int version = (stream.getMessageFlags() & TRACK_INFO_VERSIONED) != 0 ? (input.readByte() & 0xFF) : 1; - - AudioTrackInfo trackInfo = new AudioTrackInfo(input.readUTF(), input.readUTF(), input.readLong(), input.readUTF(), - input.readBoolean(), version >= 2 ? DataFormatTools.readNullableText(input) : null); - AudioTrack track = decodeTrackDetails(trackInfo, input); - long position = input.readLong(); - - if (track != null) { - track.setPosition(position); - } - - stream.skipRemainingBytes(); - - return new DecodedTrackHolder(track); - } - - /** - * Encodes an audio track to a byte array. Does not include AudioTrackInfo in the buffer. - * - * @param track The track to encode - * @return The bytes of the encoded data - */ - public byte[] encodeTrackDetails(AudioTrack track) { - try { - ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); - DataOutput output = new DataOutputStream(byteOutput); - - encodeTrackDetails(track, output); - - return byteOutput.toByteArray(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void encodeTrackDetails(AudioTrack track, DataOutput output) throws IOException { - AudioSourceManager sourceManager = track.getSourceManager(); - output.writeUTF(sourceManager.getSourceName()); - sourceManager.encodeTrack(track, output); - } - - /** - * Decodes an audio track from a byte array. - * - * @param trackInfo Track info for the track to decode - * @param buffer Byte array containing the encoded track - * @return Decoded audio track - */ - public AudioTrack decodeTrackDetails(AudioTrackInfo trackInfo, byte[] buffer) { - try { - DataInput input = new DataInputStream(new ByteArrayInputStream(buffer)); - return decodeTrackDetails(trackInfo, input); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private AudioTrack decodeTrackDetails(AudioTrackInfo trackInfo, DataInput input) throws IOException { - String sourceName = input.readUTF(); - - for (AudioSourceManager sourceManager : sourceManagers) { - if (sourceName.equals(sourceManager.getSourceName())) { - return sourceManager.decodeTrack(trackInfo, input); - } - } - - return null; - } - - /** - * Executes an audio track with the given player and volume. - * - * @param listener A listener for track state events - * @param track The audio track to execute - * @param configuration The audio configuration to use for executing - * @param playerOptions Options of the audio player - */ - public void executeTrack(TrackStateListener listener, InternalAudioTrack track, AudioConfiguration configuration, - AudioPlayerOptions playerOptions) { - - final AudioTrackExecutor executor = createExecutorForTrack(track, configuration, playerOptions); - track.assignExecutor(executor, true); - - trackPlaybackExecutorService.execute(() -> executor.execute(listener)); - } - - private AudioTrackExecutor createExecutorForTrack(InternalAudioTrack track, AudioConfiguration configuration, - AudioPlayerOptions playerOptions) { - - AudioSourceManager sourceManager = track.getSourceManager(); - - if (remoteNodeManager.isEnabled() && sourceManager != null && sourceManager.isTrackEncodable(track)) { - return new RemoteAudioTrackExecutor(track, configuration, remoteNodeManager, playerOptions.volumeLevel); - } else { - AudioTrackExecutor customExecutor = track.createLocalExecutor(this); - - if (customExecutor != null) { - return customExecutor; - } else { - int bufferDuration = Optional.ofNullable(playerOptions.frameBufferDuration.get()).orElse(frameBufferDuration); - return new LocalAudioTrackExecutor(track, configuration, playerOptions, useSeekGhosting, bufferDuration); - } - } - } - - @Override - public AudioConfiguration getConfiguration() { - return configuration; - } - - @Override - public boolean isUsingSeekGhosting() { - return useSeekGhosting; - } - - @Override - public void setUseSeekGhosting(boolean useSeekGhosting) { - this.useSeekGhosting = useSeekGhosting; - } - - @Override - public int getFrameBufferDuration() { - return frameBufferDuration; - } - - @Override - public void setFrameBufferDuration(int frameBufferDuration) { - this.frameBufferDuration = Math.max(200, frameBufferDuration); - } - - @Override - public void setTrackStuckThreshold(long trackStuckThreshold) { - this.trackStuckThreshold = TimeUnit.MILLISECONDS.toNanos(trackStuckThreshold); - } - - public long getTrackStuckThresholdNanos() { - return trackStuckThreshold; - } - - @Override - public void setPlayerCleanupThreshold(long cleanupThreshold) { - this.cleanupThreshold.set(cleanupThreshold); - } - - @Override - public void setItemLoaderThreadPoolSize(int poolSize) { - trackInfoExecutorService.setMaximumPoolSize(poolSize); - } - - private boolean checkSourcesForItem(AudioReference reference, AudioLoadResultHandler resultHandler, boolean[] reported) { - AudioReference currentReference = reference; - - for (int redirects = 0; redirects < MAXIMUM_LOAD_REDIRECTS && currentReference.identifier != null; redirects++) { - AudioItem item = checkSourcesForItemOnce(currentReference, resultHandler, reported); - if (item == null) { - return false; - } else if (!(item instanceof AudioReference)) { - return true; - } - currentReference = (AudioReference) item; - } - - return false; - } - - private AudioItem checkSourcesForItemOnce(AudioReference reference, AudioLoadResultHandler resultHandler, boolean[] reported) { - for (AudioSourceManager sourceManager : sourceManagers) { - if (reference.containerDescriptor != null && !(sourceManager instanceof ProbingAudioSourceManager)) { - continue; - } - - AudioItem item = sourceManager.loadItem(this, reference); - - if (item != null) { - if (item instanceof AudioTrack) { - log.debug("Loaded a track with identifier {} using {}.", reference.identifier, sourceManager.getClass().getSimpleName()); - reported[0] = true; - resultHandler.trackLoaded((AudioTrack) item); - } else if (item instanceof AudioPlaylist) { - log.debug("Loaded a playlist with identifier {} using {}.", reference.identifier, sourceManager.getClass().getSimpleName()); - reported[0] = true; - resultHandler.playlistLoaded((AudioPlaylist) item); - } - return item; - } - } - - return null; - } - - public ExecutorService getExecutor() { - return trackPlaybackExecutorService; - } - - @Override - public AudioPlayer createPlayer() { - AudioPlayer player = constructPlayer(); - player.addListener(lifecycleManager); - - if (remoteNodeManager.isEnabled()) { - player.addListener(remoteNodeManager); - } - - return player; - } - - protected AudioPlayer constructPlayer() { - return new DefaultAudioPlayer(this); - } - - @Override - public RemoteNodeRegistry getRemoteNodeRegistry() { - return remoteNodeManager; - } - - @Override - public void setHttpRequestConfigurator(Function configurator) { - this.httpConfigurator = configurator; - - if (configurator != null) { - for (AudioSourceManager sourceManager : sourceManagers) { - if (sourceManager instanceof HttpConfigurable) { - ((HttpConfigurable) sourceManager).configureRequests(configurator); - } - } - } - } - - @Override - public void setHttpBuilderConfigurator(Consumer configurator) { - this.httpBuilderConfigurator = configurator; - - if (configurator != null) { - for (AudioSourceManager sourceManager : sourceManagers) { - if (sourceManager instanceof HttpConfigurable) { - ((HttpConfigurable) sourceManager).configureBuilder(configurator); - } - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/FunctionalResultHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/FunctionalResultHandler.java deleted file mode 100644 index 8f2c161..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/FunctionalResultHandler.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player; - -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; - -import java.util.function.Consumer; - -/** - * Helper class for creating an audio result handler using only methods that can be passed as lambdas. - */ -public class FunctionalResultHandler implements AudioLoadResultHandler { - private final Consumer trackConsumer; - private final Consumer playlistConsumer; - private final Runnable emptyResultHandler; - private final Consumer exceptionConsumer; - - /** - * Refer to {@link AudioLoadResultHandler} methods for details on when each method is called. - * - * @param trackConsumer Consumer for single track result - * @param playlistConsumer Consumer for playlist result - * @param emptyResultHandler Empty result handler - * @param exceptionConsumer Consumer for an exception when loading the item fails - */ - public FunctionalResultHandler(Consumer trackConsumer, Consumer playlistConsumer, - Runnable emptyResultHandler, Consumer exceptionConsumer) { - - this.trackConsumer = trackConsumer; - this.playlistConsumer = playlistConsumer; - this.emptyResultHandler = emptyResultHandler; - this.exceptionConsumer = exceptionConsumer; - } - - @Override - public void trackLoaded(AudioTrack track) { - if (trackConsumer != null) { - trackConsumer.accept(track); - } - } - - @Override - public void playlistLoaded(AudioPlaylist playlist) { - if (playlistConsumer != null) { - playlistConsumer.accept(playlist); - } - } - - @Override - public void noMatches() { - if (emptyResultHandler != null) { - emptyResultHandler.run(); - } - } - - @Override - public void loadFailed(FriendlyException exception) { - if (exceptionConsumer != null) { - exceptionConsumer.accept(exception); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEvent.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEvent.java deleted file mode 100644 index a923632..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEvent.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.event; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; - -/** - * An event related to an audio player. - */ -public abstract class AudioEvent { - /** - * The related audio player. - */ - public final AudioPlayer player; - - /** - * @param player The related audio player. - */ - public AudioEvent(AudioPlayer player) { - this.player = player; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEventAdapter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEventAdapter.java deleted file mode 100644 index 1929aa0..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEventAdapter.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.event; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; - -/** - * Adapter for different event handlers as method overrides - */ -public abstract class AudioEventAdapter implements AudioEventListener { - /** - * @param player Audio player - */ - public void onPlayerPause(AudioPlayer player) { - // Adapter dummy method - } - - /** - * @param player Audio player - */ - public void onPlayerResume(AudioPlayer player) { - // Adapter dummy method - } - - /** - * @param player Audio player - * @param track Audio track that started - */ - public void onTrackStart(AudioPlayer player, AudioTrack track) { - // Adapter dummy method - } - - /** - * @param player Audio player - * @param track Audio track that ended - * @param endReason The reason why the track stopped playing - */ - public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { - // Adapter dummy method - } - - /** - * @param player Audio player - * @param track Audio track where the exception occurred - * @param exception The exception that occurred - */ - public void onTrackException(AudioPlayer player, AudioTrack track, FriendlyException exception) { - // Adapter dummy method - } - - /** - * @param player Audio player - * @param track Audio track where the exception occurred - * @param thresholdMs The wait threshold that was exceeded for this event to trigger - */ - public void onTrackStuck(AudioPlayer player, AudioTrack track, long thresholdMs) { - // Adapter dummy method - } - - @Override - public void onEvent(AudioEvent event) { - if (event instanceof PlayerPauseEvent) { - onPlayerPause(event.player); - } else if (event instanceof PlayerResumeEvent) { - onPlayerResume(event.player); - } else if (event instanceof TrackStartEvent) { - onTrackStart(event.player, ((TrackStartEvent) event).track); - } else if (event instanceof TrackEndEvent) { - onTrackEnd(event.player, ((TrackEndEvent) event).track, ((TrackEndEvent) event).endReason); - } else if (event instanceof TrackExceptionEvent) { - onTrackException(event.player, ((TrackExceptionEvent) event).track, ((TrackExceptionEvent) event).exception); - } else if (event instanceof TrackStuckEvent) { - onTrackStuck(event.player, ((TrackStuckEvent) event).track, ((TrackStuckEvent) event).thresholdMs); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEventListener.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEventListener.java deleted file mode 100644 index 4b0776b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/AudioEventListener.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.event; - -/** - * Listener of audio events. - */ -public interface AudioEventListener { - /** - * @param event The event - */ - void onEvent(AudioEvent event); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/PlayerPauseEvent.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/PlayerPauseEvent.java deleted file mode 100644 index 9304ee4..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/PlayerPauseEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.event; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; - -/** - * Event that is fired when a player is paused. - */ -public class PlayerPauseEvent extends AudioEvent { - /** - * @param player Audio player - */ - public PlayerPauseEvent(AudioPlayer player) { - super(player); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/PlayerResumeEvent.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/PlayerResumeEvent.java deleted file mode 100644 index 15670bb..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/PlayerResumeEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.event; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; - -/** - * Event that is fired when a player is resumed. - */ -public class PlayerResumeEvent extends AudioEvent { - /** - * @param player Audio player - */ - public PlayerResumeEvent(AudioPlayer player) { - super(player); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackEndEvent.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackEndEvent.java deleted file mode 100644 index 7e1192d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackEndEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.event; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; - -/** - * Event that is fired when an audio track ends in an audio player, either by interruption, exception or reaching the end. - */ -public class TrackEndEvent extends AudioEvent { - /** - * Audio track that ended - */ - public final AudioTrack track; - /** - * The reason why the track stopped playing - */ - public final AudioTrackEndReason endReason; - - /** - * @param player Audio player - * @param track Audio track that ended - * @param endReason The reason why the track stopped playing - */ - public TrackEndEvent(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { - super(player); - this.track = track; - this.endReason = endReason; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackExceptionEvent.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackExceptionEvent.java deleted file mode 100644 index dd3039f..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackExceptionEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.event; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; - -/** - * Event that is fired when an exception occurs in an audio track that causes it to halt or not start. - */ -public class TrackExceptionEvent extends AudioEvent { - /** - * Audio track where the exception occurred - */ - public final AudioTrack track; - /** - * The exception that occurred - */ - public final FriendlyException exception; - - /** - * @param player Audio player - * @param track Audio track where the exception occurred - * @param exception The exception that occurred - */ - public TrackExceptionEvent(AudioPlayer player, AudioTrack track, FriendlyException exception) { - super(player); - this.track = track; - this.exception = exception; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackStartEvent.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackStartEvent.java deleted file mode 100644 index 8ac79d9..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackStartEvent.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.event; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; - -/** - * Event that is fired when a track starts playing. - */ -public class TrackStartEvent extends AudioEvent { - /** - * Audio track that started - */ - public final AudioTrack track; - - /** - * @param player Audio player - * @param track Audio track that started - */ - public TrackStartEvent(AudioPlayer player, AudioTrack track) { - super(player); - this.track = track; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackStuckEvent.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackStuckEvent.java deleted file mode 100644 index e6eda4b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/event/TrackStuckEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.event; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; - -/** - * Event that is fired when a track was started, but no audio frames from it have arrived in a long time, specified - * by the threshold set via AudioPlayerManager.setTrackStuckThreshold(). - */ -public class TrackStuckEvent extends AudioEvent { - /** - * Audio track where the exception occurred - */ - public final AudioTrack track; - /** - * The wait threshold that was exceeded for this event to trigger - */ - public final long thresholdMs; - - /** - * @param player Audio player - * @param track Audio track where the exception occurred - * @param thresholdMs The wait threshold that was exceeded for this event to trigger - */ - public TrackStuckEvent(AudioPlayer player, AudioTrack track, long thresholdMs) { - super(player); - this.track = track; - this.thresholdMs = thresholdMs; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/hook/AudioOutputHook.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/hook/AudioOutputHook.java deleted file mode 100644 index f47fc22..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/hook/AudioOutputHook.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.hook; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; - -/** - * Hook for intercepting outgoing audio frames from AudioPlayer. - */ -public interface AudioOutputHook { - /** - * @param player Audio player where the frame is coming from - * @param frame Audio frame - * @return The frame to pass onto the actual caller - */ - AudioFrame outgoingFrame(AudioPlayer player, AudioFrame frame); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/player/hook/AudioOutputHookFactory.java b/src/main/java/com/sedmelluq/discord/lavaplayer/player/hook/AudioOutputHookFactory.java deleted file mode 100644 index 7ebda8d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/player/hook/AudioOutputHookFactory.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.player.hook; - -/** - * Factory for audio output hook instances. - */ -public interface AudioOutputHookFactory { - /** - * @return New instance of an audio output hook - */ - AudioOutputHook createOutputHook(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/AbandonedTrackManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/AbandonedTrackManager.java deleted file mode 100644 index d565de0..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/AbandonedTrackManager.java +++ /dev/null @@ -1,198 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote; - -import com.sedmelluq.discord.lavaplayer.remote.message.NodeStatisticsMessage; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackState; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.COMMON; - -/** - * Takes over tracks of offline remote nodes. - */ -public class AbandonedTrackManager { - private static final Logger log = LoggerFactory.getLogger(AbandonedTrackManager.class); - - private static final long EXPIRE_THRESHOLD = TimeUnit.SECONDS.toMillis(10); - private static final long CRITICAL_PENALTY = 750; - - private final BlockingQueue abandonedExecutors; - - /** - * Create an instance. - */ - public AbandonedTrackManager() { - this.abandonedExecutors = new ArrayBlockingQueue<>(2000); - } - - /** - * Adds a track executor to abandoned tracks. The abandoned track manager will take over managing its lifecycle and - * the caller should not use it any further. - * - * @param executor The executor to register as an abandoned track. - */ - public void add(RemoteAudioTrackExecutor executor) { - if (abandonedExecutors.offer(new AbandonedExecutor(System.currentTimeMillis(), executor))) { - log.debug("{} has been put up for adoption.", executor); - } else { - log.debug("{} has been discarded, adoption queue is full.", executor); - - executor.dispatchException(new FriendlyException("Cannot find a node to play the track on.", COMMON, null)); - executor.stop(); - } - } - - /** - * Distributes any abandoned tracks between the specified nodes. Only online nodes which are not under too heavy load - * are used. The number of tracks that can be assigned to a node depends on the number of tracks it is already - * processing (track count can increase only by 1/15th on each call, or by 5). - * - * @param nodes Remote nodes to give abandoned tracks to. - */ - public void distribute(List nodes) { - if (abandonedExecutors.isEmpty()) { - return; - } - - List adopters = findAdopters(nodes); - AbandonedExecutor executor; - long currentTime = System.currentTimeMillis(); - int maximum = getMaximumAdoptions(adopters); - int assigned = 0; - - while (assigned < maximum && (executor = abandonedExecutors.poll()) != null) { - if (checkValidity(executor, currentTime)) { - Adopter adopter = selectNextAdopter(adopters); - - if (adopter != null) { - log.debug("Node {} is adopting {}.", adopter.node.getAddress(), executor.executor); - - adopter.node.startPlaying(executor.executor); - assigned++; - } else { - log.debug("No node available for adopting {}", executor.executor); - } - } - } - } - - /** - * Shut down the abandoned track manager, stopping any tracks. - */ - public void shutdown() { - AbandonedExecutor executor; - - while ((executor = abandonedExecutors.poll()) != null) { - executor.executor.dispatchException(new FriendlyException("Node system was shut down.", COMMON, null)); - executor.executor.stop(); - } - } - - /** - * Remove expired or stopped tracks from the abandoned track queue. - */ - public void drainExpired() { - AbandonedExecutor executor; - long currentTime = System.currentTimeMillis(); - - while ((executor = abandonedExecutors.peek()) != null) { - if (!checkValidity(executor, currentTime) && abandonedExecutors.remove(executor)) { - log.debug("Abandoned executor {} removed from queue.", executor.executor); - } - } - } - - private boolean checkValidity(AbandonedExecutor executor, long currentTime) { - long expirationTime = currentTime - EXPIRE_THRESHOLD; - - if (executor.executor.getState() == AudioTrackState.FINISHED) { - log.debug("{} has been cleared from adoption queue because it was stopped.", executor.executor); - return false; - } else if (executor.orphanedTime < expirationTime) { - log.debug("{} has been cleared from adoption queue because it expired.", executor.executor); - - executor.executor.dispatchException(new FriendlyException("Could not find next node to play on.", COMMON, null)); - executor.executor.stop(); - return false; - } else { - return true; - } - } - - private List findAdopters(List nodes) { - List adopters = new ArrayList<>(); - - for (RemoteNodeProcessor node : nodes) { - int penalty = node.getBalancerPenalty(); - NodeStatisticsMessage statistics = node.getLastStatistics(); - - if (penalty >= CRITICAL_PENALTY || statistics == null) { - continue; - } - - int maximumAdoptions = Math.max(5, statistics.playingTrackCount / 15); - adopters.add(new Adopter(node, maximumAdoptions)); - } - - return adopters; - } - - private Adopter selectNextAdopter(List adopters) { - Adopter selected = null; - - for (Adopter adopter : adopters) { - if (adopter.adoptions < adopter.maximumAdoptions && (selected == null || adopter.fillRate() > selected.fillRate())) { - selected = adopter; - } - } - - if (selected != null) { - selected.adoptions++; - } - - return selected; - } - - private int getMaximumAdoptions(List adopters) { - int total = 0; - - for (Adopter adopter : adopters) { - total += adopter.maximumAdoptions; - } - - return total; - } - - private static class AbandonedExecutor { - private final long orphanedTime; - private final RemoteAudioTrackExecutor executor; - - private AbandonedExecutor(long orphanedTime, RemoteAudioTrackExecutor executor) { - this.orphanedTime = orphanedTime; - this.executor = executor; - } - } - - private static class Adopter { - private final RemoteNodeProcessor node; - private final long maximumAdoptions; - private int adoptions; - - private Adopter(RemoteNodeProcessor node, long maximumAdoptions) { - this.node = node; - this.maximumAdoptions = maximumAdoptions; - this.adoptions = 0; - } - - private float fillRate() { - return (float) adoptions / maximumAdoptions; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteAudioTrackExecutor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteAudioTrackExecutor.java deleted file mode 100644 index 1736864..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteAudioTrackExecutor.java +++ /dev/null @@ -1,277 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote; - -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.*; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameBuffer; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioTrackExecutor; -import com.sedmelluq.discord.lavaplayer.track.playback.MutableAudioFrame; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -import static com.sedmelluq.discord.lavaplayer.track.TrackMarkerHandler.MarkerState.ENDED; -import static com.sedmelluq.discord.lavaplayer.track.TrackMarkerHandler.MarkerState.STOPPED; - -/** - * This executor delegates the actual audio processing to a remote node. - */ -public class RemoteAudioTrackExecutor implements AudioTrackExecutor { - private static final Logger log = LoggerFactory.getLogger(RemoteAudioTrackExecutor.class); - - private static final long NO_SEEK = -1; - private static final int BUFFER_DURATION_MS = 3000; - - private final AudioTrack track; - private final AudioConfiguration configuration; - private final RemoteNodeManager remoteNodeManager; - private final AtomicInteger volumeLevel; - private final long executorId; - private final AudioFrameBuffer frameBuffer; - private final AtomicLong lastFrameTimecode = new AtomicLong(); - private final AtomicLong pendingSeek = new AtomicLong(NO_SEEK); - private final TrackMarkerTracker markerTracker = new TrackMarkerTracker(); - private volatile TrackStateListener activeListener; - private volatile boolean hasReceivedData; - private volatile boolean hasStarted; - private volatile Throwable trackException; - - /** - * @param track Audio track to play - * @param configuration Configuration for audio processing - * @param remoteNodeManager Manager of remote nodes - * @param volumeLevel Mutable volume level - */ - public RemoteAudioTrackExecutor(AudioTrack track, AudioConfiguration configuration, - RemoteNodeManager remoteNodeManager, AtomicInteger volumeLevel) { - - this.track = track; - this.configuration = configuration.copy(); - this.remoteNodeManager = remoteNodeManager; - this.volumeLevel = volumeLevel; - this.executorId = System.nanoTime(); - this.frameBuffer = configuration.getFrameBufferFactory().create(BUFFER_DURATION_MS, configuration.getOutputFormat(), null); - } - - /** - * @return The unique ID for this executor - */ - public long getExecutorId() { - return executorId; - } - - /** - * @return The configuration to use for processing audio - */ - public AudioConfiguration getConfiguration() { - return configuration; - } - - /** - * @return The current volume of the track - */ - public int getVolume() { - return volumeLevel.get(); - } - - /** - * @return The track that this executor is playing - */ - public AudioTrack getTrack() { - return track; - } - - /** - * @return The position of a seek that has not completed. Value is -1 in case no seeking is in progress. - */ - public long getPendingSeek() { - return pendingSeek.get(); - } - - /** - * Clear the current seeking if its position matches the specified position - * - * @param position The position to compare with - */ - public void clearSeek(long position) { - if (position != NO_SEEK) { - frameBuffer.setClearOnInsert(); - - if (pendingSeek.compareAndSet(position, NO_SEEK)) { - markerTracker.checkSeekTimecode(position); - } - } - } - - /** - * Send the specified exception as an event to the active state listener. - * - * @param exception Exception to send - */ - public void dispatchException(FriendlyException exception) { - TrackStateListener currentListener = activeListener; - - ExceptionTools.log(log, exception, track.getIdentifier()); - - if (currentListener != null) { - trackException = exception; - currentListener.onTrackException(track, exception); - } - } - - /** - * Mark that this track has received data from the node. - */ - public void receivedData() { - hasReceivedData = true; - } - - /** - * Detach the currently active listener, so no useless reference would be kept and no events would be sent there. - */ - public void detach() { - activeListener = null; - - markerTracker.trigger(ENDED); - } - - @Override - public AudioFrameBuffer getAudioBuffer() { - return frameBuffer; - } - - @Override - public void execute(TrackStateListener listener) { - try { - hasStarted = true; - activeListener = listener; - remoteNodeManager.startPlaying(this); - } catch (Throwable throwable) { - listener.onTrackException(track, ExceptionTools.wrapUnfriendlyExceptions( - "An error occurred when trying to start track remotely.", FriendlyException.Severity.FAULT, throwable)); - - ExceptionTools.rethrowErrors(throwable); - } - } - - @Override - public void stop() { - frameBuffer.lockBuffer(); - frameBuffer.setTerminateOnEmpty(); - frameBuffer.clear(); - - markerTracker.trigger(STOPPED); - - remoteNodeManager.onTrackEnd(null, track, AudioTrackEndReason.STOPPED); - } - - @Override - public long getPosition() { - return lastFrameTimecode.get(); - } - - @Override - public void setPosition(long timecode) { - pendingSeek.set(timecode); - } - - @Override - public AudioTrackState getState() { - if (hasStarted && activeListener == null) { - return AudioTrackState.FINISHED; - } else if (!hasReceivedData) { - return AudioTrackState.LOADING; - } else { - return AudioTrackState.PLAYING; - } - } - - @Override - public void setMarker(TrackMarker marker) { - markerTracker.set(marker, getPosition()); - } - - @Override - public AudioFrame provide() { - AudioFrame frame = frameBuffer.provide(); - processProvidedFrame(frame); - return frame; - } - - @Override - public AudioFrame provide(long timeout, TimeUnit unit) throws TimeoutException, InterruptedException { - AudioFrame frame = frameBuffer.provide(timeout, unit); - processProvidedFrame(frame); - return frame; - } - - @Override - public boolean provide(MutableAudioFrame targetFrame) { - if (frameBuffer.provide(targetFrame)) { - processProvidedFrame(targetFrame); - return true; - } - - return true; - } - - @Override - public boolean provide(MutableAudioFrame targetFrame, long timeout, TimeUnit unit) - throws TimeoutException, InterruptedException { - - if (frameBuffer.provide(targetFrame, timeout, unit)) { - processProvidedFrame(targetFrame); - return true; - } - - return true; - } - - private void processProvidedFrame(AudioFrame frame) { - if (frame != null && !frame.isTerminator()) { - lastFrameTimecode.set(frame.getTimecode()); - - if (pendingSeek.get() == NO_SEEK && !frameBuffer.hasClearOnInsert()) { - markerTracker.checkPlaybackTimecode(frame.getTimecode()); - } - } - } - - @Override - public boolean failedBeforeLoad() { - return trackException != null && !hasReceivedData; - } - - /** - * @return The expected timecode of the next frame to receive from the remote node. - */ - public long getNextInputTimecode() { - boolean dataReceived = hasReceivedData; - long frameDuration = configuration.getOutputFormat().frameDuration(); - - if (dataReceived) { - Long lastBufferTimecode = frameBuffer.getLastInputTimecode(); - if (lastBufferTimecode != null) { - return lastBufferTimecode + frameDuration; - } - } - - long seekPosition = pendingSeek.get(); - if (seekPosition != NO_SEEK) { - return seekPosition; - } - - return dataReceived ? lastFrameTimecode.get() + frameDuration : lastFrameTimecode.get(); - } - - @Override - public String toString() { - return "RemoteExec " + executorId + ", " + track.getIdentifier(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNode.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNode.java deleted file mode 100644 index 52b79aa..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNode.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote; - -import com.sedmelluq.discord.lavaplayer.remote.message.NodeStatisticsMessage; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; - -import java.util.List; -import java.util.Map; - -/** - * A remote node interface which provides information about a specific node. - */ -public interface RemoteNode { - /** - * @return The address of this remote node. - */ - String getAddress(); - - /** - * @return Gets the current state of connection between the node processor and the node. - */ - ConnectionState getConnectionState(); - - /** - * @return The last statistics received from this node. May be null. - */ - NodeStatisticsMessage getLastStatistics(); - - /** - * @return The minimum amount of time in milliseconds between the start time of two ticks. - */ - int getTickMinimumInterval(); - - /** - * To record all ticks, it is possible to calculate the minimum amount of time which guarantees that none are - * discarded in the internal history (minimumInterval * tickHistoryCapacity). - * - * @return The number of ticks that are kept in history. - */ - int getTickHistoryCapacity(); - - /** - * @param reset Whether to reset the history so next calls will only contain new ones. - * @return All the ticks in the history, up to the history capacity. In case of an overflow, newer ones will replace - * older ones. - */ - List getLastTicks(boolean reset); - - /** - * @return The number of tracks being played by this player manager through this node. - */ - int getPlayingTrackCount(); - - /** - * @return List of tracks being played by this node for the current player manager. - */ - List getPlayingTracks(); - - /** - * @return Map containing the balancer penalty factors, with "Total" being the sum of all others. - */ - Map getBalancerPenaltyDetails(); - - /** - * Checks if a audio track is being played by this node. - * - * @param track The audio track. - * @return True if this node is playing that track. - */ - boolean isPlayingTrack(AudioTrack track); - - /** - * Information about one request made to the node. - */ - class Tick { - /** - * The time when the node processor started building the request to send to the node. - */ - public final long startTime; - /** - * The time when the processing the response data from the node was finished. - */ - public final long endTime; - /** - * Response code from the node. -1 in case of connection failure. - */ - public final int responseCode; - /** - * The size of the request in bytes. - */ - public final int requestSize; - /** - * The size of the uncompressed response in bytes. - */ - public final int responseSize; - - /** - * @param startTime The time when the node processor started building the request to send to the node. - * @param endTime The time when the processing the response data from the node was finished. - * @param responseCode Response code from the node. -1 in case of connection failure. - * @param requestSize The size of the request in bytes. - * @param responseSize The size of the uncompressed response in bytes. - */ - public Tick(long startTime, long endTime, int responseCode, int requestSize, int responseSize) { - this.startTime = startTime; - this.endTime = endTime; - this.responseCode = responseCode; - this.requestSize = requestSize; - this.responseSize = responseSize; - } - } - - /** - * State of the connection to this node. - */ - enum ConnectionState { - /** - * The node processor is current in the middle of attempting a connection to this node. Happens on every - * reconnection attempt, even if the node has already been offline for a period of time. - */ - PENDING, - /** - * The node is currently online, new tracks can be sent to this node. - */ - ONLINE, - /** - * The node is offline, this is the state the node has before attempting the first request and after any failed - * request to a node until a new request is successful. - */ - OFFLINE, - /** - * This node has been removed from the list of nodes to use. In case a node with the same address is added, this - * instance will not be reactivated, but a new one should be retrieved. - */ - REMOVED; - - /** - * @return Shortcut for ordinal. - */ - public int id() { - return ordinal(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeManager.java deleted file mode 100644 index 40829f4..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeManager.java +++ /dev/null @@ -1,192 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; -import com.sedmelluq.discord.lavaplayer.track.InternalAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioTrackExecutor; -import com.sedmelluq.lava.common.tools.DaemonThreadFactory; -import com.sedmelluq.lava.common.tools.ExecutorTools; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Manager of remote nodes for audio processing. - */ -public class RemoteNodeManager extends AudioEventAdapter implements RemoteNodeRegistry, Runnable { - private final DefaultAudioPlayerManager playerManager; - private final HttpInterfaceManager httpInterfaceManager; - private final List processors; - private final AbandonedTrackManager abandonedTrackManager; - private final AtomicBoolean enabled; - private final Object lock; - private volatile ScheduledThreadPoolExecutor scheduler; - private volatile List activeProcessors; - - /** - * @param playerManager Audio player manager - */ - public RemoteNodeManager(DefaultAudioPlayerManager playerManager) { - this.playerManager = playerManager; - this.httpInterfaceManager = RemoteNodeProcessor.createHttpInterfaceManager(); - this.processors = new ArrayList<>(); - this.abandonedTrackManager = new AbandonedTrackManager(); - this.enabled = new AtomicBoolean(); - this.lock = new Object(); - this.activeProcessors = new ArrayList<>(); - } - - /** - * Enable and initialise the remote nodes. - * - * @param nodeAddresses Addresses of remote nodes - */ - public void initialise(List nodeAddresses) { - synchronized (lock) { - if (enabled.compareAndSet(false, true)) { - startScheduler(nodeAddresses.size() + 1); - } else { - scheduler.setCorePoolSize(nodeAddresses.size() + 1); - } - - List newNodeAddresses = new ArrayList<>(nodeAddresses); - - for (Iterator iterator = processors.iterator(); iterator.hasNext(); ) { - RemoteNodeProcessor processor = iterator.next(); - - if (!newNodeAddresses.remove(processor.getAddress())) { - processor.shutdown(); - iterator.remove(); - } - } - - for (String nodeAddress : newNodeAddresses) { - RemoteNodeProcessor processor = new RemoteNodeProcessor(playerManager, nodeAddress, scheduler, - httpInterfaceManager, abandonedTrackManager); - - scheduler.submit(processor); - processors.add(processor); - } - - activeProcessors = new ArrayList<>(processors); - } - } - - /** - * Shut down, freeing all threads and stopping all tracks executed on remote nodes. - * - * @param terminal True if initialise will never be called again. - */ - public void shutdown(boolean terminal) { - synchronized (lock) { - if (!enabled.compareAndSet(true, false)) { - return; - } - - ExecutorTools.shutdownExecutor(scheduler, "node manager"); - - for (RemoteNodeProcessor processor : processors) { - processor.processHealthCheck(true); - } - - abandonedTrackManager.shutdown(); - - processors.clear(); - activeProcessors = new ArrayList<>(processors); - } - - if (terminal) { - ExceptionTools.closeWithWarnings(httpInterfaceManager); - } - } - - @Override - public boolean isEnabled() { - return enabled.get(); - } - - /** - * Start playing an audio track remotely. - * - * @param remoteExecutor The executor of the track - */ - public void startPlaying(RemoteAudioTrackExecutor remoteExecutor) { - RemoteNodeProcessor processor = getNodeForNextTrack(); - - processor.startPlaying(remoteExecutor); - } - - private void startScheduler(int initialSize) { - ScheduledThreadPoolExecutor scheduledExecutor = new ScheduledThreadPoolExecutor(initialSize, new DaemonThreadFactory("remote")); - scheduledExecutor.scheduleAtFixedRate(this, 2000, 2000, TimeUnit.MILLISECONDS); - scheduler = scheduledExecutor; - } - - private RemoteNodeProcessor getNodeForNextTrack() { - int lowestPenalty = Integer.MAX_VALUE; - RemoteNodeProcessor node = null; - - for (RemoteNodeProcessor processor : processors) { - int penalty = processor.getBalancerPenalty(); - - if (penalty < lowestPenalty) { - lowestPenalty = penalty; - node = processor; - } - } - - if (node == null) { - throw new FriendlyException("No available machines for playing track.", SUSPICIOUS, null); - } - - return node; - } - - @Override - public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { - AudioTrackExecutor executor = ((InternalAudioTrack) track).getActiveExecutor(); - - if (endReason != AudioTrackEndReason.FINISHED && executor instanceof RemoteAudioTrackExecutor) { - for (RemoteNodeProcessor processor : activeProcessors) { - processor.trackEnded((RemoteAudioTrackExecutor) executor, true); - } - } - } - - @Override - public void run() { - for (RemoteNodeProcessor processor : activeProcessors) { - processor.processHealthCheck(false); - } - - abandonedTrackManager.drainExpired(); - } - - @Override - public RemoteNode getNodeUsedForTrack(AudioTrack track) { - for (RemoteNodeProcessor processor : activeProcessors) { - if (processor.isPlayingTrack(track)) { - return processor; - } - } - - return null; - } - - @Override - public List getNodes() { - return new ArrayList<>(activeProcessors); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeProcessor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeProcessor.java deleted file mode 100644 index 8508138..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeProcessor.java +++ /dev/null @@ -1,575 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.remote.message.*; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.RingBufferMath; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.tools.io.SimpleHttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.InternalAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameBuffer; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioTrackExecutor; -import com.sedmelluq.discord.lavaplayer.track.playback.ImmutableAudioFrame; -import org.apache.commons.io.input.CountingInputStream; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ByteArrayEntity; -import org.apache.http.impl.client.HttpClientBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Processes one remote node. - */ -public class RemoteNodeProcessor implements RemoteNode, Runnable { - private static final Logger log = LoggerFactory.getLogger(RemoteNodeProcessor.class); - - private static final int CONNECT_TIMEOUT = 1000; - private static final int SOCKET_TIMEOUT = 2000; - private static final int TRACK_KILL_THRESHOLD = 10000; - private static final int TICK_MINIMUM_INTERVAL = 500; - private static final int NODE_REQUEST_HISTORY = 200; - - private final DefaultAudioPlayerManager playerManager; - private final String nodeAddress; - private final ScheduledThreadPoolExecutor scheduledExecutor; - private final HttpInterfaceManager httpInterfaceManager; - private final AbandonedTrackManager abandonedTrackManager; - private final BlockingQueue queuedMessages; - private final ConcurrentMap playingTracks; - private final RemoteMessageMapper mapper; - private final AtomicBoolean threadRunning; - private final AtomicInteger connectionState; - private final ArrayDeque tickHistory; - private volatile int aliveTickCounter; - private volatile int requestTimingPenalty; - private volatile long lastAliveTime; - private volatile NodeStatisticsMessage lastStatistics; - private volatile boolean closed; - - /** - * @param playerManager Audio player manager - * @param nodeAddress Address of this node - * @param scheduledExecutor Scheduler to use to schedule reconnects - * @param httpInterfaceManager HTTP interface manager to use for communicating with node - * @param abandonedTrackManager Abandoned track manager, where the playing tracks are sent if node goes offline - */ - public RemoteNodeProcessor(DefaultAudioPlayerManager playerManager, String nodeAddress, - ScheduledThreadPoolExecutor scheduledExecutor, HttpInterfaceManager httpInterfaceManager, - AbandonedTrackManager abandonedTrackManager) { - - this.playerManager = playerManager; - this.nodeAddress = nodeAddress; - this.scheduledExecutor = scheduledExecutor; - this.httpInterfaceManager = httpInterfaceManager; - this.abandonedTrackManager = abandonedTrackManager; - queuedMessages = new LinkedBlockingQueue<>(); - playingTracks = new ConcurrentHashMap<>(); - mapper = new RemoteMessageMapper(); - threadRunning = new AtomicBoolean(); - connectionState = new AtomicInteger(ConnectionState.OFFLINE.id()); - tickHistory = new ArrayDeque<>(NODE_REQUEST_HISTORY); - closed = false; - } - - /** - * Start playing a track through this remote node. - * - * @param executor The executor of the track - */ - public void startPlaying(RemoteAudioTrackExecutor executor) { - AudioTrack track = executor.getTrack(); - - if (playingTracks.putIfAbsent(executor.getExecutorId(), executor) == null) { - long position = executor.getNextInputTimecode(); - log.info("Sending request to play {} {} from position {}", track.getIdentifier(), executor.getExecutorId(), position); - - queuedMessages.add(new TrackStartRequestMessage(executor.getExecutorId(), track.getInfo(), playerManager.encodeTrackDetails(track), - executor.getVolume(), executor.getConfiguration(), position)); - } - } - - /** - * Clear the track from this node. - * - * @param executor Executor of the track - * @param notifyNode Whether it is necessary to notify the node - */ - public void trackEnded(RemoteAudioTrackExecutor executor, boolean notifyNode) { - if (playingTracks.remove(executor.getExecutorId()) != null) { - log.info("Track {} removed from node {} (context {})", executor.getTrack().getIdentifier(), nodeAddress, executor.getExecutorId()); - - if (notifyNode) { - log.info("Notifying node {} of track stop for {} (context {})", nodeAddress, executor.getTrack().getIdentifier(), executor.getExecutorId()); - - queuedMessages.add(new TrackStoppedMessage(executor.getExecutorId())); - } - - executor.detach(); - } - } - - /** - * Mark this processor as shut down. No further tasks for it will be scheduled. - */ - public void shutdown() { - processHealthCheck(true); - closed = true; - scheduledExecutor.remove(this); - } - - @Override - public void run() { - if (closed || !threadRunning.compareAndSet(false, true)) { - log.debug("Not running node processor for {}, thread already active.", nodeAddress); - return; - } - - log.debug("Trying to connect to node {}.", nodeAddress); - - connectionState.set(ConnectionState.PENDING.id()); - - try (HttpInterface httpInterface = httpInterfaceManager.getInterface()) { - RingBufferMath timingAverage = new RingBufferMath(10, in -> Math.pow(in, 5.0), out -> Math.pow(out, 0.2)); - - while (processOneTick(httpInterface, timingAverage)) { - aliveTickCounter = Math.max(1, aliveTickCounter + 1); - lastAliveTime = System.currentTimeMillis(); - } - } catch (InterruptedException e) { - log.info("Node {} processing was stopped.", nodeAddress); - Thread.currentThread().interrupt(); - } catch (IOException e) { - if (aliveTickCounter > 0) { - log.error("Node {} went offline with exception.", nodeAddress, e); - } else { - log.debug("Retry, node {} is still offline.", nodeAddress); - } - } catch (Throwable e) { - log.error("Node {} appears offline due to unexpected exception.", nodeAddress, e); - - ExceptionTools.rethrowErrors(e); - } finally { - processHealthCheck(true); - connectionState.set(ConnectionState.OFFLINE.id()); - - aliveTickCounter = Math.min(-1, aliveTickCounter - 1); - threadRunning.set(false); - - if (!closed) { - long delay = getScheduleDelay(); - - if (aliveTickCounter == -1) { - log.info("Node {} loop ended, retry scheduled in {}.", nodeAddress, delay); - } - - scheduledExecutor.schedule(this, delay, TimeUnit.MILLISECONDS); - } else { - log.info("Node {} loop ended, node was removed.", nodeAddress); - } - } - } - - private long getScheduleDelay() { - if (aliveTickCounter >= -5) { - return 1000; - } else if (aliveTickCounter >= -20) { - return 3000; - } else { - return 10000; - } - } - - private boolean processOneTick(HttpInterface httpInterface, RingBufferMath timingAverage) throws Exception { - TickBuilder tickBuilder = new TickBuilder(System.currentTimeMillis()); - - try { - if (!dispatchOneTick(httpInterface, tickBuilder)) { - return false; - } - } finally { - tickBuilder.endTime = System.currentTimeMillis(); - recordTick(tickBuilder.build(), timingAverage); - } - - long sleepDuration = Math.max((tickBuilder.startTime + 500) - tickBuilder.endTime, 10); - - Thread.sleep(sleepDuration); - return true; - } - - private boolean dispatchOneTick(HttpInterface httpInterface, TickBuilder tickBuilder) throws Exception { - boolean success = false; - HttpPost post = new HttpPost("http://" + nodeAddress + "/tick"); - - abandonedTrackManager.distribute(Collections.singletonList(this)); - - ByteArrayEntity entity = new ByteArrayEntity(buildRequestBody()); - post.setEntity(entity); - - tickBuilder.requestSize = (int) entity.getContentLength(); - - CloseableHttpResponse response = httpInterface.execute(post); - - try { - tickBuilder.responseCode = response.getStatusLine().getStatusCode(); - if (tickBuilder.responseCode != 200) { - throw new IOException("Returned an unexpected response code " + tickBuilder.responseCode); - } - - if (connectionState.compareAndSet(ConnectionState.PENDING.id(), ConnectionState.ONLINE.id())) { - log.info("Node {} came online.", nodeAddress); - } else if (connectionState.get() != ConnectionState.ONLINE.id()) { - log.warn("Node {} received successful response, but had already lost control of its tracks.", nodeAddress); - return false; - } - - lastAliveTime = System.currentTimeMillis(); - - if (!handleResponseBody(response.getEntity().getContent(), tickBuilder)) { - return false; - } - - success = true; - } finally { - if (!success) { - ExceptionTools.closeWithWarnings(response); - } else { - ExceptionTools.closeWithWarnings(response.getEntity().getContent()); - } - } - - return true; - } - - private byte[] buildRequestBody() throws IOException { - ByteArrayOutputStream outputBytes = new ByteArrayOutputStream(); - DataOutputStream output = new DataOutputStream(outputBytes); - - List messages = new ArrayList<>(); - int queuedCount = queuedMessages.drainTo(messages); - - if (queuedCount > 0) { - log.debug("Including {} queued messages in the request to {}.", queuedCount, nodeAddress); - } - - for (RemoteAudioTrackExecutor executor : playingTracks.values()) { - long pendingSeek = executor.getPendingSeek(); - - AudioFrameBuffer buffer = executor.getAudioBuffer(); - int neededFrames = pendingSeek == -1 ? buffer.getRemainingCapacity() : buffer.getFullCapacity(); - - messages.add(new TrackFrameRequestMessage(executor.getExecutorId(), neededFrames, executor.getVolume(), pendingSeek)); - } - - for (RemoteMessage message : messages) { - mapper.encode(output, message); - } - - mapper.endOutput(output); - return outputBytes.toByteArray(); - } - - private boolean handleResponseBody(InputStream inputStream, TickBuilder tickBuilder) { - CountingInputStream countingStream = new CountingInputStream(inputStream); - DataInputStream input = new DataInputStream(countingStream); - RemoteMessage message; - - try { - while ((message = mapper.decode(input)) != null) { - if (message instanceof TrackStartResponseMessage) { - handleTrackStartResponse((TrackStartResponseMessage) message); - } else if (message instanceof TrackFrameDataMessage) { - handleTrackFrameData((TrackFrameDataMessage) message); - } else if (message instanceof TrackExceptionMessage) { - handleTrackException((TrackExceptionMessage) message); - } else if (message instanceof NodeStatisticsMessage) { - handleNodeStatistics((NodeStatisticsMessage) message); - } - } - } catch (InterruptedException interruption) { - log.error("Node {} processing thread was interrupted.", nodeAddress); - Thread.currentThread().interrupt(); - return false; - } catch (Throwable e) { - log.error("Error when processing response from node {}.", nodeAddress, e); - ExceptionTools.rethrowErrors(e); - } finally { - tickBuilder.responseSize = countingStream.getCount(); - } - - return true; - } - - private void handleTrackStartResponse(TrackStartResponseMessage message) { - if (message.success) { - log.debug("Successful start confirmation from node {} for executor {}.", nodeAddress, message.executorId); - } else { - RemoteAudioTrackExecutor executor = playingTracks.get(message.executorId); - - if (executor != null) { - executor.dispatchException(new FriendlyException("Remote machine failed to start track: " + message.failureReason, SUSPICIOUS, null)); - executor.stop(); - } else { - log.debug("Received failed track start for an already stopped executor {} from node {}.", message.executorId, nodeAddress); - } - } - } - - private void handleTrackFrameData(TrackFrameDataMessage message) throws Exception { - RemoteAudioTrackExecutor executor = playingTracks.get(message.executorId); - - if (executor != null) { - if (message.seekedPosition >= 0) { - executor.clearSeek(message.seekedPosition); - } - - AudioFrameBuffer buffer = executor.getAudioBuffer(); - executor.receivedData(); - - AudioDataFormat format = executor.getConfiguration().getOutputFormat(); - - for (AudioFrame frame : message.frames) { - buffer.consume(new ImmutableAudioFrame(frame.getTimecode(), frame.getData(), frame.getVolume(), format)); - } - - if (message.finished) { - buffer.setTerminateOnEmpty(); - trackEnded(executor, false); - } - } - } - - private void handleTrackException(TrackExceptionMessage message) { - RemoteAudioTrackExecutor executor = playingTracks.get(message.executorId); - - if (executor != null) { - executor.dispatchException(message.exception); - } - } - - private void handleNodeStatistics(NodeStatisticsMessage message) { - log.trace("Received stats from node: {} {} {} {}", message.playingTrackCount, message.totalTrackCount, - message.processCpuUsage, message.systemCpuUsage); - - lastStatistics = message; - } - - /** - * @return An HTTP interface manager with appropriate timeouts for node requests. - */ - public static HttpInterfaceManager createHttpInterfaceManager() { - RequestConfig requestConfig = RequestConfig.custom() - .setConnectTimeout(CONNECT_TIMEOUT) - .setConnectionRequestTimeout(CONNECT_TIMEOUT) - .setSocketTimeout(SOCKET_TIMEOUT) - .build(); - - HttpClientBuilder builder = HttpClientTools.createSharedCookiesHttpBuilder(); - builder.setDefaultRequestConfig(requestConfig); - return new SimpleHttpInterfaceManager(builder, requestConfig); - } - - /** - * Check if there are any playing tracks on a node that has not shown signs of life in too long. In that case its - * playing tracks will also be marked dead. - * - * @param terminate Whether to terminate without checking the threshold - */ - public synchronized void processHealthCheck(boolean terminate) { - if (playingTracks.isEmpty() || (!terminate && lastAliveTime >= System.currentTimeMillis() - TRACK_KILL_THRESHOLD)) { - return; - } - - connectionState.set(ConnectionState.OFFLINE.id()); - - if (!terminate) { - log.warn("Bringing node {} offline since last response from it was {}ms ago.", nodeAddress, System.currentTimeMillis() - lastAliveTime); - } - - // There may be some racing that manages to add a track after this, it will be dealt with on the next iteration - for (Long executorId : new ArrayList<>(playingTracks.keySet())) { - RemoteAudioTrackExecutor executor = playingTracks.remove(executorId); - - if (executor != null) { - abandonedTrackManager.add(executor); - } - } - } - - private void recordTick(RemoteNode.Tick tick, RingBufferMath timingAverage) { - timingAverage.add(tick.endTime - tick.startTime); - requestTimingPenalty = (int) ((1450.0f / ((1450.0f - Math.min(timingAverage.mean(), 1440)) / 30.0f)) - 30.0f); - - synchronized (tickHistory) { - if (tickHistory.size() == NODE_REQUEST_HISTORY) { - tickHistory.removeFirst(); - } - - tickHistory.addLast(tick); - } - } - - @Override - public String getAddress() { - return nodeAddress; - } - - @Override - public ConnectionState getConnectionState() { - if (closed) { - return ConnectionState.REMOVED; - } else { - return ConnectionState.class.getEnumConstants()[connectionState.get()]; - } - } - - @Override - public NodeStatisticsMessage getLastStatistics() { - return lastStatistics; - } - - @Override - public int getTickMinimumInterval() { - return TICK_MINIMUM_INTERVAL; - } - - @Override - public int getTickHistoryCapacity() { - return NODE_REQUEST_HISTORY; - } - - @Override - public List getLastTicks(boolean reset) { - synchronized (tickHistory) { - List result = new ArrayList<>(tickHistory); - - if (reset) { - tickHistory.clear(); - } - - return result; - } - } - - @Override - public int getPlayingTrackCount() { - return playingTracks.size(); - } - - @Override - public List getPlayingTracks() { - List tracks = new ArrayList<>(); - - for (RemoteAudioTrackExecutor executor : playingTracks.values()) { - tracks.add(executor.getTrack()); - } - - return tracks; - } - - private boolean isUnavailableForTracks(NodeStatisticsMessage statistics) { - return statistics == null || connectionState.get() != ConnectionState.ONLINE.id(); - } - - private int getPenaltyForPlayingTracks(NodeStatisticsMessage statistics) { - int count = statistics.playingTrackCount; - int penalty = Math.min(count, 100); - - if (count > 100) { - penalty += Math.pow(count - 100.0, 0.7); - } - - return penalty * 3 / 2; - } - - private int getPenaltyForPausedTracks(NodeStatisticsMessage statistics) { - return statistics.totalTrackCount - statistics.playingTrackCount; - } - - private int getPenaltyForCpuUsage(NodeStatisticsMessage statistics) { - return (int) ((1.0f / ((1.0f - Math.min(statistics.systemCpuUsage, 0.99f)) / 30.0f)) - 30.0f); - } - - @Override - public Map getBalancerPenaltyDetails() { - Map details = new HashMap<>(); - NodeStatisticsMessage statistics = lastStatistics; - - if (isUnavailableForTracks(statistics)) { - details.put("unavailable", Integer.MAX_VALUE); - } else { - details.put("playing", getPenaltyForPlayingTracks(statistics)); - details.put("paused", getPenaltyForPausedTracks(statistics)); - details.put("cpu", getPenaltyForCpuUsage(statistics)); - details.put("timings", requestTimingPenalty); - } - - int total = 0; - for (int value : details.values()) { - total += value; - } - details.put("total", total); - - return details; - } - - /** - * @return The penalty for load balancing. Node with the lowest value will receive the next track. - */ - public int getBalancerPenalty() { - NodeStatisticsMessage statistics = lastStatistics; - - if (isUnavailableForTracks(statistics)) { - return Integer.MAX_VALUE; - } - - return getPenaltyForPlayingTracks(statistics) + - getPenaltyForPausedTracks(statistics) + - getPenaltyForCpuUsage(statistics) + - requestTimingPenalty; - } - - @Override - public boolean isPlayingTrack(AudioTrack track) { - AudioTrackExecutor executor = ((InternalAudioTrack) track).getActiveExecutor(); - - if (executor instanceof RemoteAudioTrackExecutor) { - return playingTracks.containsKey(((RemoteAudioTrackExecutor) executor).getExecutorId()); - } - - return false; - } - - private static class TickBuilder { - private final long startTime; - private long endTime; - private int responseCode; - private int requestSize; - private int responseSize; - - private TickBuilder(long startTime) { - this.startTime = startTime; - this.responseCode = -1; - } - - private RemoteNode.Tick build() { - return new RemoteNode.Tick(startTime, endTime, responseCode, requestSize, responseSize); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeRegistry.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeRegistry.java deleted file mode 100644 index f3d628a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/RemoteNodeRegistry.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote; - -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; - -import java.util.List; - -/** - * Registry of currently used remote nodes by a player manager. - */ -public interface RemoteNodeRegistry { - /** - * @return True if using remote nodes for audio processing is enabled. - */ - boolean isEnabled(); - - /** - * Finds the node which is playing the specified track. - * - * @param track The track to check. - * @return The node which is playing this track, or null if no node is playing it. - */ - RemoteNode getNodeUsedForTrack(AudioTrack track); - - /** - * @return List of all nodes currently in use (including ones which are offline). - */ - List getNodes(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/NodeStatisticsCodec.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/NodeStatisticsCodec.java deleted file mode 100644 index a0fabfb..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/NodeStatisticsCodec.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Codec for node statistics message. - */ -public class NodeStatisticsCodec implements RemoteMessageCodec { - @Override - public Class getMessageClass() { - return NodeStatisticsMessage.class; - } - - @Override - public int version(RemoteMessage message) { - return 1; - } - - @Override - public void encode(DataOutput out, NodeStatisticsMessage message) throws IOException { - out.writeInt(message.playingTrackCount); - out.writeInt(message.totalTrackCount); - out.writeFloat(message.systemCpuUsage); - out.writeFloat(message.processCpuUsage); - } - - @Override - public NodeStatisticsMessage decode(DataInput in, int version) throws IOException { - return new NodeStatisticsMessage(in.readInt(), in.readInt(), in.readFloat(), in.readFloat()); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/NodeStatisticsMessage.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/NodeStatisticsMessage.java deleted file mode 100644 index c0aa9f2..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/NodeStatisticsMessage.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -/** - * A message detailing track and performance statistics that a node includes in every response. - */ -public class NodeStatisticsMessage implements RemoteMessage { - /** - * The number of tracks that are not paused - */ - public final int playingTrackCount; - /** - * Total number of tracks being processed by the node - */ - public final int totalTrackCount; - /** - * Total CPU usage of the system - */ - public final float systemCpuUsage; - /** - * CPU usage of the node process - */ - public final float processCpuUsage; - - /** - * @param playingTrackCount The number of tracks that are not paused - * @param totalTrackCount Total number of tracks being processed by the node - * @param systemCpuUsage Total CPU usage of the machine - * @param processCpuUsage CPU usage of the node process - */ - public NodeStatisticsMessage(int playingTrackCount, int totalTrackCount, float systemCpuUsage, float processCpuUsage) { - this.playingTrackCount = playingTrackCount; - this.totalTrackCount = totalTrackCount; - this.systemCpuUsage = systemCpuUsage; - this.processCpuUsage = processCpuUsage; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessage.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessage.java deleted file mode 100644 index 6612a9c..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessage.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -/** - * A marker interface for all remote message classes. - */ -public interface RemoteMessage { -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageCodec.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageCodec.java deleted file mode 100644 index 4214da5..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageCodec.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Codec for encoding and decoding remote messages. - * - * @param The message class - */ -public interface RemoteMessageCodec { - /** - * @return The class of the message this codec works with - */ - Class getMessageClass(); - - /** - * @param message If set, returns version to use for this specific message. - * @return Latest version of this codec, or version to use if the message is specified. - */ - int version(RemoteMessage message); - - /** - * Encode the message to the specified output. - * - * @param out The output stream - * @param message The message to encode - * @throws IOException When an IO error occurs - */ - void encode(DataOutput out, T message) throws IOException; - - /** - * Decode a message from the specified input. - * - * @param in The input stream - * @param version Version of the message - * @return The decoded message - * @throws IOException When an IO error occurs - */ - T decode(DataInput in, int version) throws IOException; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageMapper.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageMapper.java deleted file mode 100644 index c2f2e58..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageMapper.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.util.IdentityHashMap; -import java.util.Map; - -/** - * Handles encoding and decoding of messages. - */ -public class RemoteMessageMapper { - private static final Logger log = LoggerFactory.getLogger(RemoteMessageMapper.class); - - private final Map, RemoteMessageType> encodingMap; - - /** - * Create a new instance. - */ - public RemoteMessageMapper() { - encodingMap = new IdentityHashMap<>(); - - initialiseEncodingMap(); - } - - private void initialiseEncodingMap() { - for (RemoteMessageType type : RemoteMessageType.class.getEnumConstants()) { - encodingMap.put(type.codec.getMessageClass(), type); - } - } - - /** - * Decodes one message. If the input stream indicates the end of messages, null is returned. - * - * @param input The input stream containing the message - * @return The decoded message or null in case no more messages are present - * @throws IOException When an IO error occurs - */ - public RemoteMessage decode(DataInput input) throws IOException { - int messageSize = input.readInt(); - if (messageSize == 0) { - return null; - } - - RemoteMessageType[] types = RemoteMessageType.class.getEnumConstants(); - int typeIndex = input.readByte() & 0xFF; - int version = input.readByte() & 0xFF; - - if (typeIndex >= types.length) { - log.warn("Invalid message type {}.", typeIndex); - input.readFully(new byte[messageSize - 1]); - return UnknownMessage.INSTANCE; - } - - RemoteMessageType type = types[typeIndex]; - - if (version < 1 || version > type.codec.version(null)) { - log.warn("Invalid version {} for message {}.", version, type); - input.readFully(new byte[messageSize - 2]); - return UnknownMessage.INSTANCE; - } - - return type.codec.decode(input, version); - } - - /** - * Encodes one message. - * - * @param output The output stream to encode to - * @param message The message to encode - * @throws IOException When an IO error occurs - */ - @SuppressWarnings("unchecked") - public void encode(DataOutputStream output, RemoteMessage message) throws IOException { - RemoteMessageType type = encodingMap.get(message.getClass()); - - ByteArrayOutputStream messageOutputBytes = new ByteArrayOutputStream(); - DataOutput messageOutput = new DataOutputStream(messageOutputBytes); - - RemoteMessageCodec codec = type.codec; - codec.encode(messageOutput, message); - - output.writeInt(messageOutputBytes.size() + 2); - output.writeByte((byte) type.ordinal()); - output.writeByte((byte) type.codec.version(message)); - messageOutputBytes.writeTo(output); - } - - /** - * Write the marker to indicate no more messages are in the stream. - * - * @param output The output stream - * @throws IOException When an IO error occurs - */ - public void endOutput(DataOutputStream output) throws IOException { - output.writeInt(0); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageType.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageType.java deleted file mode 100644 index 8e81937..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/RemoteMessageType.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -/** - * All remote message types. - */ -public enum RemoteMessageType { - TRACK_START_REQUEST(new TrackStartRequestCodec()), - TRACK_START_RESPONSE(new TrackStartResponseCodec()), - TRACK_FRAME_REQUEST(new TrackFrameRequestCodec()), - TRACK_FRAME_DATA(new TrackFrameDataCodec()), - TRACK_STOPPED(new TrackStoppedCodec()), - TRACK_EXCEPTION(new TrackExceptionCodec()), - NODE_STATISTICS(new NodeStatisticsCodec()); - - /** - * The codec used for encoding and decoding this type of message. - */ - public final RemoteMessageCodec codec; - - RemoteMessageType(RemoteMessageCodec codec) { - this.codec = codec; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackExceptionCodec.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackExceptionCodec.java deleted file mode 100644 index 2e172f4..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackExceptionCodec.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Codec for track exception message. - */ -public class TrackExceptionCodec implements RemoteMessageCodec { - @Override - public Class getMessageClass() { - return TrackExceptionMessage.class; - } - - @Override - public int version(RemoteMessage message) { - return 1; - } - - @Override - public void encode(DataOutput out, TrackExceptionMessage message) throws IOException { - out.writeLong(message.executorId); - ExceptionTools.encodeException(out, message.exception); - } - - @Override - public TrackExceptionMessage decode(DataInput in, int version) throws IOException { - return new TrackExceptionMessage(in.readLong(), ExceptionTools.decodeException(in)); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackExceptionMessage.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackExceptionMessage.java deleted file mode 100644 index 324dbf1..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackExceptionMessage.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; - -/** - * Track exception message which is sent by the node when processing the track in the node fails. - */ -public class TrackExceptionMessage implements RemoteMessage { - /** - * The ID for the track executor - */ - public final long executorId; - /** - * Exception that was thrown by the local executor - */ - public final FriendlyException exception; - - /** - * @param executorId The ID for the track executor - * @param exception Exception that was thrown by the local executor - */ - public TrackExceptionMessage(long executorId, FriendlyException exception) { - this.executorId = executorId; - this.exception = exception; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameDataCodec.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameDataCodec.java deleted file mode 100644 index 7f9db39..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameDataCodec.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; -import com.sedmelluq.discord.lavaplayer.track.playback.ImmutableAudioFrame; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * Codec for track frame data message. - */ -public class TrackFrameDataCodec implements RemoteMessageCodec { - @Override - public Class getMessageClass() { - return TrackFrameDataMessage.class; - } - - @Override - public int version(RemoteMessage message) { - return 1; - } - - @Override - public void encode(DataOutput out, TrackFrameDataMessage message) throws IOException { - out.writeLong(message.executorId); - out.writeInt(message.frames.size()); - - for (AudioFrame frame : message.frames) { - out.writeLong(frame.getTimecode()); - out.writeInt(frame.getDataLength()); - out.write(frame.getData()); - out.writeInt(frame.getVolume()); - } - - out.writeBoolean(message.finished); - out.writeLong(message.seekedPosition); - } - - @Override - public TrackFrameDataMessage decode(DataInput in, int version) throws IOException { - long executorId = in.readLong(); - int frameCount = in.readInt(); - - List frames = new ArrayList<>(frameCount); - - for (int i = 0; i < frameCount; i++) { - long timecode = in.readLong(); - byte[] data = new byte[in.readInt()]; - in.readFully(data); - - frames.add(new ImmutableAudioFrame(timecode, data, in.readInt(), null)); - } - - return new TrackFrameDataMessage(executorId, frames, in.readBoolean(), in.readLong()); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameDataMessage.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameDataMessage.java deleted file mode 100644 index 7018b55..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameDataMessage.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; - -import java.util.List; - -/** - * Message from an audio node to the master as a response to TrackFrameRequestMessage. Bouncing back the seeked position - * is necessary because then the master can clear up the pending seek only if it matches this number. Otherwise the seek - * position has been changed while the data for the previous seek was requested. The master also cannot clear the seek - * state when sending the request, because in case the request fails, the seek will be discarded. - */ -public class TrackFrameDataMessage implements RemoteMessage { - /** - * The ID for the track executor - */ - public final long executorId; - /** - * Frames provided by the node. These are missing the audio format, which must be attached locally. It can be assumed - * that the node provides data in the format that it was initially requested in. - */ - public final List frames; - /** - * If these are the last frames for the track. After receiving a message with this set to true, no more requests about - * this track should be made to the node as it has already deleted the track from its registry. - */ - public final boolean finished; - /** - * In case the data request included a seek, then this will report that the seek was completed by having the requested - * seek position as a value. When no seek was performed, this is -1. The frames returned in this message start from - * this position. - */ - public final long seekedPosition; - - /** - * @param executorId The ID for the track executor - * @param frames Frames provided by the node - * @param finished If these are the last frames for the track - * @param seekedPosition The position of the seek that was performed - */ - public TrackFrameDataMessage(long executorId, List frames, boolean finished, long seekedPosition) { - this.executorId = executorId; - this.frames = frames; - this.finished = finished; - this.seekedPosition = seekedPosition; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameRequestCodec.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameRequestCodec.java deleted file mode 100644 index a857db3..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameRequestCodec.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Codec for track frame request message. - */ -public class TrackFrameRequestCodec implements RemoteMessageCodec { - @Override - public Class getMessageClass() { - return TrackFrameRequestMessage.class; - } - - @Override - public int version(RemoteMessage message) { - return 1; - } - - @Override - public void encode(DataOutput out, TrackFrameRequestMessage message) throws IOException { - out.writeLong(message.executorId); - out.writeInt(message.maximumFrames); - out.writeInt(message.volume); - out.writeLong(message.seekPosition); - } - - @Override - public TrackFrameRequestMessage decode(DataInput in, int version) throws IOException { - return new TrackFrameRequestMessage(in.readLong(), in.readInt(), in.readInt(), in.readLong()); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameRequestMessage.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameRequestMessage.java deleted file mode 100644 index 79aa300..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackFrameRequestMessage.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -/** - * A message sent to the node to request frames from a track. This is sent even when no frames are required as it is - * used to indicate that the track is still alive in the master. - */ -public class TrackFrameRequestMessage implements RemoteMessage { - /** - * The ID for the track executor - */ - public final long executorId; - /** - * Maximum number of frames that can be included in the response - */ - public final int maximumFrames; - /** - * Current volume of the track - */ - public final int volume; - /** - * The position to seek to. Value is -1 if no seeking is required at the moment. - */ - public final long seekPosition; - - /** - * @param executorId The ID for the track executor - * @param maximumFrames Maximum number of frames that can be included in the response - * @param volume Current volume of the track - * @param seekPosition The position to seek to - */ - public TrackFrameRequestMessage(long executorId, int maximumFrames, int volume, long seekPosition) { - this.executorId = executorId; - this.maximumFrames = maximumFrames; - this.volume = volume; - this.seekPosition = seekPosition; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartRequestCodec.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartRequestCodec.java deleted file mode 100644 index 54f1cca..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartRequestCodec.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.format.OpusAudioDataFormat; -import com.sedmelluq.discord.lavaplayer.format.Pcm16AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.format.StandardAudioDataFormats; -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Codec for track start message. - */ -public class TrackStartRequestCodec implements RemoteMessageCodec { - private static final int VERSION_INITIAL = 1; - private static final int VERSION_WITH_FORMAT = 2; - private static final int VERSION_WITH_POSITION = 3; - - @Override - public Class getMessageClass() { - return TrackStartRequestMessage.class; - } - - @Override - public int version(RemoteMessage message) { - // Backwards compatibility with older nodes. - if (message instanceof TrackStartRequestMessage) { - if (((TrackStartRequestMessage) message).position != 0) { - return VERSION_WITH_POSITION; - } - - AudioDataFormat format = ((TrackStartRequestMessage) message).configuration.getOutputFormat(); - - if (!format.equals(StandardAudioDataFormats.DISCORD_OPUS)) { - return VERSION_WITH_FORMAT; - } - - return VERSION_INITIAL; - } - - return VERSION_WITH_POSITION; - } - - @Override - public void encode(DataOutput out, TrackStartRequestMessage message) throws IOException { - int version = version(message); - - out.writeLong(message.executorId); - out.writeUTF(message.trackInfo.title); - out.writeUTF(message.trackInfo.author); - out.writeLong(message.trackInfo.length); - out.writeUTF(message.trackInfo.identifier); - out.writeBoolean(message.trackInfo.isStream); - out.writeInt(message.encodedTrack.length); - out.write(message.encodedTrack); - out.writeInt(message.volume); - out.writeUTF(message.configuration.getResamplingQuality().name()); - out.writeInt(message.configuration.getOpusEncodingQuality()); - - if (version >= VERSION_WITH_FORMAT) { - AudioDataFormat format = message.configuration.getOutputFormat(); - out.writeInt(format.channelCount); - out.writeInt(format.sampleRate); - out.writeInt(format.chunkSampleCount); - out.writeUTF(format.codecName()); - } - - if (version >= VERSION_WITH_POSITION) { - out.writeLong(message.position); - } - } - - @Override - public TrackStartRequestMessage decode(DataInput in, int version) throws IOException { - long executorId = in.readLong(); - AudioTrackInfo trackInfo = new AudioTrackInfo(in.readUTF(), in.readUTF(), in.readLong(), in.readUTF(), in.readBoolean(), null); - - byte[] encodedTrack = new byte[in.readInt()]; - in.readFully(encodedTrack); - - int volume = in.readInt(); - AudioConfiguration configuration = new AudioConfiguration(); - configuration.setResamplingQuality(AudioConfiguration.ResamplingQuality.valueOf(in.readUTF())); - configuration.setOpusEncodingQuality(in.readInt()); - - if (version >= VERSION_WITH_FORMAT) { - AudioDataFormat format = createFormat(in.readInt(), in.readInt(), in.readInt(), in.readUTF()); - configuration.setOutputFormat(format); - } - - long position = 0; - - if (version >= VERSION_WITH_POSITION) { - position = in.readLong(); - } - - return new TrackStartRequestMessage(executorId, trackInfo, encodedTrack, volume, configuration, position); - } - - private AudioDataFormat createFormat(int channelCount, int sampleRate, int chunkSampleCount, String codecName) - throws IOException { - - switch (codecName) { - case OpusAudioDataFormat.CODEC_NAME: - return new OpusAudioDataFormat(channelCount, sampleRate, chunkSampleCount); - case Pcm16AudioDataFormat.CODEC_NAME_LE: - return new Pcm16AudioDataFormat(channelCount, sampleRate, chunkSampleCount, false); - case Pcm16AudioDataFormat.CODEC_NAME_BE: - return new Pcm16AudioDataFormat(channelCount, sampleRate, chunkSampleCount, true); - default: - throw new IOException("Unsupported codec requested."); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartRequestMessage.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartRequestMessage.java deleted file mode 100644 index 785e96f..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartRequestMessage.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; - -/** - * The message that is sent to the node when the master requests the node to start playing a track. - */ -public class TrackStartRequestMessage implements RemoteMessage { - /** - * The ID for the track executor - */ - public final long executorId; - /** - * Generic track information - */ - public final AudioTrackInfo trackInfo; - /** - * Track specific extra information that is required to initialise the track object - */ - public final byte[] encodedTrack; - /** - * Initial volume of the track - */ - public final int volume; - /** - * Configuration to use for audio processing - */ - public final AudioConfiguration configuration; - /** - * Position to start playing at in milliseconds - */ - public final long position; - - /** - * @param executorId The ID for the track executor - * @param trackInfo Generic track information - * @param encodedTrack Track specific extra information that is required to initialise the track object - * @param volume Initial volume of the track - * @param configuration Configuration to use for audio processing - * @param position Position to start playing at in milliseconds - */ - public TrackStartRequestMessage(long executorId, AudioTrackInfo trackInfo, byte[] encodedTrack, int volume, - AudioConfiguration configuration, long position) { - - this.executorId = executorId; - this.encodedTrack = encodedTrack; - this.trackInfo = trackInfo; - this.volume = volume; - this.configuration = configuration; - this.position = position; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartResponseCodec.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartResponseCodec.java deleted file mode 100644 index a8ec66b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartResponseCodec.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Codec for track start request response message. - */ -public class TrackStartResponseCodec implements RemoteMessageCodec { - @Override - public Class getMessageClass() { - return TrackStartResponseMessage.class; - } - - @Override - public int version(RemoteMessage message) { - return 1; - } - - @Override - public void encode(DataOutput out, TrackStartResponseMessage message) throws IOException { - out.writeLong(message.executorId); - out.writeBoolean(message.success); - - if (!message.success) { - out.writeUTF(message.failureReason); - } - } - - @Override - public TrackStartResponseMessage decode(DataInput in, int version) throws IOException { - long executorId = in.readLong(); - boolean success = in.readBoolean(); - - return new TrackStartResponseMessage(executorId, success, success ? null : in.readUTF()); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartResponseMessage.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartResponseMessage.java deleted file mode 100644 index 673b931..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStartResponseMessage.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -/** - * This is the response to a TrackStartRequestMessage. It indicates whether the track was successfully started on the - * node. This does not guarantee that any frames from the track will arrive, only that its execution was submitted. - */ -public class TrackStartResponseMessage implements RemoteMessage { - /** - * The ID for the track executor - */ - public final long executorId; - /** - * Whether the track was successfully started in the node - */ - public final boolean success; - /** - * The reason in case the track was not started - */ - public final String failureReason; - - /** - * @param executorId The ID for the track executor - * @param success Whether the track was successfully started in the node - * @param failureReason The reason in case the track was not started - */ - public TrackStartResponseMessage(long executorId, boolean success, String failureReason) { - this.executorId = executorId; - this.success = success; - this.failureReason = failureReason; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStoppedCodec.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStoppedCodec.java deleted file mode 100644 index 4c01030..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStoppedCodec.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Codec for stopped track notification message. - */ -public class TrackStoppedCodec implements RemoteMessageCodec { - @Override - public Class getMessageClass() { - return TrackStoppedMessage.class; - } - - @Override - public int version(RemoteMessage message) { - return 1; - } - - @Override - public void encode(DataOutput out, TrackStoppedMessage message) throws IOException { - out.writeLong(message.executorId); - } - - @Override - public TrackStoppedMessage decode(DataInput in, int version) throws IOException { - return new TrackStoppedMessage(in.readLong()); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStoppedMessage.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStoppedMessage.java deleted file mode 100644 index ae5bf9c..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/TrackStoppedMessage.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -/** - * Message to notify the node that the track has been stopped in the master. No more requests for that track will occur - * so the track may be deleted from the node. - */ -public class TrackStoppedMessage implements RemoteMessage { - /** - * The ID for the track executor - */ - public final long executorId; - - /** - * @param executorId The ID for the track executor - */ - public TrackStoppedMessage(long executorId) { - this.executorId = executorId; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/UnknownMessage.java b/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/UnknownMessage.java deleted file mode 100644 index 1bf8ce5..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/remote/message/UnknownMessage.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.remote.message; - -/** - * Used for cases where the message could not be decoded. - */ -public class UnknownMessage implements RemoteMessage { - /** - * Keep a singleton instance as there can be no difference between instances. - */ - public static final UnknownMessage INSTANCE = new UnknownMessage(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/AudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/AudioSourceManager.java deleted file mode 100644 index 883a9ae..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/AudioSourceManager.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source; - -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -/** - * Manager for a source of audio items. - */ -public interface AudioSourceManager { - /** - * Every source manager implementation should have its unique name as it is used to determine which source manager - * should be able to decode a serialized audio track. - * - * @return The name of this source manager - */ - String getSourceName(); - - /** - * Returns an audio track for the input string. It should return null if it can immediately detect that there is no - * track for this identifier for this source. If checking that requires more expensive operations, then it should - * return a track instance and check that in InternalAudioTrack#loadTrackInfo. - * - * @param manager The audio manager to attach to the loaded tracks - * @param reference The reference with the identifier which the source manager should find the track with - * @return The loaded item or null on unrecognized identifier - */ - AudioItem loadItem(DefaultAudioPlayerManager manager, AudioReference reference); - - /** - * Returns whether the specified track can be encoded. The argument is always a track created by this manager. Being - * encodable also means that it must be possible to play this track on a different node, so it should not depend on - * any resources that are only available on the current system. - * - * @param track The track to check - * @return True if it is encodable - */ - boolean isTrackEncodable(AudioTrack track); - - /** - * Encodes an audio track into the specified output. The contents of AudioTrackInfo do not have to be included since - * they are written to the output already before this call. This will only be called for tracks which were loaded by - * this source manager and for which isEncodable() returns true. - * - * @param track The track to encode - * @param output Output where to write the decoded format to - * @throws IOException On write error. - */ - void encodeTrack(AudioTrack track, DataOutput output) throws IOException; - - /** - * Decodes an audio track from the encoded format encoded with encodeTrack(). - * - * @param trackInfo The track info - * @param input The input where to read the bytes of the encoded format - * @return The decoded track - * @throws IOException On read error. - */ - AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) throws IOException; - - /** - * Shut down the source manager, freeing all associated resources and threads. A source manager is not responsible for - * terminating the tracks that it has created. - */ - void shutdown(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/AudioSourceManagers.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/AudioSourceManagers.java deleted file mode 100644 index 1e805b3..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/AudioSourceManagers.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerRegistry; -import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.bandcamp.BandcampAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.beam.BeamAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.local.LocalAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.soundcloud.SoundCloudAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.vimeo.VimeoAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager; - -/** - * A helper class for registering built-in source managers to a player manager. - */ -public class AudioSourceManagers { - /** - * See {@link #registerRemoteSources(AudioPlayerManager, MediaContainerRegistry)}, but with default containers. - */ - public static void registerRemoteSources(AudioPlayerManager playerManager) { - registerRemoteSources(playerManager, MediaContainerRegistry.DEFAULT_REGISTRY); - } - - /** - * Registers all built-in remote audio sources to the specified player manager. Local file audio source must be - * registered separately. - * - * @param playerManager Player manager to register the source managers to - * @param containerRegistry Media container registry to be used by any probing sources. - */ - public static void registerRemoteSources(AudioPlayerManager playerManager, MediaContainerRegistry containerRegistry) { - playerManager.registerSourceManager(new YoutubeAudioSourceManager(true)); - playerManager.registerSourceManager(new SoundCloudAudioSourceManager()); - playerManager.registerSourceManager(new BandcampAudioSourceManager()); - playerManager.registerSourceManager(new VimeoAudioSourceManager()); - playerManager.registerSourceManager(new TwitchStreamAudioSourceManager()); - playerManager.registerSourceManager(new BeamAudioSourceManager()); - playerManager.registerSourceManager(new HttpAudioSourceManager()); - } - - /** - * Registers the local file source manager to the specified player manager. - * - * @param playerManager Player manager to register the source manager to - */ - public static void registerLocalSource(AudioPlayerManager playerManager) { - registerLocalSource(playerManager, MediaContainerRegistry.DEFAULT_REGISTRY); - } - - /** - * Registers the local file source manager to the specified player manager. - * - * @param playerManager Player manager to register the source manager to - * @param containerRegistry Media container registry to be used by the local source. - */ - public static void registerLocalSource(AudioPlayerManager playerManager, MediaContainerRegistry containerRegistry) { - playerManager.registerSourceManager(new LocalAudioSourceManager()); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/ProbingAudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/ProbingAudioSourceManager.java deleted file mode 100644 index 4fb8acb..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/ProbingAudioSourceManager.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDescriptor; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerProbe; -import com.sedmelluq.discord.lavaplayer.container.MediaContainerRegistry; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.COMMON; - -/** - * The base class for audio sources which use probing to detect container type. - */ -public abstract class ProbingAudioSourceManager implements AudioSourceManager { - private static final char PARAMETERS_SEPARATOR = '|'; - - protected final MediaContainerRegistry containerRegistry; - - protected ProbingAudioSourceManager(MediaContainerRegistry containerRegistry) { - this.containerRegistry = containerRegistry; - } - - protected AudioItem handleLoadResult(MediaContainerDetectionResult result) { - if (result != null) { - if (result.isReference()) { - return result.getReference(); - } else if (!result.isContainerDetected()) { - throw new FriendlyException("Unknown file format.", COMMON, null); - } else if (!result.isSupportedFile()) { - throw new FriendlyException(result.getUnsupportedReason(), COMMON, null); - } else { - return createTrack(result.getTrackInfo(), result.getContainerDescriptor()); - } - } - - return null; - } - - protected abstract AudioTrack createTrack(AudioTrackInfo trackInfo, MediaContainerDescriptor containerTrackFactory); - - protected void encodeTrackFactory(MediaContainerDescriptor factory, DataOutput output) throws IOException { - String probeInfo = factory.probe.getName() + (factory.parameters != null ? PARAMETERS_SEPARATOR + - factory.parameters : ""); - - output.writeUTF(probeInfo); - } - - protected MediaContainerDescriptor decodeTrackFactory(DataInput input) throws IOException { - String probeInfo = input.readUTF(); - int separatorPosition = probeInfo.indexOf(PARAMETERS_SEPARATOR); - - String probeName = separatorPosition < 0 ? probeInfo : probeInfo.substring(0, separatorPosition); - String parameters = separatorPosition < 0 ? null : probeInfo.substring(separatorPosition + 1); - - MediaContainerProbe probe = containerRegistry.find(probeName); - if (probe != null) { - return new MediaContainerDescriptor(probe, parameters); - } - - return null; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/bandcamp/BandcampAudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/bandcamp/BandcampAudioSourceManager.java deleted file mode 100644 index b45a80b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/bandcamp/BandcampAudioSourceManager.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.bandcamp; - -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpConfigurable; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.*; -import org.apache.commons.io.IOUtils; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.HttpClientBuilder; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.regex.Pattern; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.FAULT; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio source manager that implements finding Bandcamp tracks based on URL. - */ -public class BandcampAudioSourceManager implements AudioSourceManager, HttpConfigurable { - private static final String TRACK_URL_REGEX = "^https?://(?:[^.]+\\.|)bandcamp\\.com/track/([a-zA-Z0-9-_]+)/?(?:\\?.*|)$"; - private static final String ALBUM_URL_REGEX = "^https?://(?:[^.]+\\.|)bandcamp\\.com/album/([a-zA-Z0-9-_]+)/?(?:\\?.*|)$"; - - private static final Pattern trackUrlPattern = Pattern.compile(TRACK_URL_REGEX); - private static final Pattern albumUrlPattern = Pattern.compile(ALBUM_URL_REGEX); - - private final HttpInterfaceManager httpInterfaceManager; - - /** - * Create an instance. - */ - public BandcampAudioSourceManager() { - httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager(); - } - - @Override - public String getSourceName() { - return "bandcamp"; - } - - @Override - public AudioItem loadItem(DefaultAudioPlayerManager manager, AudioReference reference) { - if (trackUrlPattern.matcher(reference.identifier).matches()) { - return loadTrack(reference.identifier); - } else if (albumUrlPattern.matcher(reference.identifier).matches()) { - return loadAlbum(reference.identifier); - } - return null; - } - - private AudioItem loadTrack(String trackUrl) { - return extractFromPage(trackUrl, (httpClient, text) -> { - String bandUrl = readBandUrl(text); - JsonBrowser trackListInfo = readTrackListInformation(text); - String artist = trackListInfo.get("artist").text(); - - return extractTrack(trackListInfo.get("trackinfo").index(0), bandUrl, artist); - }); - } - - private AudioItem loadAlbum(String albumUrl) { - return extractFromPage(albumUrl, (httpClient, text) -> { - String bandUrl = readBandUrl(text); - JsonBrowser trackListInfo = readTrackListInformation(text); - String artist = trackListInfo.get("artist").text(); - - List tracks = new ArrayList<>(); - for (JsonBrowser trackInfo : trackListInfo.get("trackinfo").values()) { - tracks.add(extractTrack(trackInfo, bandUrl, artist)); - } - - JsonBrowser albumInfo = readAlbumInformation(text); - return new BasicAudioPlaylist(albumInfo.get("album_title").text(), tracks, null, false); - }); - } - - private AudioTrack extractTrack(JsonBrowser trackInfo, String bandUrl, String artist) { - String trackPageUrl = bandUrl + trackInfo.get("title_link").text(); - - return new BandcampAudioTrack(new AudioTrackInfo( - trackInfo.get("title").text(), - artist, - (long) (trackInfo.get("duration").as(Double.class) * 1000.0), - bandUrl + trackInfo.get("title_link").text(), - false, - trackPageUrl - ), this); - } - - private String readBandUrl(String text) { - String bandUrl = DataFormatTools.extractBetween(text, "var band_url = \"", "\";"); - - if (bandUrl == null) { - throw new FriendlyException("Band information not found on the Bandcamp page.", SUSPICIOUS, null); - } - - return bandUrl; - } - - private JsonBrowser readAlbumInformation(String text) throws IOException { - String albumInfoJson = DataFormatTools.extractBetween(text, "var EmbedData = ", "};"); - - if (albumInfoJson == null) { - throw new FriendlyException("Album information not found on the Bandcamp page.", SUSPICIOUS, null); - } - - albumInfoJson = albumInfoJson.replace("\" + \"", "") + "};"; - return JsonBrowser.parse(albumInfoJson); - } - - JsonBrowser readTrackListInformation(String text) throws IOException { - String trackInfoJson = DataFormatTools.extractBetween(text, "var TralbumData = ", "};"); - - if (trackInfoJson == null) { - throw new FriendlyException("Track information not found on the Bandcamp page.", SUSPICIOUS, null); - } - - trackInfoJson = trackInfoJson.replace("\" + \"", "") + "};"; - return JsonBrowser.parse(trackInfoJson + "};"); - } - - private AudioItem extractFromPage(String url, AudioItemExtractor extractor) { - try (HttpInterface httpInterface = httpInterfaceManager.getInterface()) { - return extractFromPageWithInterface(httpInterface, url, extractor); - } catch (Exception e) { - throw ExceptionTools.wrapUnfriendlyExceptions("Loading information for a Bandcamp track failed.", FAULT, e); - } - } - - private AudioItem extractFromPageWithInterface(HttpInterface httpInterface, String url, AudioItemExtractor extractor) throws Exception { - String responseText; - - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(url))) { - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode == 404) { - return new AudioReference(null, null); - } else if (statusCode != 200) { - throw new IOException("Invalid status code for track page: " + statusCode); - } - - responseText = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); - } - - return extractor.extract(httpInterface, responseText); - } - - @Override - public boolean isTrackEncodable(AudioTrack track) { - return true; - } - - @Override - public void encodeTrack(AudioTrack track, DataOutput output) throws IOException { - // No special values to encode - } - - @Override - public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) throws IOException { - return new BandcampAudioTrack(trackInfo, this); - } - - @Override - public void shutdown() { - ExceptionTools.closeWithWarnings(httpInterfaceManager); - } - - /** - * @return Get an HTTP interface for a playing track. - */ - public HttpInterface getHttpInterface() { - return httpInterfaceManager.getInterface(); - } - - @Override - public void configureRequests(Function configurator) { - httpInterfaceManager.configureRequests(configurator); - } - - @Override - public void configureBuilder(Consumer configurator) { - httpInterfaceManager.configureBuilder(configurator); - } - - private interface AudioItemExtractor { - AudioItem extract(HttpInterface httpInterface, String text) throws Exception; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/bandcamp/BandcampAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/bandcamp/BandcampAudioTrack.java deleted file mode 100644 index 1380d3b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/bandcamp/BandcampAudioTrack.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.bandcamp; - -import com.sedmelluq.discord.lavaplayer.container.mp3.Mp3AudioTrack; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.PersistentHttpStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.apache.commons.io.IOUtils; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; - -/** - * Audio track that handles processing Bandcamp tracks. - */ -public class BandcampAudioTrack extends DelegatedAudioTrack { - private static final Logger log = LoggerFactory.getLogger(BandcampAudioTrack.class); - - private final BandcampAudioSourceManager sourceManager; - - /** - * @param trackInfo Track info - * @param sourceManager Source manager which was used to find this track - */ - public BandcampAudioTrack(AudioTrackInfo trackInfo, BandcampAudioSourceManager sourceManager) { - super(trackInfo); - - this.sourceManager = sourceManager; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - try (HttpInterface httpInterface = sourceManager.getHttpInterface()) { - log.debug("Loading Bandcamp track page from URL: {}", trackInfo.identifier); - - String trackMediaUrl = getTrackMediaUrl(httpInterface); - log.debug("Starting Bandcamp track from URL: {}", trackMediaUrl); - - try (PersistentHttpStream stream = new PersistentHttpStream(httpInterface, new URI(trackMediaUrl), null)) { - processDelegate(new Mp3AudioTrack(trackInfo, stream), localExecutor); - } - } - } - - private String getTrackMediaUrl(HttpInterface httpInterface) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(trackInfo.identifier))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for track page: " + statusCode); - } - - String responseText = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); - JsonBrowser trackInfo = sourceManager.readTrackListInformation(responseText); - - return trackInfo.get("trackinfo").index(0).get("file").get("mp3-128").text(); - } - } - - @Override - public AudioTrack makeClone() { - return new BandcampAudioTrack(trackInfo, sourceManager); - } - - @Override - public AudioSourceManager getSourceManager() { - return sourceManager; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamAudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamAudioSourceManager.java deleted file mode 100644 index 07af3c9..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamAudioSourceManager.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.beam; - -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpConfigurable; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.HttpClientBuilder; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio source manager which detects Beam.pro tracks by URL. - */ -public class BeamAudioSourceManager implements AudioSourceManager, HttpConfigurable { - private static final String STREAM_NAME_REGEX = "^https://(?:www\\.)?(?:beam\\.pro|mixer\\.com)/([^/]+)$"; - private static final Pattern streamNameRegex = Pattern.compile(STREAM_NAME_REGEX); - - private final HttpInterfaceManager httpInterfaceManager; - - /** - * Create an instance. - */ - public BeamAudioSourceManager() { - this.httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager(); - } - - @Override - public String getSourceName() { - return "beam.pro"; - } - - @Override - public AudioItem loadItem(DefaultAudioPlayerManager manager, AudioReference reference) { - String streamName = getChannelNameFromUrl(reference.identifier); - if (streamName == null) { - return null; - } - - JsonBrowser channelInfo = fetchStreamChannelInfo(streamName); - - if (channelInfo == null) { - return AudioReference.NO_TRACK; - } else { - String displayName = channelInfo.get("name").text(); - String id = getPlayedStreamId(channelInfo); - - if (displayName == null || id == null) { - throw new IllegalStateException("Expected id and name fields from Beam channel info."); - } - - return new BeamAudioTrack(new AudioTrackInfo( - displayName, - streamName, - Long.MAX_VALUE, - id + "|" + streamName + "|" + reference.identifier, - true, - "https://beam.pro/" + streamName - ), this); - } - } - - @Override - public boolean isTrackEncodable(AudioTrack track) { - return true; - } - - @Override - public void encodeTrack(AudioTrack track, DataOutput output) throws IOException { - // Nothing special to do, URL (identifier) is enough - } - - @Override - public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) throws IOException { - return new BeamAudioTrack(trackInfo, this); - } - - @Override - public void shutdown() { - // Nothing to shut down. - } - - private static String getPlayedStreamId(JsonBrowser channelInfo) { - // If there is a hostee, this means that the current channel itself is not actually broadcasting anything and all - // further requests should be performed with the ID of the hostee. Hostee is not rechecked later so it will keep - // playing the current hostee even if it changes. - String hosteeId = channelInfo.get("hosteeId").text(); - return hosteeId != null ? hosteeId : channelInfo.get("id").text(); - } - - private static String getChannelNameFromUrl(String url) { - Matcher matcher = streamNameRegex.matcher(url); - if (!matcher.matches()) { - return null; - } - - return matcher.group(1); - } - - private JsonBrowser fetchStreamChannelInfo(String name) { - try (HttpInterface httpInterface = getHttpInterface()) { - return HttpClientTools.fetchResponseAsJson(httpInterface, - new HttpGet("https://mixer.com/api/v1/channels/" + name + "?noCount=1")); - } catch (IOException e) { - throw new FriendlyException("Loading Beam channel information failed.", SUSPICIOUS, e); - } - } - - /** - * @return Get an HTTP interface for a playing track. - */ - public HttpInterface getHttpInterface() { - return httpInterfaceManager.getInterface(); - } - - @Override - public void configureRequests(Function configurator) { - httpInterfaceManager.configureRequests(configurator); - } - - @Override - public void configureBuilder(Consumer configurator) { - httpInterfaceManager.configureBuilder(configurator); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamAudioTrack.java deleted file mode 100644 index cf64986..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamAudioTrack.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.beam; - -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.stream.M3uStreamAudioTrack; -import com.sedmelluq.discord.lavaplayer.source.stream.M3uStreamSegmentUrlProvider; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Audio track that handles processing Beam.pro tracks. - */ -public class BeamAudioTrack extends M3uStreamAudioTrack { - private static final Logger log = LoggerFactory.getLogger(BeamAudioTrack.class); - - private final BeamAudioSourceManager sourceManager; - private final M3uStreamSegmentUrlProvider segmentUrlProvider; - - - /** - * @param trackInfo Track info - * @param sourceManager Source manager which was used to find this track - */ - public BeamAudioTrack(AudioTrackInfo trackInfo, BeamAudioSourceManager sourceManager) { - super(trackInfo); - - this.sourceManager = sourceManager; - this.segmentUrlProvider = new BeamSegmentUrlProvider(getChannelId()); - } - - @Override - protected M3uStreamSegmentUrlProvider getSegmentUrlProvider() { - return segmentUrlProvider; - } - - @Override - protected HttpInterface getHttpInterface() { - return sourceManager.getHttpInterface(); - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - log.debug("Starting to play Beam channel {}.", getChannelUrl()); - - super.process(localExecutor); - } - - @Override - public AudioTrack makeClone() { - return new BeamAudioTrack(trackInfo, sourceManager); - } - - @Override - public AudioSourceManager getSourceManager() { - return sourceManager; - } - - private String getChannelId() { - return trackInfo.identifier.substring(0, trackInfo.identifier.indexOf('|')); - } - - private String getChannelUrl() { - return trackInfo.identifier.substring(trackInfo.identifier.lastIndexOf('|') + 1); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamSegmentUrlProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamSegmentUrlProvider.java deleted file mode 100644 index 87bbd00..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/beam/BeamSegmentUrlProvider.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.beam; - -import com.sedmelluq.discord.lavaplayer.source.stream.ExtendedM3uParser; -import com.sedmelluq.discord.lavaplayer.source.stream.M3uStreamSegmentUrlProvider; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.List; - -import static com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools.fetchResponseLines; - -/** - * Provider for Beam segment URLs from a channel. - */ -public class BeamSegmentUrlProvider extends M3uStreamSegmentUrlProvider { - private static final Logger log = LoggerFactory.getLogger(BeamSegmentUrlProvider.class); - - private final String channelId; - private String streamSegmentPlaylistUrl; - - /** - * @param channelId Channel ID number. - */ - public BeamSegmentUrlProvider(String channelId) { - this.channelId = channelId; - } - - @Override - protected String getQualityFromM3uDirective(ExtendedM3uParser.Line directiveLine) { - return directiveLine.directiveArguments.get("NAME"); - } - - @Override - protected String fetchSegmentPlaylistUrl(HttpInterface httpInterface) throws IOException { - if (streamSegmentPlaylistUrl != null) { - return streamSegmentPlaylistUrl; - } - - HttpUriRequest jsonRequest = new HttpGet("https://mixer.com/api/v1/channels/" + channelId + "/manifest.light2"); - JsonBrowser lightManifest = HttpClientTools.fetchResponseAsJson(httpInterface, jsonRequest); - - if (lightManifest == null) { - throw new IllegalStateException("Did not find light manifest at " + jsonRequest.getURI()); - } - - HttpUriRequest manifestRequest = new HttpGet("https://mixer.com" + lightManifest.get("hlsSrc").text()); - List streams = loadChannelStreamsList(fetchResponseLines(httpInterface, manifestRequest, - "mixer channel streams list")); - - if (streams.isEmpty()) { - throw new IllegalStateException("No streams available on channel."); - } - - ChannelStreamInfo stream = streams.get(0); - - log.debug("Chose stream with quality {} from url {}", stream.quality, stream.url); - streamSegmentPlaylistUrl = stream.url; - return streamSegmentPlaylistUrl; - } - - @Override - protected HttpUriRequest createSegmentGetRequest(String url) { - return new HttpGet(url); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/http/HttpAudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/http/HttpAudioSourceManager.java deleted file mode 100644 index 146827a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/http/HttpAudioSourceManager.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.http; - -import com.sedmelluq.discord.lavaplayer.container.*; -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.ProbingAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.io.*; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoBuilder; -import org.apache.http.HttpStatus; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.HttpClientBuilder; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.function.Consumer; -import java.util.function.Function; - -import static com.sedmelluq.discord.lavaplayer.container.MediaContainerDetectionResult.refer; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.COMMON; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; -import static com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools.getHeaderValue; - -/** - * Audio source manager which implements finding audio files from HTTP addresses. - */ -public class HttpAudioSourceManager extends ProbingAudioSourceManager implements HttpConfigurable { - private final HttpInterfaceManager httpInterfaceManager; - - /** - * Create a new instance with default media container registry. - */ - public HttpAudioSourceManager() { - this(MediaContainerRegistry.DEFAULT_REGISTRY); - } - - /** - * Create a new instance. - */ - public HttpAudioSourceManager(MediaContainerRegistry containerRegistry) { - super(containerRegistry); - - httpInterfaceManager = new ThreadLocalHttpInterfaceManager( - HttpClientTools - .createSharedCookiesHttpBuilder() - .setRedirectStrategy(new HttpClientTools.NoRedirectsStrategy()), - HttpClientTools.DEFAULT_REQUEST_CONFIG - ); - } - - @Override - public String getSourceName() { - return "http"; - } - - @Override - public AudioItem loadItem(DefaultAudioPlayerManager manager, AudioReference reference) { - AudioReference httpReference = getAsHttpReference(reference); - if (httpReference == null) { - return null; - } - - if (httpReference.containerDescriptor != null) { - return createTrack(AudioTrackInfoBuilder.create(reference, null).build(), httpReference.containerDescriptor); - } else { - return handleLoadResult(detectContainer(httpReference)); - } - } - - @Override - protected AudioTrack createTrack(AudioTrackInfo trackInfo, MediaContainerDescriptor containerDescriptor) { - return new HttpAudioTrack(trackInfo, containerDescriptor, this); - } - - /** - * @return Get an HTTP interface for a playing track. - */ - public HttpInterface getHttpInterface() { - return httpInterfaceManager.getInterface(); - } - - @Override - public void configureRequests(Function configurator) { - httpInterfaceManager.configureRequests(configurator); - } - - @Override - public void configureBuilder(Consumer configurator) { - httpInterfaceManager.configureBuilder(configurator); - } - - public static AudioReference getAsHttpReference(AudioReference reference) { - if (reference.identifier.startsWith("https://") || reference.identifier.startsWith("http://")) { - return reference; - } else if (reference.identifier.startsWith("icy://")) { - return new AudioReference("http://" + reference.identifier.substring(6), reference.title); - } - return null; - } - - private MediaContainerDetectionResult detectContainer(AudioReference reference) { - MediaContainerDetectionResult result; - - try (HttpInterface httpInterface = getHttpInterface()) { - result = detectContainerWithClient(httpInterface, reference); - } catch (IOException e) { - throw new FriendlyException("Connecting to the URL failed.", SUSPICIOUS, e); - } - - return result; - } - - private MediaContainerDetectionResult detectContainerWithClient(HttpInterface httpInterface, AudioReference reference) throws IOException { - try (PersistentHttpStream inputStream = new PersistentHttpStream(httpInterface, new URI(reference.identifier), Long.MAX_VALUE)) { - int statusCode = inputStream.checkStatusCode(); - String redirectUrl = HttpClientTools.getRedirectLocation(reference.identifier, inputStream.getCurrentResponse()); - - if (redirectUrl != null) { - return refer(null, new AudioReference(redirectUrl, null)); - } else if (statusCode == HttpStatus.SC_NOT_FOUND) { - return null; - } else if (!HttpClientTools.isSuccessWithContent(statusCode)) { - throw new FriendlyException("That URL is not playable.", COMMON, new IllegalStateException("Status code " + statusCode)); - } - - MediaContainerHints hints = MediaContainerHints.from(getHeaderValue(inputStream.getCurrentResponse(), "Content-Type"), null); - return new MediaContainerDetection(containerRegistry, reference, inputStream, hints).detectContainer(); - } catch (URISyntaxException e) { - throw new FriendlyException("Not a valid URL.", COMMON, e); - } - } - - @Override - public boolean isTrackEncodable(AudioTrack track) { - return true; - } - - @Override - public void encodeTrack(AudioTrack track, DataOutput output) throws IOException { - encodeTrackFactory(((HttpAudioTrack) track).getContainerTrackFactory(), output); - } - - @Override - public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) throws IOException { - MediaContainerDescriptor containerTrackFactory = decodeTrackFactory(input); - - if (containerTrackFactory != null) { - return new HttpAudioTrack(trackInfo, containerTrackFactory, this); - } - - return null; - } - - @Override - public void shutdown() { - // Nothing to shut down - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/http/HttpAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/http/HttpAudioTrack.java deleted file mode 100644 index 6f1de55..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/http/HttpAudioTrack.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.http; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDescriptor; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.PersistentHttpStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.InternalAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.URI; - -/** - * Audio track that handles processing HTTP addresses as audio tracks. - */ -public class HttpAudioTrack extends DelegatedAudioTrack { - private static final Logger log = LoggerFactory.getLogger(HttpAudioTrack.class); - - private final MediaContainerDescriptor containerTrackFactory; - private final HttpAudioSourceManager sourceManager; - - /** - * @param trackInfo Track info - * @param containerTrackFactory Container track factory - contains the probe with its parameters. - * @param sourceManager Source manager used to load this track - */ - public HttpAudioTrack(AudioTrackInfo trackInfo, MediaContainerDescriptor containerTrackFactory, - HttpAudioSourceManager sourceManager) { - - super(trackInfo); - - this.containerTrackFactory = containerTrackFactory; - this.sourceManager = sourceManager; - } - - /** - * @return The media probe which handles creating a container-specific delegated track for this track. - */ - public MediaContainerDescriptor getContainerTrackFactory() { - return containerTrackFactory; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - try (HttpInterface httpInterface = sourceManager.getHttpInterface()) { - log.debug("Starting http track from URL: {}", trackInfo.identifier); - - try (PersistentHttpStream inputStream = new PersistentHttpStream(httpInterface, new URI(trackInfo.identifier), Long.MAX_VALUE)) { - processDelegate((InternalAudioTrack) containerTrackFactory.createTrack(trackInfo, inputStream), localExecutor); - } - } - } - - @Override - public AudioTrack makeClone() { - return new HttpAudioTrack(trackInfo, containerTrackFactory, sourceManager); - } - - @Override - public AudioSourceManager getSourceManager() { - return sourceManager; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalAudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalAudioSourceManager.java deleted file mode 100644 index 16ebc6d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalAudioSourceManager.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.local; - -import com.sedmelluq.discord.lavaplayer.container.*; -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.ProbingAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.File; -import java.io.IOException; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio source manager that implements finding audio files from the local file system. - */ -public class LocalAudioSourceManager extends ProbingAudioSourceManager { - public LocalAudioSourceManager() { - this(MediaContainerRegistry.DEFAULT_REGISTRY); - } - - public LocalAudioSourceManager(MediaContainerRegistry containerRegistry) { - super(containerRegistry); - } - - @Override - public String getSourceName() { - return "local"; - } - - @Override - public AudioItem loadItem(DefaultAudioPlayerManager manager, AudioReference reference) { - File file = new File(reference.identifier); - - if (file.exists() && file.isFile() && file.canRead()) { - return handleLoadResult(detectContainerForFile(reference, file)); - } else { - return null; - } - } - - @Override - protected AudioTrack createTrack(AudioTrackInfo trackInfo, MediaContainerDescriptor containerTrackFactory) { - return new LocalAudioTrack(trackInfo, containerTrackFactory, this); - } - - private MediaContainerDetectionResult detectContainerForFile(AudioReference reference, File file) { - try (LocalSeekableInputStream inputStream = new LocalSeekableInputStream(file)) { - int lastDotIndex = file.getName().lastIndexOf('.'); - String fileExtension = lastDotIndex >= 0 ? file.getName().substring(lastDotIndex + 1) : null; - - return new MediaContainerDetection(containerRegistry, reference, inputStream, - MediaContainerHints.from(null, fileExtension)).detectContainer(); - } catch (IOException e) { - throw new FriendlyException("Failed to open file for reading.", SUSPICIOUS, e); - } - } - - @Override - public boolean isTrackEncodable(AudioTrack track) { - return true; - } - - @Override - public void encodeTrack(AudioTrack track, DataOutput output) throws IOException { - encodeTrackFactory(((LocalAudioTrack) track).getContainerTrackFactory(), output); - } - - @Override - public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) throws IOException { - MediaContainerDescriptor containerTrackFactory = decodeTrackFactory(input); - - if (containerTrackFactory != null) { - return new LocalAudioTrack(trackInfo, containerTrackFactory, this); - } - - return null; - } - - @Override - public void shutdown() { - // Nothing to shut down - } -} \ No newline at end of file diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalAudioTrack.java deleted file mode 100644 index 07d36a2..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalAudioTrack.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.local; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDescriptor; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.InternalAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; - -import java.io.File; - -/** - * Audio track that handles processing local files as audio tracks. - */ -public class LocalAudioTrack extends DelegatedAudioTrack { - private final File file; - private final MediaContainerDescriptor containerTrackFactory; - private final LocalAudioSourceManager sourceManager; - - /** - * @param trackInfo Track info - * @param containerTrackFactory Probe track factory - contains the probe with its parameters. - * @param sourceManager Source manager used to load this track - */ - public LocalAudioTrack(AudioTrackInfo trackInfo, MediaContainerDescriptor containerTrackFactory, - LocalAudioSourceManager sourceManager) { - - super(trackInfo); - - this.file = new File(trackInfo.identifier); - this.containerTrackFactory = containerTrackFactory; - this.sourceManager = sourceManager; - } - - /** - * @return The media probe which handles creating a container-specific delegated track for this track. - */ - public MediaContainerDescriptor getContainerTrackFactory() { - return containerTrackFactory; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - try (LocalSeekableInputStream inputStream = new LocalSeekableInputStream(file)) { - processDelegate((InternalAudioTrack) containerTrackFactory.createTrack(trackInfo, inputStream), localExecutor); - } - } - - @Override - public AudioTrack makeClone() { - return new LocalAudioTrack(trackInfo, containerTrackFactory, sourceManager); - } - - @Override - public AudioSourceManager getSourceManager() { - return sourceManager; - } -} \ No newline at end of file diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalSeekableInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalSeekableInputStream.java deleted file mode 100644 index b27fad8..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/local/LocalSeekableInputStream.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.local; - -import com.sedmelluq.discord.lavaplayer.tools.io.ExtendedBufferedInputStream; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.channels.FileChannel; -import java.util.Collections; -import java.util.List; - -/** - * Seekable input stream implementation for local files. - */ -public class LocalSeekableInputStream extends SeekableInputStream { - private static final Logger log = LoggerFactory.getLogger(LocalSeekableInputStream.class); - - private final FileInputStream inputStream; - private final FileChannel channel; - private final ExtendedBufferedInputStream bufferedStream; - private long position; - - /** - * @param file File to create a stream for. - */ - public LocalSeekableInputStream(File file) { - super(file.length(), 0); - - try { - inputStream = new FileInputStream(file); - bufferedStream = new ExtendedBufferedInputStream(inputStream); - channel = inputStream.getChannel(); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } - } - - @Override - public int read() throws IOException { - int result = bufferedStream.read(); - if (result >= 0) { - position++; - } - - return result; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - int read = bufferedStream.read(b, off, len); - position += read; - return read; - } - - @Override - public long skip(long n) throws IOException { - long skipped = bufferedStream.skip(n); - position += skipped; - return skipped; - } - - @Override - public int available() throws IOException { - return bufferedStream.available(); - } - - @Override - public synchronized void reset() throws IOException { - throw new IOException("mark/reset not supported"); - } - - @Override - public boolean markSupported() { - return false; - } - - @Override - public void close() throws IOException { - try { - channel.close(); - } catch (IOException e) { - log.debug("Failed to close channel", e); - } - } - - @Override - public long getPosition() { - return position; - } - - @Override - public boolean canSeekHard() { - return true; - } - - @Override - public List getTrackInfoProviders() { - return Collections.emptyList(); - } - - @Override - protected void seekHard(long position) throws IOException { - channel.position(position); - this.position = position; - bufferedStream.discardBuffer(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/nico/NicoAudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/nico/NicoAudioSourceManager.java deleted file mode 100644 index 6815600..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/nico/NicoAudioSourceManager.java +++ /dev/null @@ -1,187 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.nico; - -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpConfigurable; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import org.apache.http.Header; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.message.BasicNameValuePair; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.parser.Parser; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.COMMON; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio source manager that implements finding NicoNico tracks based on URL. - */ -public class NicoAudioSourceManager implements AudioSourceManager, HttpConfigurable { - private static final String TRACK_URL_REGEX = "^(?:http://|https://|)(?:www\\.|)nicovideo\\.jp/watch/(sm[0-9]+)(?:\\?.*|)$"; - - private static final Pattern trackUrlPattern = Pattern.compile(TRACK_URL_REGEX); - - private final String email; - private final String password; - private final HttpInterfaceManager httpInterfaceManager; - private final AtomicBoolean loggedIn; - - /** - * @param email Site account email - * @param password Site account password - */ - public NicoAudioSourceManager(String email, String password) { - this.email = email; - this.password = password; - httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager(); - loggedIn = new AtomicBoolean(); - } - - @Override - public String getSourceName() { - return "niconico"; - } - - @Override - public AudioItem loadItem(DefaultAudioPlayerManager manager, AudioReference reference) { - Matcher trackMatcher = trackUrlPattern.matcher(reference.identifier); - - if (trackMatcher.matches()) { - return loadTrack(trackMatcher.group(1)); - } - - return null; - } - - private AudioTrack loadTrack(String videoId) { - checkLoggedIn(); - - try (HttpInterface httpInterface = getHttpInterface()) { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet("http://ext.nicovideo.jp/api/getthumbinfo/" + videoId))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Unexpected response code from video info: " + statusCode); - } - - Document document = Jsoup.parse(response.getEntity().getContent(), StandardCharsets.UTF_8.name(), "", Parser.xmlParser()); - return extractTrackFromXml(videoId, document); - } - } catch (IOException e) { - throw new FriendlyException("Error occurred when extracting video info.", SUSPICIOUS, e); - } - } - - private AudioTrack extractTrackFromXml(String videoId, Document document) { - for (Element element : document.select(":root > thumb")) { - String uploader = element.select("user_nickname").first().text(); - String title = element.select("title").first().text(); - long duration = DataFormatTools.durationTextToMillis(element.select("length").first().text()); - - return new NicoAudioTrack(new AudioTrackInfo(title, uploader, duration, videoId, false, getWatchUrl(videoId)), this); - } - - return null; - } - - @Override - public boolean isTrackEncodable(AudioTrack track) { - return true; - } - - @Override - public void encodeTrack(AudioTrack track, DataOutput output) throws IOException { - // No extra information to save - } - - @Override - public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) throws IOException { - return new NicoAudioTrack(trackInfo, this); - } - - @Override - public void shutdown() { - // Nothing to shut down - } - - /** - * @return Get an HTTP interface for a playing track. - */ - public HttpInterface getHttpInterface() { - return httpInterfaceManager.getInterface(); - } - - @Override - public void configureRequests(Function configurator) { - httpInterfaceManager.configureRequests(configurator); - } - - @Override - public void configureBuilder(Consumer configurator) { - httpInterfaceManager.configureBuilder(configurator); - } - - void checkLoggedIn() { - synchronized (loggedIn) { - if (loggedIn.get()) { - return; - } - - HttpPost loginRequest = new HttpPost("https://secure.nicovideo.jp/secure/login"); - - loginRequest.setEntity(new UrlEncodedFormEntity(Arrays.asList( - new BasicNameValuePair("mail", email), - new BasicNameValuePair("password", password) - ), StandardCharsets.UTF_8)); - - try (HttpInterface httpInterface = getHttpInterface()) { - try (CloseableHttpResponse response = httpInterface.execute(loginRequest)) { - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode != 302) { - throw new IOException("Unexpected response code " + statusCode); - } - - Header location = response.getFirstHeader("Location"); - - if (location == null || location.getValue().contains("message=")) { - throw new FriendlyException("Login details for NicoNico are invalid.", COMMON, null); - } - - loggedIn.set(true); - } - } catch (IOException e) { - throw new FriendlyException("Exception when trying to log into NicoNico", SUSPICIOUS, e); - } - } - } - - private static String getWatchUrl(String videoId) { - return "http://www.nicovideo.jp/watch/" + videoId; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/nico/NicoAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/nico/NicoAudioTrack.java deleted file mode 100644 index 0ab57fa..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/nico/NicoAudioTrack.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.nico; - -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegAudioTrack; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.PersistentHttpStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URLEncodedUtils; -import org.apache.http.util.EntityUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.Map; - -import static com.sedmelluq.discord.lavaplayer.tools.DataFormatTools.convertToMapLayout; - -/** - * Audio track that handles processing NicoNico tracks. - */ -public class NicoAudioTrack extends DelegatedAudioTrack { - private static final Logger log = LoggerFactory.getLogger(NicoAudioTrack.class); - - private final NicoAudioSourceManager sourceManager; - - /** - * @param trackInfo Track info - * @param sourceManager Source manager which was used to find this track - */ - public NicoAudioTrack(AudioTrackInfo trackInfo, NicoAudioSourceManager sourceManager) { - super(trackInfo); - - this.sourceManager = sourceManager; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - sourceManager.checkLoggedIn(); - - try (HttpInterface httpInterface = sourceManager.getHttpInterface()) { - loadVideoMainPage(httpInterface); - String playbackUrl = loadPlaybackUrl(httpInterface); - - log.debug("Starting NicoNico track from URL: {}", playbackUrl); - - try (PersistentHttpStream stream = new PersistentHttpStream(httpInterface, new URI(playbackUrl), null)) { - processDelegate(new MpegAudioTrack(trackInfo, stream), localExecutor); - } - } - } - - private void loadVideoMainPage(HttpInterface httpInterface) throws IOException { - HttpGet request = new HttpGet("http://www.nicovideo.jp/watch/" + trackInfo.identifier); - - try (CloseableHttpResponse response = httpInterface.execute(request)) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Unexpected status code from video main page: " + statusCode); - } - - EntityUtils.consume(response.getEntity()); - } - } - - private String loadPlaybackUrl(HttpInterface httpInterface) throws IOException { - HttpGet request = new HttpGet("http://flapi.nicovideo.jp/api/getflv/" + trackInfo.identifier); - - try (CloseableHttpResponse response = httpInterface.execute(request)) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Unexpected status code from playback parameters page: " + statusCode); - } - - String text = EntityUtils.toString(response.getEntity()); - Map format = convertToMapLayout(URLEncodedUtils.parse(text, StandardCharsets.UTF_8)); - - return format.get("url"); - } - } - - @Override - public AudioTrack makeClone() { - return new NicoAudioTrack(trackInfo, sourceManager); - } - - @Override - public AudioSourceManager getSourceManager() { - return sourceManager; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/soundcloud/SoundCloudAudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/soundcloud/SoundCloudAudioSourceManager.java deleted file mode 100644 index 1aaecdd..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/soundcloud/SoundCloudAudioSourceManager.java +++ /dev/null @@ -1,606 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.soundcloud; - -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpConfigurable; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.*; -import org.apache.commons.io.IOUtils; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.util.EntityUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.COMMON; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio source manager that implements finding SoundCloud tracks based on URL. - */ -public class SoundCloudAudioSourceManager implements AudioSourceManager, HttpConfigurable { - private static final Logger log = LoggerFactory.getLogger(SoundCloudAudioSourceManager.class); - - private static final int DEFAULT_SEARCH_RESULTS = 10; - private static final int MAXIMUM_SEARCH_RESULTS = 200; - - private static final long CLIENT_ID_REFRESH_INTERVAL = TimeUnit.HOURS.toMillis(1); - - private static final String CHARSET = "UTF-8"; - private static final String LATEST_CLIENT_ID = "2t9loNQH90kzJcsFCODdigxfp325aq4z"; - private static final String TRACK_URL_REGEX = "^(?:http://|https://|)(?:www\\.|)(?:m\\.|)soundcloud\\.com/([a-zA-Z0-9-_]+)/([a-zA-Z0-9-_]+)(?:\\?.*|)$"; - private static final String UNLISTED_URL_REGEX = "^(?:http://|https://|)(?:www\\.|)(?:m\\.|)soundcloud\\.com/([a-zA-Z0-9-_]+)/([a-zA-Z0-9-_]+)/s-([a-zA-Z0-9-_]+)(?:\\?.*|)$"; - private static final String PLAYLIST_URL_REGEX = "^(?:http://|https://|)(?:www\\.|)(?:m\\.|)soundcloud\\.com/([a-zA-Z0-9-_]+)/sets/([a-zA-Z0-9-_]+)(?:\\?.*|)$"; - private static final String LIKED_URL_REGEX = "^(?:http://|https://|)(?:www\\.|)(?:m\\.|)soundcloud\\.com/([a-zA-Z0-9-_]+)/likes/?(?:\\?.*|)$"; - private static final String LIKED_USER_URN_REGEX = "\"urn\":\"soundcloud:users:([0-9]+)\",\"username\":\"([^\"]+)\""; - private static final String SEARCH_PREFIX = "scsearch"; - private static final String SEARCH_PREFIX_DEFAULT = "scsearch:"; - private static final String SEARCH_REGEX = SEARCH_PREFIX + "\\[([0-9]{1,9}),([0-9]{1,9})\\]:\\s*(.*)\\s*"; - private static final String PAGE_APP_SCRIPT_REGEX = "https://[A-Za-z0-9-.]+/assets/app-[a-f0-9-]+\\.js"; - private static final String APP_SCRIPT_CLIENT_ID_REGEX = ",client_id:\"([a-zA-Z0-9-_]+)\""; - - private static final Pattern trackUrlPattern = Pattern.compile(TRACK_URL_REGEX); - private static final Pattern unlistedUrlPattern = Pattern.compile(UNLISTED_URL_REGEX); - private static final Pattern playlistUrlPattern = Pattern.compile(PLAYLIST_URL_REGEX); - private static final Pattern likedUrlPattern = Pattern.compile(LIKED_URL_REGEX); - private static final Pattern likedUserUrnPattern = Pattern.compile(LIKED_USER_URN_REGEX); - private static final Pattern searchPattern = Pattern.compile(SEARCH_REGEX); - private static final Pattern pageAppScriptPattern = Pattern.compile(PAGE_APP_SCRIPT_REGEX); - private static final Pattern appScriptClientIdPattern = Pattern.compile(APP_SCRIPT_CLIENT_ID_REGEX); - - private final HttpInterfaceManager httpInterfaceManager; - private final Object clientIdLock; - private final boolean allowSearch; - private long lastClientIdUpdate; - private volatile String clientId; - - /** - * Create an instance with default settings. - */ - public SoundCloudAudioSourceManager() { - this(true); - } - - /** - * Create an instance. - * - * @param allowSearch Whether to allow search queries as identifiers - */ - public SoundCloudAudioSourceManager(boolean allowSearch) { - httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager(); - this.allowSearch = allowSearch; - this.clientIdLock = new Object(); - this.lastClientIdUpdate = 0; - - setClientId(LATEST_CLIENT_ID); - } - - @Override - public String getSourceName() { - return "soundcloud"; - } - - @Override - public AudioItem loadItem(DefaultAudioPlayerManager manager, AudioReference reference) { - AudioItem track = processAsSingleTrack(reference); - - if (track == null) { - track = processAsPlaylist(reference); - } - - if (track == null && allowSearch) { - track = processAsSearchQuery(reference); - } - - return track; - } - - @Override - public boolean isTrackEncodable(AudioTrack track) { - return true; - } - - @Override - public void encodeTrack(AudioTrack track, DataOutput output) throws IOException { - // No extra information to save - } - - @Override - public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) throws IOException { - return new SoundCloudAudioTrack(trackInfo, this); - } - - @Override - public void shutdown() { - // Nothing to shut down - } - - /** - * @param trackId ID of the track - * @return URL to use for streaming the track. - */ - public String getTrackUrlFromId(String trackId) { - String[] parts = trackId.split("\\|"); - - if (parts.length < 2) { - return "https://api.soundcloud.com/tracks/" + trackId + "/stream?client_id=" + getClientId(); - } else { - return "https://api.soundcloud.com/tracks/" + parts[0] + "/stream?client_id=" + getClientId() + "&secret_token=" + parts[1]; - } - } - - /** - * @return Get an HTTP interface for a playing track. - */ - public HttpInterface getHttpInterface() { - return httpInterfaceManager.getInterface(); - } - - @Override - public void configureRequests(Function configurator) { - httpInterfaceManager.configureRequests(configurator); - } - - @Override - public void configureBuilder(Consumer configurator) { - httpInterfaceManager.configureBuilder(configurator); - } - - /** - * Updates the clientID if more than {@link #CLIENT_ID_REFRESH_INTERVAL} time has passed since last updated. - */ - public void updateClientId() { - synchronized (clientIdLock) { - long now = System.currentTimeMillis(); - if (now - lastClientIdUpdate < CLIENT_ID_REFRESH_INTERVAL) { - log.debug("Client ID was recently updated, not updating again right away."); - return; - } - - lastClientIdUpdate = now; - log.info("Updating SoundCloud client ID (current is {}).", clientId); - - try { - clientId = findClientIdFromSite(); - log.info("Updating SoundCloud client ID succeeded, new ID is {}.", clientId); - } catch (Exception e) { - log.error("SoundCloud client ID update failed.", e); - } - } - } - - public void setClientId(String clientId) { - synchronized (clientIdLock) { - this.clientId = clientId; - } - } - - public String getClientId() { - synchronized (clientIdLock) { - return clientId; - } - } - - private String findClientIdFromSite() throws IOException { - try (HttpInterface httpInterface = getHttpInterface()) { - String scriptUrl = findApplicationScriptUrl(httpInterface); - return findClientIdFromApplicationScript(httpInterface, scriptUrl); - } - } - - private String findApplicationScriptUrl(HttpInterface httpInterface) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet("https://soundcloud.com"))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for main page response: " + statusCode); - } - - String page = EntityUtils.toString(response.getEntity()); - Matcher scriptMatcher = pageAppScriptPattern.matcher(page); - - if (scriptMatcher.find()) { - return scriptMatcher.group(0); - } else { - throw new IllegalStateException("Could not find application script from main page."); - } - } - } - - private String findClientIdFromApplicationScript(HttpInterface httpInterface, String scriptUrl) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(scriptUrl))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for application script response: " + statusCode); - } - - String page = EntityUtils.toString(response.getEntity()); - Matcher clientIdMatcher = appScriptClientIdPattern.matcher(page); - - if (clientIdMatcher.find()) { - return clientIdMatcher.group(1); - } else { - throw new IllegalStateException("Could not find client ID from application script."); - } - } - } - - private AudioTrack processAsSingleTrack(AudioReference reference) { - String url = nonMobileUrl(reference.identifier); - - Matcher trackUrlMatcher = trackUrlPattern.matcher(url); - if (trackUrlMatcher.matches() && !"likes".equals(trackUrlMatcher.group(2))) { - return loadFromTrackPage(url, null); - } - - Matcher unlistedUrlMatcher = unlistedUrlPattern.matcher(url); - if (unlistedUrlMatcher.matches()) { - return loadFromTrackPage(url, "s-" + unlistedUrlMatcher.group(3)); - } - - return null; - } - - private AudioItem processAsPlaylist(AudioReference reference) { - String url = nonMobileUrl(reference.identifier); - - if (playlistUrlPattern.matcher(url).matches()) { - return loadFromSet(url); - } else if (likedUrlPattern.matcher(url).matches()) { - return loadFromLikedTracks(url); - } else { - return null; - } - } - - private AudioTrack loadFromTrackPage(String trackWebUrl, String secretToken) { - try (HttpInterface httpInterface = getHttpInterface()) { - JsonBrowser trackInfoJson = loadTrackInfoFromJson(loadPageConfigJson(httpInterface, trackWebUrl)); - return buildAudioTrack(trackInfoJson, secretToken); - } catch (IOException e) { - throw new FriendlyException("Loading track from SoundCloud failed.", SUSPICIOUS, e); - } - } - - private AudioTrack buildAudioTrack(JsonBrowser trackInfoJson, String secretToken) { - String trackId = trackInfoJson.get("id").text(); - - AudioTrackInfo trackInfo = new AudioTrackInfo( - trackInfoJson.get("title").text(), - trackInfoJson.get("user").get("username").text(), - trackInfoJson.get("duration").as(Integer.class), - secretToken != null ? trackId + "|" + secretToken : trackId, - false, - trackInfoJson.get("permalink_url").text() - ); - - return new SoundCloudAudioTrack(trackInfo, this); - } - - private JsonBrowser loadPageConfigJson(HttpInterface httpInterface, String url) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(url))) { - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode == HttpStatus.SC_NOT_FOUND) { - throw new FriendlyException("That track does not exist.", COMMON, null); - } else if (statusCode != HttpStatus.SC_OK) { - throw new IOException("Invalid status code for video page response: " + statusCode); - } - - String html = IOUtils.toString(response.getEntity().getContent(), Charset.forName(CHARSET)); - String configJson = DataFormatTools.extractBetween(html, "e}var c=", ",o=Date.now()"); - - if (configJson == null) { - throw new FriendlyException("This url does not appear to be a playable track.", SUSPICIOUS, null); - } - - return JsonBrowser.parse(configJson); - } - } - - private JsonBrowser loadTrackInfoFromJson(JsonBrowser json) { - for (JsonBrowser value : json.values()) { - for (JsonBrowser entry : value.safeGet("data").values()) { - if (entry.isMap() && "track".equals(entry.get("kind").text())) { - return entry; - } - } - } - - throw new IllegalStateException("Could not find track information block."); - } - - private static String nonMobileUrl(String url) { - if (url.startsWith("https://m.")) { - return "https://" + url.substring("https://m.".length()); - } else { - return url; - } - } - - private AudioPlaylist loadFromSet(String playlistWebUrl) { - try (HttpInterface httpInterface = getHttpInterface()) { - JsonBrowser playlistInfo = loadPlaylistInfoFromJson(loadPageConfigJson(httpInterface, playlistWebUrl)); - - return new BasicAudioPlaylist( - playlistInfo.get("title").text(), - loadTracksFromPlaylist(httpInterface, playlistInfo, playlistWebUrl), - null, - false - ); - } catch (IOException e) { - throw new FriendlyException("Loading playlist from SoundCloud failed.", SUSPICIOUS, e); - } - } - - private JsonBrowser loadPlaylistInfoFromJson(JsonBrowser json) { - for (JsonBrowser value : json.values()) { - for (JsonBrowser entry : value.safeGet("data").values()) { - if (entry.isMap() && "playlist".equals(entry.get("kind").text())) { - return entry; - } - } - } - - throw new IllegalStateException("Could not find playlist information block."); - } - - private List loadTracksFromPlaylist(HttpInterface httpInterface, JsonBrowser playlistInfo, String playlistWebUrl) throws IOException { - List trackIds = loadPlaylistTrackList(playlistInfo); - - return withClientIdRetry(httpInterface, - response -> handlePlaylistTracksResponse(response, playlistWebUrl, trackIds), - () -> buildTrackListUrl(trackIds) - ); - } - - private List handlePlaylistTracksResponse(HttpResponse response, String playlistWebUrl, List trackIds) throws IOException { - List tracks = new ArrayList<>(); - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for track list response: " + statusCode); - } - - JsonBrowser trackList = JsonBrowser.parse(response.getEntity().getContent()); - int blockedCount = 0; - - for (JsonBrowser trackInfoJson : trackList.values()) { - if ("BLOCK".equals(trackInfoJson.get("policy").text())) { - blockedCount++; - } else { - tracks.add(buildAudioTrack(trackInfoJson, null)); - } - } - - if (blockedCount > 0) { - log.debug("In soundcloud playlist {}, {} tracks were omitted because they are blocked.", playlistWebUrl, blockedCount); - } - - sortPlaylistTracks(tracks, trackIds); - - return tracks; - } - - private List loadPlaylistTrackList(JsonBrowser playlistInfo) { - List trackIds = new ArrayList<>(); - for (JsonBrowser trackInfo : playlistInfo.get("tracks").values()) { - trackIds.add(trackInfo.get("id").text()); - } - return trackIds; - } - - private URI buildTrackListUrl(List trackIds) { - try { - StringJoiner joiner = new StringJoiner(","); - for (String trackId : trackIds) { - joiner.add(trackId); - } - - return new URIBuilder("https://api-v2.soundcloud.com/tracks") - .addParameter("ids", joiner.toString()) - .addParameter("client_id", getClientId()) - .build(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } - - private static void sortPlaylistTracks(List tracks, List trackIds) { - final Map positions = new HashMap<>(); - for (int i = 0; i < trackIds.size(); i++) { - positions.put(trackIds.get(i), i); - } - - Collections.sort(tracks, Comparator.comparingInt(o -> getSortPosition(positions, o))); - } - - private static int getSortPosition(Map positions, AudioTrack track) { - return DataFormatTools.defaultOnNull(positions.get(track.getIdentifier()), Integer.MAX_VALUE); - } - - private AudioItem loadFromLikedTracks(String likedListUrl) { - try (HttpInterface httpInterface = getHttpInterface()) { - UserInfo userInfo = findUserIdFromLikedList(httpInterface, likedListUrl); - if (userInfo == null) { - return AudioReference.NO_TRACK; - } - - return extractTracksFromLikedList(loadLikedListForUserId(httpInterface, userInfo), userInfo); - } catch (IOException e) { - throw new FriendlyException("Loading liked tracks from SoundCloud failed.", SUSPICIOUS, e); - } - } - - private UserInfo findUserIdFromLikedList(HttpInterface httpInterface, String likedListUrl) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(likedListUrl))) { - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode == 404) { - return null; - } else if (statusCode != 200) { - throw new IOException("Invalid status code for track list response: " + statusCode); - } - - Matcher matcher = likedUserUrnPattern.matcher(IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8)); - return matcher.find() ? new UserInfo(matcher.group(1), matcher.group(2)) : null; - } - } - - private JsonBrowser loadLikedListForUserId(HttpInterface httpInterface, UserInfo userInfo) throws IOException { - return withClientIdRetry(httpInterface, response -> { - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode != 200) { - throw new IOException("Invalid status code for liked tracks response: " + statusCode); - } - - return JsonBrowser.parse(response.getEntity().getContent()); - }, () -> - new URI("https://api-v2.soundcloud.com/users/" + userInfo.id + "/likes?client_id=" + getClientId() + "&limit=200&offset=0") - ); - } - - private AudioItem extractTracksFromLikedList(JsonBrowser likedTracks, UserInfo userInfo) { - List tracks = new ArrayList<>(); - - for (JsonBrowser item : likedTracks.get("collection").values()) { - JsonBrowser trackItem = item.get("track"); - - if (!trackItem.isNull()) { - tracks.add(buildAudioTrack(trackItem, null)); - } - } - - return new BasicAudioPlaylist("Liked by " + userInfo.name, tracks, null, false); - } - - private static class UserInfo { - private final String id; - private final String name; - - private UserInfo(String id, String name) { - this.id = id; - this.name = name; - } - } - - private AudioItem processAsSearchQuery(AudioReference reference) { - if (reference.identifier.startsWith(SEARCH_PREFIX)) { - if (reference.identifier.startsWith(SEARCH_PREFIX_DEFAULT)) { - return loadSearchResult(reference.identifier.substring(SEARCH_PREFIX_DEFAULT.length()).trim(), 0, DEFAULT_SEARCH_RESULTS); - } - - Matcher searchMatcher = searchPattern.matcher(reference.identifier); - - if (searchMatcher.matches()) { - return loadSearchResult(searchMatcher.group(3), Integer.parseInt(searchMatcher.group(1)), Integer.parseInt(searchMatcher.group(2))); - } - } - - return null; - } - - private AudioItem loadSearchResult(String query, int offset, int rawLimit) { - int limit = Math.min(rawLimit, MAXIMUM_SEARCH_RESULTS); - - try (HttpInterface httpInterface = getHttpInterface()) { - return withClientIdRetry(httpInterface, - response -> loadSearchResultsFromResponse(response, query), - () -> buildSearchUri(query, offset, limit) - ); - } catch (IOException e) { - throw new FriendlyException("Loading search results from SoundCloud failed.", SUSPICIOUS, e); - } - } - - private AudioItem loadSearchResultsFromResponse(HttpResponse response, String query) throws IOException { - try { - JsonBrowser searchResults = JsonBrowser.parse(response.getEntity().getContent()); - return extractTracksFromSearchResults(query, searchResults); - } finally { - EntityUtils.consumeQuietly(response.getEntity()); - } - } - - private URI buildSearchUri(String query, int offset, int limit) { - try { - return new URIBuilder("https://api-v2.soundcloud.com/search/tracks") - .addParameter("q", query) - .addParameter("client_id", getClientId()) - .addParameter("offset", String.valueOf(offset)) - .addParameter("limit", String.valueOf(limit)) - .build(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } - - private T withClientIdRetry(HttpInterface httpInterface, ResponseHandler handler, URIProvider uriProvider) throws IOException { - try { - HttpResponse response = httpInterface.execute(new HttpGet(uriProvider.provide())); - int statusCode = response.getStatusLine().getStatusCode(); - - try { - if (statusCode != 401) { - return handler.handle(response); - } - } finally { - EntityUtils.consumeQuietly(response.getEntity()); - } - - updateClientId(); - response = httpInterface.execute(new HttpGet(uriProvider.provide())); - - try { - return handler.handle(response); - } finally { - EntityUtils.consumeQuietly(response.getEntity()); - } - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } - - private AudioItem extractTracksFromSearchResults(String query, JsonBrowser searchResults) { - List tracks = new ArrayList<>(); - - for (JsonBrowser item : searchResults.get("collection").values()) { - if (!item.isNull()) { - tracks.add(buildAudioTrack(item, null)); - } - } - - return new BasicAudioPlaylist("Search results for: " + query, tracks, null, true); - } - - private interface ResponseHandler { - T handle(HttpResponse response) throws IOException; - } - - private interface URIProvider { - URI provide() throws URISyntaxException; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/soundcloud/SoundCloudAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/soundcloud/SoundCloudAudioTrack.java deleted file mode 100644 index 6331d82..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/soundcloud/SoundCloudAudioTrack.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.soundcloud; - -import com.sedmelluq.discord.lavaplayer.container.mp3.Mp3AudioTrack; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.PersistentHttpStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; - -/** - * Audio track that handles processing SoundCloud tracks. - */ -public class SoundCloudAudioTrack extends DelegatedAudioTrack { - private static final Logger log = LoggerFactory.getLogger(SoundCloudAudioTrack.class); - - private final SoundCloudAudioSourceManager sourceManager; - - /** - * @param trackInfo Track info - * @param sourceManager Source manager which was used to find this track - */ - public SoundCloudAudioTrack(AudioTrackInfo trackInfo, SoundCloudAudioSourceManager sourceManager) { - super(trackInfo); - - this.sourceManager = sourceManager; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - try (HttpInterface httpInterface = sourceManager.getHttpInterface()) { - if (!attemptLoadStream(localExecutor, httpInterface, true)) { - sourceManager.updateClientId(); - - attemptLoadStream(localExecutor, httpInterface, false); - } - } - } - - private boolean attemptLoadStream(LocalAudioTrackExecutor localExecutor, HttpInterface httpInterface, boolean checkUnauthorized) throws Exception { - String trackUrl = sourceManager.getTrackUrlFromId(trackInfo.identifier); - log.debug("Starting SoundCloud track from URL: {}", trackUrl); - - try (PersistentHttpStream stream = new PersistentHttpStream(httpInterface, new URI(trackUrl), null)) { - if (checkUnauthorized) { - int statusCode = stream.checkStatusCode(); - - if (statusCode == 401) { - return false; - } else if (statusCode < 200 && statusCode >= 300) { - throw new IOException("Invalid status code for soundcloud stream: " + statusCode); - } - } - - processDelegate(new Mp3AudioTrack(trackInfo, stream), localExecutor); - } - - return true; - } - - @Override - public AudioTrack makeClone() { - return new SoundCloudAudioTrack(trackInfo, sourceManager); - } - - @Override - public AudioSourceManager getSourceManager() { - return sourceManager; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/ExtendedM3uParser.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/ExtendedM3uParser.java deleted file mode 100644 index 328be1d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/ExtendedM3uParser.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.stream; - -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Parser for extended M3U lines, handles the format where directives have named argumentsm, for example: - * #SOMETHING:FOO="thing",BAR=4 - */ -public class ExtendedM3uParser { - private static final Pattern directiveArgumentPattern = Pattern.compile("([A-Z-]+)=(?:\"([^\"]*)\"|([^,]*))(?:,|\\z)"); - - /** - * Parses one line. - * - * @param line Line. - * @return Line object describing the directive or data on the line. - */ - public static Line parseLine(String line) { - String trimmed = line.trim(); - - if (trimmed.isEmpty()) { - return Line.EMPTY_LINE; - } else if (!trimmed.startsWith("#")) { - return new Line(trimmed, null, Collections.emptyMap(), null); - } else { - return parseDirectiveLine(trimmed); - } - } - - private static Line parseDirectiveLine(String line) { - String[] parts = line.split(":", 2); - - if (parts.length == 1) { - return new Line(null, line.substring(1), Collections.emptyMap(), ""); - } - - Matcher matcher = directiveArgumentPattern.matcher(parts[1]); - Map arguments = new HashMap<>(); - - while (matcher.find()) { - arguments.put(matcher.group(1), DataFormatTools.defaultOnNull(matcher.group(2), matcher.group(3))); - } - - return new Line(null, parts[0].substring(1), arguments, parts[1]); - } - - /** - * Parsed extended M3U line info. May be either an empty line (isDirective() and isData() both false), a directive - * or a data line. - */ - public static class Line { - private static final Line EMPTY_LINE = new Line(null, null, null, null); - - /** - * The data of a data line. - */ - public final String lineData; - /** - * Directive name of a directive line. - */ - public final String directiveName; - /** - * Directive arguments of a directive line. - */ - public final Map directiveArguments; - /** - * Raw unprocessed directive extra data (where arguments are parsed from). - */ - public final String extraData; - - private Line(String lineData, String directiveName, Map directiveArguments, String extraData) { - this.lineData = lineData; - this.directiveName = directiveName; - this.directiveArguments = directiveArguments; - this.extraData = extraData; - } - - /** - * @return True if it is a directive line. - */ - public boolean isDirective() { - return directiveName != null; - } - - /** - * @return True if it is a data line. - */ - public boolean isData() { - return lineData != null; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/M3uStreamAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/M3uStreamAudioTrack.java deleted file mode 100644 index 388ae1f..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/M3uStreamAudioTrack.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.stream; - -import com.sedmelluq.discord.lavaplayer.container.adts.AdtsAudioTrack; -import com.sedmelluq.discord.lavaplayer.container.mpegts.MpegTsElementaryInputStream; -import com.sedmelluq.discord.lavaplayer.container.mpegts.PesPacketInputStream; -import com.sedmelluq.discord.lavaplayer.tools.io.ChainedInputStream; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; - -import static com.sedmelluq.discord.lavaplayer.container.mpegts.MpegTsElementaryInputStream.ADTS_ELEMENTARY_STREAM; - -/** - * Audio track that handles processing M3U segment streams which using MPEG-TS wrapped ADTS codec. - */ -public abstract class M3uStreamAudioTrack extends DelegatedAudioTrack { - /** - * @param trackInfo Track info - */ - public M3uStreamAudioTrack(AudioTrackInfo trackInfo) { - super(trackInfo); - } - - protected abstract M3uStreamSegmentUrlProvider getSegmentUrlProvider(); - - protected abstract HttpInterface getHttpInterface(); - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - try (final HttpInterface httpInterface = getHttpInterface()) { - try (ChainedInputStream chainedInputStream = new ChainedInputStream(() -> getSegmentUrlProvider().getNextSegmentStream(httpInterface))) { - MpegTsElementaryInputStream elementaryInputStream = new MpegTsElementaryInputStream(chainedInputStream, ADTS_ELEMENTARY_STREAM); - PesPacketInputStream pesPacketInputStream = new PesPacketInputStream(elementaryInputStream); - - processDelegate(new AdtsAudioTrack(trackInfo, pesPacketInputStream), localExecutor); - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/M3uStreamSegmentUrlProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/M3uStreamSegmentUrlProvider.java deleted file mode 100644 index f5ec1d1..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/stream/M3uStreamSegmentUrlProvider.java +++ /dev/null @@ -1,239 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.stream; - -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; -import static com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools.fetchResponseLines; - -/** - * Provides track segment URLs for streams which use the M3U segment format. There is a base M3U containing the list of - * different available streams. Those point to segment M3U urls, which always give the direct stream URLs of last X - * segments. The segment provider fetches the stream for the next segment on each call to - * {@link M3uStreamSegmentUrlProvider#getNextSegmentStream}. - */ -public abstract class M3uStreamSegmentUrlProvider { - private static final long SEGMENT_WAIT_STEP_MS = 200; - - protected SegmentInfo lastSegment; - - protected static String createSegmentUrl(String playlistUrl, String segmentName) { - return URI.create(playlistUrl).resolve(segmentName).toString(); - } - - /** - * If applicable, extracts the quality information from the M3U directive which describes one stream in the root M3U. - * - * @param directiveLine Directive line with arguments. - * @return The quality name extracted from the directive line. - */ - protected abstract String getQualityFromM3uDirective(ExtendedM3uParser.Line directiveLine); - - protected abstract String fetchSegmentPlaylistUrl(HttpInterface httpInterface) throws IOException; - - /** - * Logic for getting the URL for the next segment. - * - * @param httpInterface HTTP interface to use for any requests required to perform to find the segment URL. - * @return The direct stream URL of the next segment. - */ - protected String getNextSegmentUrl(HttpInterface httpInterface) { - try { - String streamSegmentPlaylistUrl = fetchSegmentPlaylistUrl(httpInterface); - if (streamSegmentPlaylistUrl == null) { - return null; - } - - long startTime = System.currentTimeMillis(); - SegmentInfo nextSegment; - - while (true) { - List segments = loadStreamSegmentsList(httpInterface, streamSegmentPlaylistUrl); - nextSegment = chooseNextSegment(segments, lastSegment); - - if (nextSegment != null || !shouldWaitForSegment(startTime, segments)) { - break; - } - - Thread.sleep(SEGMENT_WAIT_STEP_MS); - } - - if (nextSegment == null) { - return null; - } - - lastSegment = nextSegment; - return createSegmentUrl(streamSegmentPlaylistUrl, lastSegment.url); - } catch (IOException e) { - throw new FriendlyException("Failed to get next part of the stream.", SUSPICIOUS, e); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - /** - * Fetches the input stream for the next segment in the M3U stream. - * - * @param httpInterface HTTP interface to use for any requests required to perform to find the segment URL. - * @return Input stream of the next segment. - */ - public InputStream getNextSegmentStream(HttpInterface httpInterface) { - String url = getNextSegmentUrl(httpInterface); - if (url == null) { - return null; - } - - CloseableHttpResponse response = null; - boolean success = false; - - try { - response = httpInterface.execute(createSegmentGetRequest(url)); - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode != 200) { - throw new IOException("Invalid status code from segment data URL: " + statusCode); - } - - success = true; - return response.getEntity().getContent(); - } catch (IOException e) { - throw new RuntimeException(e); - } finally { - if (response != null && !success) { - ExceptionTools.closeWithWarnings(response); - } - } - } - - protected abstract HttpUriRequest createSegmentGetRequest(String url); - - protected List loadChannelStreamsList(String[] lines) { - ExtendedM3uParser.Line streamInfoLine = null; - - List streams = new ArrayList<>(); - - for (String lineText : lines) { - ExtendedM3uParser.Line line = ExtendedM3uParser.parseLine(lineText); - - if (line.isData() && streamInfoLine != null) { - String quality = getQualityFromM3uDirective(streamInfoLine); - if (quality != null) { - streams.add(new ChannelStreamInfo(quality, line.lineData)); - } - - streamInfoLine = null; - } else if (line.isDirective() && "EXT-X-STREAM-INF".equals(line.directiveName)) { - streamInfoLine = line; - } - } - - return streams; - } - - protected List loadStreamSegmentsList(HttpInterface httpInterface, String streamSegmentPlaylistUrl) throws IOException { - List segments = new ArrayList<>(); - ExtendedM3uParser.Line segmentInfo = null; - - for (String lineText : fetchResponseLines(httpInterface, new HttpGet(streamSegmentPlaylistUrl), "stream segments list")) { - ExtendedM3uParser.Line line = ExtendedM3uParser.parseLine(lineText); - - if (line.isDirective() && "EXTINF".equals(line.directiveName)) { - segmentInfo = line; - } - - if (line.isData()) { - if (segmentInfo != null && segmentInfo.extraData.contains(",")) { - String[] fields = segmentInfo.extraData.split(",", 2); - segments.add(new SegmentInfo(line.lineData, parseSecondDuration(fields[0]), fields[1])); - } else { - segments.add(new SegmentInfo(line.lineData, null, null)); - } - } - } - - return segments; - } - - private static Long parseSecondDuration(String value) { - try { - double asDouble = Double.parseDouble(value); - return (long) (asDouble * 1000.0); - } catch (NumberFormatException ignored) { - return null; - } - } - - protected SegmentInfo chooseNextSegment(List segments, SegmentInfo lastSegment) { - SegmentInfo selected = null; - - for (int i = segments.size() - 1; i >= 0; i--) { - SegmentInfo current = segments.get(i); - if (lastSegment != null && current.url.equals(lastSegment.url)) { - break; - } - - selected = current; - } - - return selected; - } - - private boolean shouldWaitForSegment(long startTime, List segments) { - if (!segments.isEmpty()) { - SegmentInfo sampleSegment = segments.get(0); - - if (sampleSegment.duration != null) { - return System.currentTimeMillis() - startTime < sampleSegment.duration; - } - } - - return false; - } - - protected static class ChannelStreamInfo { - /** - * Stream quality extracted from stream M3U directive. - */ - public final String quality; - /** - * URL for stream segment list. - */ - public final String url; - - private ChannelStreamInfo(String quality, String url) { - this.quality = quality; - this.url = url; - } - } - - protected static class SegmentInfo { - /** - * URL of the segment. - */ - public final String url; - /** - * Duration of the segment in milliseconds. null if unknown. - */ - public final Long duration; - /** - * Name of the segment. null if unknown. - */ - public final String name; - - public SegmentInfo(String url, Long duration, String name) { - this.url = url; - this.duration = duration; - this.name = name; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamAudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamAudioSourceManager.java deleted file mode 100644 index 3f15942..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamAudioSourceManager.java +++ /dev/null @@ -1,191 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.twitch; - -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpConfigurable; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.impl.client.HttpClientBuilder; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.net.URI; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio source manager which detects Twitch tracks by URL. - */ -public class TwitchStreamAudioSourceManager implements AudioSourceManager, HttpConfigurable { - private static final String STREAM_NAME_REGEX = "^https://(?:www\\.|go\\.)?twitch.tv/([^/]+)$"; - private static final Pattern streamNameRegex = Pattern.compile(STREAM_NAME_REGEX); - - public static final String DEFAULT_CLIENT_ID = "jzkbprff40iqj646a697cyrvl0zt2m6"; - - private final HttpInterfaceManager httpInterfaceManager; - private final String twitchClientId; - - /** - * Create an instance. - */ - public TwitchStreamAudioSourceManager() { - this(DEFAULT_CLIENT_ID); - } - - /** - * Create an instance. - * - * @param clientId The Twitch client id for your application. - */ - public TwitchStreamAudioSourceManager(String clientId) { - httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager(); - twitchClientId = clientId; - } - - public String getClientId() { - return twitchClientId; - } - - @Override - public String getSourceName() { - return "twitch"; - } - - @Override - public AudioItem loadItem(DefaultAudioPlayerManager manager, AudioReference reference) { - String streamName = getChannelIdentifierFromUrl(reference.identifier); - if (streamName == null) { - return null; - } - - JsonBrowser channelInfo = fetchStreamChannelInfo(streamName); - - if (channelInfo == null) { - return AudioReference.NO_TRACK; - } else { - //Use the stream name as the display name (we would require an additional call to the user to get the true display name) - String displayName = streamName; - - //Retrieve the data value list; this will have only one element since we're getting only one stream's information - List dataList = channelInfo.get("data").values(); - - //The value list is empty if the stream is offline, even when hosting another channel - if (dataList.size() == 0) { - return null; - } - - //The first one has the title of the broadcast - JsonBrowser channelData = dataList.get(0); - String status = channelData.get("title").text(); - - return new TwitchStreamAudioTrack(new AudioTrackInfo( - status, - displayName, - Long.MAX_VALUE, - reference.identifier, - true, - reference.identifier - ), this); - } - } - - @Override - public boolean isTrackEncodable(AudioTrack track) { - return true; - } - - @Override - public void encodeTrack(AudioTrack track, DataOutput output) throws IOException { - // Nothing special to do, URL (identifier) is enough - } - - @Override - public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) throws IOException { - return new TwitchStreamAudioTrack(trackInfo, this); - } - - /** - * Extract channel identifier from a channel URL. - * - * @param url Channel URL - * @return Channel identifier (for API requests) - */ - public static String getChannelIdentifierFromUrl(String url) { - Matcher matcher = streamNameRegex.matcher(url); - if (!matcher.matches()) { - return null; - } - - return matcher.group(1); - } - - /** - * @param url Request URL - * @return Request with necessary headers attached. - */ - public HttpUriRequest createGetRequest(String url) { - return addClientHeaders(new HttpGet(url), twitchClientId); - } - - /** - * @param url Request URL - * @return Request with necessary headers attached. - */ - public HttpUriRequest createGetRequest(URI url) { - return addClientHeaders(new HttpGet(url), twitchClientId); - } - - /** - * @return Get an HTTP interface for a playing track. - */ - public HttpInterface getHttpInterface() { - return httpInterfaceManager.getInterface(); - } - - @Override - public void configureRequests(Function configurator) { - httpInterfaceManager.configureRequests(configurator); - } - - @Override - public void configureBuilder(Consumer configurator) { - httpInterfaceManager.configureBuilder(configurator); - } - - private static HttpUriRequest addClientHeaders(HttpUriRequest request, String clientId) { - request.setHeader("Client-ID", clientId); - return request; - } - - private JsonBrowser fetchStreamChannelInfo(String name) { - try (HttpInterface httpInterface = getHttpInterface()) { - HttpUriRequest request = createGetRequest("https://api.twitch.tv/helix/streams?user_login=" + name); - - return HttpClientTools.fetchResponseAsJson(httpInterface, request); - } catch (IOException e) { - throw new FriendlyException("Loading Twitch channel information failed.", SUSPICIOUS, e); - } - } - - @Override - public void shutdown() { - ExceptionTools.closeWithWarnings(httpInterfaceManager); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamAudioTrack.java deleted file mode 100644 index a88e78a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamAudioTrack.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.twitch; - -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.stream.M3uStreamAudioTrack; -import com.sedmelluq.discord.lavaplayer.source.stream.M3uStreamSegmentUrlProvider; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager.getChannelIdentifierFromUrl; - -/** - * Audio track that handles processing Twitch tracks. - */ -public class TwitchStreamAudioTrack extends M3uStreamAudioTrack { - private static final Logger log = LoggerFactory.getLogger(TwitchStreamAudioTrack.class); - - private final TwitchStreamAudioSourceManager sourceManager; - private final M3uStreamSegmentUrlProvider segmentUrlProvider; - - /** - * @param trackInfo Track info - * @param sourceManager Source manager which was used to find this track - */ - public TwitchStreamAudioTrack(AudioTrackInfo trackInfo, TwitchStreamAudioSourceManager sourceManager) { - super(trackInfo); - - this.sourceManager = sourceManager; - this.segmentUrlProvider = new TwitchStreamSegmentUrlProvider(getChannelName(), sourceManager); - } - - /** - * @return Name of the channel of the stream. - */ - public String getChannelName() { - return getChannelIdentifierFromUrl(trackInfo.identifier); - } - - @Override - protected M3uStreamSegmentUrlProvider getSegmentUrlProvider() { - return segmentUrlProvider; - } - - @Override - protected HttpInterface getHttpInterface() { - return sourceManager.getHttpInterface(); - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - log.debug("Starting to play Twitch channel {}.", getChannelName()); - - super.process(localExecutor); - } - - @Override - public AudioTrack makeClone() { - return new TwitchStreamAudioTrack(trackInfo, sourceManager); - } - - @Override - public AudioSourceManager getSourceManager() { - return sourceManager; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamSegmentUrlProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamSegmentUrlProvider.java deleted file mode 100644 index f4223cf..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/twitch/TwitchStreamSegmentUrlProvider.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.twitch; - -import com.sedmelluq.discord.lavaplayer.source.stream.ExtendedM3uParser; -import com.sedmelluq.discord.lavaplayer.source.stream.M3uStreamSegmentUrlProvider; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.utils.URIBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; - -/** - * Provider for Twitch segment URLs from a channel. - */ -public class TwitchStreamSegmentUrlProvider extends M3uStreamSegmentUrlProvider { - private static final String TOKEN_PARAMETER = "token"; - - private static final Logger log = LoggerFactory.getLogger(TwitchStreamSegmentUrlProvider.class); - - private final String channelName; - private final TwitchStreamAudioSourceManager manager; - - private String streamSegmentPlaylistUrl; - private long tokenExpirationTime; - - /** - * @param channelName Channel identifier. - * @param manager Twitch source manager. - */ - public TwitchStreamSegmentUrlProvider(String channelName, TwitchStreamAudioSourceManager manager) { - this.channelName = channelName; - this.manager = manager; - this.tokenExpirationTime = -1; - } - - @Override - protected String getQualityFromM3uDirective(ExtendedM3uParser.Line directiveLine) { - return directiveLine.directiveArguments.get("VIDEO"); - } - - @Override - protected String fetchSegmentPlaylistUrl(HttpInterface httpInterface) throws IOException { - if (System.currentTimeMillis() < tokenExpirationTime) { - return streamSegmentPlaylistUrl; - } - - JsonBrowser token = loadAccessToken(httpInterface); - HttpUriRequest request = new HttpGet(getChannelStreamsUrl(token).toString()); - ChannelStreams streams = loadChannelStreamsInfo(HttpClientTools.fetchResponseLines(httpInterface, request, "channel streams list")); - - if (streams.entries.isEmpty()) { - throw new IllegalStateException("No streams available on channel."); - } - - ChannelStreamInfo stream = streams.entries.get(0); - - log.debug("Chose stream with quality {} from url {}", stream.quality, stream.url); - streamSegmentPlaylistUrl = stream.url; - - long tokenServerExpirationTime = JsonBrowser.parse(token.get(TOKEN_PARAMETER).text()).get("expires").as(Long.class) * 1000L; - tokenExpirationTime = System.currentTimeMillis() + (tokenServerExpirationTime - streams.serverTime) - 5000; - - return streamSegmentPlaylistUrl; - } - - @Override - protected HttpUriRequest createSegmentGetRequest(String url) { - return manager.createGetRequest(url); - } - - private JsonBrowser loadAccessToken(HttpInterface httpInterface) throws IOException { - HttpUriRequest request = createSegmentGetRequest("https://api.twitch.tv/api/channels/" + channelName + - "/access_token?adblock=false&need_https=true&platform=web&player_type=site"); - - try (CloseableHttpResponse response = httpInterface.execute(request)) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Unexpected response code from access token request: " + statusCode); - } - - return JsonBrowser.parse(response.getEntity().getContent()); - } - } - - private ChannelStreams loadChannelStreamsInfo(String[] lines) { - List streams = loadChannelStreamsList(lines); - ExtendedM3uParser.Line twitchInfoLine = null; - - for (String lineText : lines) { - ExtendedM3uParser.Line line = ExtendedM3uParser.parseLine(lineText); - - if (line.isDirective() && "EXT-X-TWITCH-INFO".equals(line.directiveName)) { - twitchInfoLine = line; - } - } - - return buildChannelStreamsInfo(twitchInfoLine, streams); - } - - private ChannelStreams buildChannelStreamsInfo(ExtendedM3uParser.Line twitchInfoLine, List streams) { - String serverTimeValue = twitchInfoLine != null ? twitchInfoLine.directiveArguments.get("SERVER-TIME") : null; - - if (serverTimeValue == null) { - throw new IllegalStateException("Required server time information not available."); - } - - return new ChannelStreams( - (long) (Double.valueOf(serverTimeValue) * 1000.0), - streams - ); - } - - private URI getChannelStreamsUrl(JsonBrowser token) { - try { - return new URIBuilder("https://usher.ttvnw.net/api/channel/hls/" + channelName + ".m3u8") - .addParameter(TOKEN_PARAMETER, token.get(TOKEN_PARAMETER).text()) - .addParameter("sig", token.get("sig").text()) - .addParameter("allow_source", "true") - .addParameter("allow_spectre", "true") - .addParameter("player_backend", "html5") - .addParameter("expgroup", "regular") - .build(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } - - private static class ChannelStreams { - private final long serverTime; - private final List entries; - - private ChannelStreams(long serverTime, List entries) { - this.serverTime = serverTime; - this.entries = entries; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/vimeo/VimeoAudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/vimeo/VimeoAudioSourceManager.java deleted file mode 100644 index d96b976..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/vimeo/VimeoAudioSourceManager.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.vimeo; - -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpConfigurable; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import org.apache.commons.io.IOUtils; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.HttpClientBuilder; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.regex.Pattern; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio source manager which detects Vimeo tracks by URL. - */ -public class VimeoAudioSourceManager implements AudioSourceManager, HttpConfigurable { - private static final String TRACK_URL_REGEX = "^https://vimeo.com/[0-9]+(?:\\?.*|)$"; - private static final Pattern trackUrlPattern = Pattern.compile(TRACK_URL_REGEX); - - private final HttpInterfaceManager httpInterfaceManager; - - /** - * Create an instance. - */ - public VimeoAudioSourceManager() { - httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager(); - } - - @Override - public String getSourceName() { - return "vimeo"; - } - - @Override - public AudioItem loadItem(DefaultAudioPlayerManager manager, AudioReference reference) { - if (!trackUrlPattern.matcher(reference.identifier).matches()) { - return null; - } - - try (HttpInterface httpInterface = httpInterfaceManager.getInterface()) { - return loadFromTrackPage(httpInterface, reference.identifier); - } catch (IOException e) { - throw new FriendlyException("Loading Vimeo track information failed.", SUSPICIOUS, e); - } - } - - @Override - public boolean isTrackEncodable(AudioTrack track) { - return true; - } - - @Override - public void encodeTrack(AudioTrack track, DataOutput output) throws IOException { - // Nothing special to encode - } - - @Override - public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) throws IOException { - return new VimeoAudioTrack(trackInfo, this); - } - - @Override - public void shutdown() { - ExceptionTools.closeWithWarnings(httpInterfaceManager); - } - - /** - * @return Get an HTTP interface for a playing track. - */ - public HttpInterface getHttpInterface() { - return httpInterfaceManager.getInterface(); - } - - @Override - public void configureRequests(Function configurator) { - httpInterfaceManager.configureRequests(configurator); - } - - @Override - public void configureBuilder(Consumer configurator) { - httpInterfaceManager.configureBuilder(configurator); - } - - JsonBrowser loadConfigJsonFromPageContent(String content) throws IOException { - String configText = DataFormatTools.extractBetween(content, "window.vimeo.clip_page_config = ", "\n"); - - if (configText != null) { - return JsonBrowser.parse(configText); - } - - return null; - } - - private AudioItem loadFromTrackPage(HttpInterface httpInterface, String trackUrl) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(trackUrl))) { - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode == 404) { - return AudioReference.NO_TRACK; - } else if (statusCode != 200) { - throw new FriendlyException("Server responded with an error.", SUSPICIOUS, - new IllegalStateException("Response code is " + statusCode)); - } - - return loadTrackFromPageContent(trackUrl, IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8)); - } - } - - private AudioTrack loadTrackFromPageContent(String trackUrl, String content) throws IOException { - JsonBrowser config = loadConfigJsonFromPageContent(content); - - if (config == null) { - throw new FriendlyException("Track information not found on the page.", SUSPICIOUS, null); - } - - return new VimeoAudioTrack(new AudioTrackInfo( - config.get("clip").get("title").text(), - config.get("owner").get("display_name").text(), - (long) (config.get("clip").get("duration").get("raw").as(Double.class) * 1000.0), - trackUrl, - false, - trackUrl - ), this); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/vimeo/VimeoAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/vimeo/VimeoAudioTrack.java deleted file mode 100644 index 572c928..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/vimeo/VimeoAudioTrack.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.vimeo; - -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegAudioTrack; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.PersistentHttpStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.apache.commons.io.IOUtils; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio track that handles processing Vimeo tracks. - */ -public class VimeoAudioTrack extends DelegatedAudioTrack { - private static final Logger log = LoggerFactory.getLogger(VimeoAudioTrack.class); - - private final VimeoAudioSourceManager sourceManager; - - /** - * @param trackInfo Track info - * @param sourceManager Source manager which was used to find this track - */ - public VimeoAudioTrack(AudioTrackInfo trackInfo, VimeoAudioSourceManager sourceManager) { - super(trackInfo); - - this.sourceManager = sourceManager; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - try (HttpInterface httpInterface = sourceManager.getHttpInterface()) { - String playbackUrl = loadPlaybackUrl(httpInterface); - - log.debug("Starting Vimeo track from URL: {}", playbackUrl); - - try (PersistentHttpStream stream = new PersistentHttpStream(httpInterface, new URI(playbackUrl), null)) { - processDelegate(new MpegAudioTrack(trackInfo, stream), localExecutor); - } - } - } - - private String loadPlaybackUrl(HttpInterface httpInterface) throws IOException { - JsonBrowser config = loadPlayerConfig(httpInterface); - if (config == null) { - throw new FriendlyException("Track information not present on the page.", SUSPICIOUS, null); - } - - String trackConfigUrl = config.get("player").get("config_url").text(); - JsonBrowser trackConfig = loadTrackConfig(httpInterface, trackConfigUrl); - - return trackConfig.get("request").get("files").get("progressive").index(0).get("url").text(); - } - - private JsonBrowser loadPlayerConfig(HttpInterface httpInterface) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(trackInfo.identifier))) { - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode != 200) { - throw new FriendlyException("Server responded with an error.", SUSPICIOUS, - new IllegalStateException("Response code for player config is " + statusCode)); - } - - return sourceManager.loadConfigJsonFromPageContent(IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8)); - } - } - - private JsonBrowser loadTrackConfig(HttpInterface httpInterface, String trackAccessInfoUrl) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(trackAccessInfoUrl))) { - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode != 200) { - throw new FriendlyException("Server responded with an error.", SUSPICIOUS, - new IllegalStateException("Response code for track access info is " + statusCode)); - } - - return JsonBrowser.parse(response.getEntity().getContent()); - } - } - - @Override - public AudioTrack makeClone() { - return new VimeoAudioTrack(trackInfo, sourceManager); - } - - @Override - public AudioSourceManager getSourceManager() { - return sourceManager; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeAudioSourceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeAudioSourceManager.java deleted file mode 100644 index cc919da..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeAudioSourceManager.java +++ /dev/null @@ -1,566 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpConfigurable; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.*; -import org.apache.commons.io.IOUtils; -import org.apache.http.NameValuePair; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.client.utils.URLEncodedUtils; -import org.apache.http.impl.client.HttpClientBuilder; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import static com.sedmelluq.discord.lavaplayer.tools.DataFormatTools.convertToMapLayout; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.*; - -/** - * Audio source manager that implements finding Youtube videos or playlists based on an URL or ID. - */ -public class YoutubeAudioSourceManager implements AudioSourceManager, HttpConfigurable { - private static final Logger log = LoggerFactory.getLogger(YoutubeAudioSourceManager.class); - static final String CHARSET = "UTF-8"; - - private static final String PROTOCOL_REGEX = "(?:http://|https://|)"; - private static final String DOMAIN_REGEX = "(?:www\\.|m\\.|music\\.|)youtube\\.com"; - private static final String SHORT_DOMAIN_REGEX = "(?:www\\.|)youtu\\.be"; - private static final String VIDEO_ID_REGEX = "(?[a-zA-Z0-9_-]{11})"; - private static final String PLAYLIST_ID_REGEX = "(?(PL|LL|FL|UU)[a-zA-Z0-9_-]+)"; - - private static final String SEARCH_PREFIX = "ytsearch:"; - - private static final Pattern directVideoIdPattern = Pattern.compile("^" + VIDEO_ID_REGEX + "$"); - - private final Extractor[] extractors = new Extractor[]{ - new Extractor(directVideoIdPattern, id -> loadTrackWithVideoId(id, false)), - new Extractor(Pattern.compile("^" + PLAYLIST_ID_REGEX + "$"), id -> loadPlaylistWithId(id, null)), - new Extractor(Pattern.compile("^" + PROTOCOL_REGEX + DOMAIN_REGEX + "/.*"), this::loadFromMainDomain), - new Extractor(Pattern.compile("^" + PROTOCOL_REGEX + SHORT_DOMAIN_REGEX + "/.*"), this::loadFromShortDomain) - }; - - private final YoutubeSignatureCipherManager signatureCipherManager; - private final HttpInterfaceManager httpInterfaceManager; - private final YoutubeSearchProvider searchProvider; - private final YoutubeMixProvider mixProvider; - private final boolean allowSearch; - private volatile int playlistPageCount; - - /** - * Create an instance with default settings. - */ - public YoutubeAudioSourceManager() { - this(true); - } - - /** - * Create an instance. - * - * @param allowSearch Whether to allow search queries as identifiers - */ - public YoutubeAudioSourceManager(boolean allowSearch) { - signatureCipherManager = new YoutubeSignatureCipherManager(); - httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager(); - this.allowSearch = allowSearch; - playlistPageCount = 6; - searchProvider = new YoutubeSearchProvider(this); - mixProvider = new YoutubeMixProvider(this); - } - - /** - * @param playlistPageCount Maximum number of pages loaded from one playlist. There are 100 tracks per page. - */ - public void setPlaylistPageCount(int playlistPageCount) { - this.playlistPageCount = playlistPageCount; - } - - /** - * @param maximumPoolSize Maximum number of threads in mix loader thread pool. - */ - public void setMixLoaderMaximumPoolSize(int maximumPoolSize) { - mixProvider.setLoaderMaximumPoolSize(maximumPoolSize); - } - - @Override - public String getSourceName() { - return "youtube"; - } - - @Override - public AudioItem loadItem(DefaultAudioPlayerManager manager, AudioReference reference) { - try { - return loadItemOnce(reference); - } catch (FriendlyException exception) { - // In case of a connection reset exception, try once more. - if (HttpClientTools.isRetriableNetworkException(exception.getCause())) { - return loadItemOnce(reference); - } else { - throw exception; - } - } - } - - @Override - public boolean isTrackEncodable(AudioTrack track) { - return true; - } - - @Override - public void encodeTrack(AudioTrack track, DataOutput output) { - // No custom values that need saving - } - - @Override - public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) { - return new YoutubeAudioTrack(trackInfo, this); - } - - @Override - public void shutdown() { - ExceptionTools.closeWithWarnings(httpInterfaceManager); - - mixProvider.shutdown(); - } - - public YoutubeSignatureCipherManager getCipherManager() { - return signatureCipherManager; - } - - /** - * @return Get an HTTP interface for a playing track. - */ - public HttpInterface getHttpInterface() { - return httpInterfaceManager.getInterface(); - } - - @Override - public void configureRequests(Function configurator) { - httpInterfaceManager.configureRequests(configurator); - searchProvider.configureRequests(configurator); - } - - @Override - public void configureBuilder(Consumer configurator) { - httpInterfaceManager.configureBuilder(configurator); - searchProvider.configureBuilder(configurator); - } - - private AudioItem loadItemOnce(AudioReference reference) { - if (allowSearch && reference.identifier.startsWith(SEARCH_PREFIX)) { - return searchProvider.loadSearchResult(reference.identifier.substring(SEARCH_PREFIX.length()).trim()); - } - - return loadNonSearch(reference.identifier); - } - - /** - * Loads a single track from video ID. - * - * @param videoId ID of the YouTube video. - * @param mustExist True if it should throw an exception on missing track, otherwise returns AudioReference.NO_TRACK. - * @return Loaded YouTube track. - */ - public AudioItem loadTrackWithVideoId(String videoId, boolean mustExist) { - try (HttpInterface httpInterface = getHttpInterface()) { - JsonBrowser info = getTrackInfoFromMainPage(httpInterface, videoId, mustExist); - if (info == null) { - return AudioReference.NO_TRACK; - } - - JsonBrowser args = info.get("args"); - - if ("fail".equals(args.get("status").text())) { - throw new FriendlyException(args.get("reason").text(), COMMON, null); - } - - boolean isStream = "1".equals(args.get("live_playback").text()); - long duration = isStream ? Long.MAX_VALUE : args.get("length_seconds").as(Long.class) * 1000; - - return buildTrackObject(videoId, args.get("title").text(), args.get("author").text(), isStream, duration); - } catch (Exception e) { - throw ExceptionTools.wrapUnfriendlyExceptions("Loading information for a YouTube track failed.", FAULT, e); - } - } - - /** - * @param tracks List of tracks to search from. - * @param selectedVideoId Selected track identifier. - * @return The selected track from the track list, or null if it is not present. - */ - public AudioTrack findSelectedTrack(List tracks, String selectedVideoId) { - if (selectedVideoId != null) { - for (AudioTrack track : tracks) { - if (selectedVideoId.equals(track.getIdentifier())) { - return track; - } - } - } - return null; - } - - private AudioItem loadFromMainDomain(String identifier) { - UrlInfo urlInfo = getUrlInfo(identifier, true); - - if ("/watch".equals(urlInfo.path)) { - String videoId = urlInfo.parameters.get("v"); - - if (videoId != null) { - return loadFromUrlWithVideoId(videoId, urlInfo); - } - } else if ("/playlist".equals(urlInfo.path)) { - String playlistId = urlInfo.parameters.get("list"); - - if (playlistId != null) { - return loadPlaylistWithId(playlistId, null); - } - } else if ("/watch_videos".equals(urlInfo.path)) { - String videoIds = urlInfo.parameters.get("video_ids"); - if (videoIds != null) { - return loadAnonymous(videoIds); - } - } - - return null; - } - - private AudioItem loadAnonymous(String videoIds) { - try (HttpInterface httpInterface = getHttpInterface()) { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet("https://www.youtube.com/watch_videos?video_ids=" + videoIds))) { - int statusCode = response.getStatusLine().getStatusCode(); - HttpClientContext context = httpInterface.getContext(); - if (statusCode != 200) { - throw new IOException("Invalid status code for playlist response: " + statusCode); - } - // youtube currently transforms watch_video links into a link with a video id and a list id. - // because thats what happens, we can simply re-process with the redirected link - List redirects = context.getRedirectLocations(); - if (redirects != null && !redirects.isEmpty()) { - return loadNonSearch(redirects.get(0).toString()); - } else { - throw new FriendlyException("Unable to process youtube watch_videos link", SUSPICIOUS, - new IllegalStateException("Expected youtube to redirect watch_videos link to a watch?v={id}&list={list_id} link, but it did not redirect at all")); - } - } - } catch (Exception e) { - throw ExceptionTools.wrapUnfriendlyExceptions(e); - } - } - - private AudioItem loadFromShortDomain(String identifier) { - UrlInfo urlInfo = getUrlInfo(identifier, true); - return loadFromUrlWithVideoId(urlInfo.path.substring(1), urlInfo); - } - - private AudioItem loadFromUrlWithVideoId(String videoId, UrlInfo urlInfo) { - if (videoId.length() > 11) { - // YouTube allows extra junk in the end, it redirects to the correct video. - videoId = videoId.substring(0, 11); - } - - if (!directVideoIdPattern.matcher(videoId).matches()) { - return AudioReference.NO_TRACK; - } else if (urlInfo.parameters.containsKey("list")) { - String playlistId = urlInfo.parameters.get("list"); - - if (playlistId.startsWith("RD")) { - return mixProvider.loadMixWithId(playlistId, videoId); - } else { - return loadLinkedPlaylistWithId(urlInfo.parameters.get("list"), videoId); - } - } else { - return loadTrackWithVideoId(videoId, false); - } - } - - private AudioItem loadNonSearch(String identifier) { - for (Extractor extractor : extractors) { - if (extractor.pattern.matcher(identifier).matches()) { - AudioItem item = extractor.loader.apply(identifier); - - if (item != null) { - return item; - } - } - } - - return null; - } - - private AudioItem loadLinkedPlaylistWithId(String playlistId, String videoId) { - AudioPlaylist playlist = loadPlaylistWithId(playlistId, videoId); - - if (playlist == null) { - return loadTrackWithVideoId(videoId, false); - } else { - return playlist; - } - } - - /** - * @param httpInterface HTTP interface to use for performing any necessary request. - * @param videoId ID of the video. - * @param mustExist If true, throws an exception instead of returning null if the track does - * not exist. - * @return JSON information about the track if it exists. null if it does not and mustExist is - * false. - * @throws IOException On network error. - */ - public JsonBrowser getTrackInfoFromMainPage(HttpInterface httpInterface, String videoId, boolean mustExist) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(getWatchUrl(videoId)))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for video page response: " + statusCode); - } - - String html = IOUtils.toString(response.getEntity().getContent(), Charset.forName(CHARSET)); - String configJson = DataFormatTools.extractBetween(html, "ytplayer.config = ", ";ytplayer.load"); - - if (configJson != null) { - return JsonBrowser.parse(configJson); - } - } - - if (determineFailureReason(httpInterface, videoId, mustExist)) { - return null; - } - - // In case main page does not give player configuration, but info page indicates an OK result, it is probably an - // age-restricted video for which the complete track info can be combined from the embed page and the info page. - return getTrackInfoFromEmbedPage(httpInterface, videoId); - } - - private boolean determineFailureReason(HttpInterface httpInterface, String videoId, boolean mustExist) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet("https://www.youtube.com/get_video_info?hl=en_GB&video_id=" + videoId))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for video info response: " + statusCode); - } - - Map format = convertToMapLayout(URLEncodedUtils.parse(response.getEntity())); - return determineFailureReasonFromStatus(format.get("status"), format.get("reason"), mustExist); - } - } - - private boolean determineFailureReasonFromStatus(String status, String reason, boolean mustExist) { - if ("fail".equals(status)) { - if (("This video does not exist.".equals(reason) || "This video is unavailable.".equals(reason)) && !mustExist) { - return true; - } else if (reason != null) { - throw new FriendlyException(reason, COMMON, null); - } - } else if ("ok".equals(status)) { - return false; - } - - throw new FriendlyException("Track is unavailable for an unknown reason.", SUSPICIOUS, - new IllegalStateException("Main page had no video, but video info has no error.")); - } - - private JsonBrowser getTrackInfoFromEmbedPage(HttpInterface httpInterface, String videoId) throws IOException { - JsonBrowser basicInfo = loadTrackBaseInfoFromEmbedPage(httpInterface, videoId); - basicInfo.put("args", loadTrackArgsFromVideoInfoPage(httpInterface, videoId, basicInfo.get("sts").text())); - return basicInfo; - } - - private JsonBrowser loadTrackBaseInfoFromEmbedPage(HttpInterface httpInterface, String videoId) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet("https://www.youtube.com/embed/" + videoId))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for embed video page response: " + statusCode); - } - - String html = IOUtils.toString(response.getEntity().getContent(), Charset.forName(CHARSET)); - String configJson = DataFormatTools.extractBetween(html, "'PLAYER_CONFIG': ", "});writeEmbed();"); - - if (configJson != null) { - return JsonBrowser.parse(configJson); - } - } - - throw new FriendlyException("Track information is unavailable.", SUSPICIOUS, - new IllegalStateException("Expected player config is not present in embed page.")); - } - - private Map loadTrackArgsFromVideoInfoPage(HttpInterface httpInterface, String videoId, String sts) throws IOException { - String url = "https://www.youtube.com/get_video_info?hl=en_GB&video_id=" + videoId + "&sts=" + sts; - - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(url))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for video info response: " + statusCode); - } - - return convertToMapLayout(URLEncodedUtils.parse(response.getEntity())); - } - } - - private AudioPlaylist loadPlaylistWithId(String playlistId, String selectedVideoId) { - log.debug("Starting to load playlist with ID {}", playlistId); - - try (HttpInterface httpInterface = getHttpInterface()) { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet("https://www.youtube.com/playlist?list=" + playlistId))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for playlist response: " + statusCode); - } - - Document document = Jsoup.parse(response.getEntity().getContent(), CHARSET, ""); - return buildPlaylist(httpInterface, document, selectedVideoId); - } - } catch (Exception e) { - throw ExceptionTools.wrapUnfriendlyExceptions(e); - } - } - - private AudioPlaylist buildPlaylist(HttpInterface httpInterface, Document document, String selectedVideoId) throws IOException { - boolean isAccessible = !document.select("#pl-header").isEmpty(); - - if (!isAccessible) { - if (selectedVideoId != null) { - return null; - } else { - throw new FriendlyException("The playlist is private.", COMMON, null); - } - } - - Element container = document.select("#pl-header").first().parent(); - - String playlistName = container.select(".pl-header-title").first().text(); - - List tracks = new ArrayList<>(); - String loadMoreUrl = extractPlaylistTracks(container, container, tracks); - int loadCount = 0; - int pageCount = playlistPageCount; - - // Also load the next pages, each result gives us a JSON with separate values for list html and next page loader html - while (loadMoreUrl != null && ++loadCount < pageCount) { - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet("https://www.youtube.com" + loadMoreUrl))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for playlist response: " + statusCode); - } - - JsonBrowser json = JsonBrowser.parse(response.getEntity().getContent()); - - String html = json.get("content_html").text(); - Element videoContainer = Jsoup.parse("" + html + "
", ""); - - String moreHtml = json.get("load_more_widget_html").text(); - Element moreContainer = moreHtml != null ? Jsoup.parse(moreHtml) : null; - - loadMoreUrl = extractPlaylistTracks(videoContainer, moreContainer, tracks); - } - } - - return new BasicAudioPlaylist(playlistName, tracks, findSelectedTrack(tracks, selectedVideoId), false); - } - - private String extractPlaylistTracks(Element videoContainer, Element loadMoreContainer, List tracks) { - for (Element video : videoContainer.select(".pl-video")) { - Elements lengthElements = video.select(".timestamp span"); - - // If the timestamp element does not exist, it means the video is private - if (!lengthElements.isEmpty()) { - String videoId = video.attr("data-video-id").trim(); - String title = video.attr("data-title").trim(); - String author = video.select(".pl-video-owner a").text().trim(); - long duration = DataFormatTools.durationTextToMillis(lengthElements.first().text()); - - tracks.add(buildTrackObject(videoId, title, author, false, duration)); - } - } - - if (loadMoreContainer != null) { - Elements more = loadMoreContainer.select(".load-more-button"); - if (!more.isEmpty()) { - return more.first().attr("data-uix-load-more-href"); - } - } - - return null; - } - - /** - * @param videoId Video ID. Used as {@link AudioTrackInfo#identifier}. - * @param title See {@link AudioTrackInfo#title}. - * @param uploader Name of the uploader. Used as {@link AudioTrackInfo#author}. - * @param isStream See {@link AudioTrackInfo#isStream}. - * @param duration See {@link AudioTrackInfo#length}. - * @return An audio track instance. - */ - public YoutubeAudioTrack buildTrackObject(String videoId, String title, String uploader, boolean isStream, long duration) { - return new YoutubeAudioTrack(new AudioTrackInfo(title, uploader, duration, videoId, isStream, getWatchUrl(videoId)), this); - } - - private static String getWatchUrl(String videoId) { - return "https://www.youtube.com/watch?v=" + videoId; - } - - private static UrlInfo getUrlInfo(String url, boolean retryValidPart) { - try { - if (!url.startsWith("http://") && !url.startsWith("https://")) { - url = "https://" + url; - } - - URIBuilder builder = new URIBuilder(url); - return new UrlInfo(builder.getPath(), builder.getQueryParams().stream() - .filter(it -> it.getValue() != null) - .collect(Collectors.toMap(NameValuePair::getName, NameValuePair::getValue))); - } catch (URISyntaxException e) { - if (retryValidPart) { - return getUrlInfo(url.substring(0, e.getIndex() - 1), false); - } else { - throw new FriendlyException("Not a valid URL: " + url, COMMON, e); - } - } - } - - private static class UrlInfo { - private final String path; - private final Map parameters; - - private UrlInfo(String path, Map parameters) { - this.path = path; - this.parameters = parameters; - } - } - - private static class Extractor { - private final Pattern pattern; - private final Function loader; - - private Extractor(Pattern pattern, Function loader) { - this.pattern = pattern; - this.loader = loader; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeAudioTrack.java deleted file mode 100644 index 963c507..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeAudioTrack.java +++ /dev/null @@ -1,289 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -import com.sedmelluq.discord.lavaplayer.container.matroska.MatroskaAudioTrack; -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegAudioTrack; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URLEncodedUtils; -import org.apache.http.entity.ContentType; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.parser.Parser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.StringJoiner; - -import static com.sedmelluq.discord.lavaplayer.container.Formats.MIME_AUDIO_WEBM; -import static com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager.CHARSET; -import static com.sedmelluq.discord.lavaplayer.tools.DataFormatTools.convertToMapLayout; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.COMMON; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Audio track that handles processing Youtube videos as audio tracks. - */ -public class YoutubeAudioTrack extends DelegatedAudioTrack { - private static final Logger log = LoggerFactory.getLogger(YoutubeAudioTrack.class); - - private static final String DEFAULT_SIGNATURE_KEY = "signature"; - - private final YoutubeAudioSourceManager sourceManager; - - /** - * @param trackInfo Track info - * @param sourceManager Source manager which was used to find this track - */ - public YoutubeAudioTrack(AudioTrackInfo trackInfo, YoutubeAudioSourceManager sourceManager) { - super(trackInfo); - - this.sourceManager = sourceManager; - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) throws Exception { - try (HttpInterface httpInterface = sourceManager.getHttpInterface()) { - FormatWithUrl format = loadBestFormatWithUrl(httpInterface); - - log.debug("Starting track from URL: {}", format.signedUrl); - - if (trackInfo.isStream) { - processStream(localExecutor, format); - } else { - processStatic(localExecutor, httpInterface, format); - } - } - } - - private void processStatic(LocalAudioTrackExecutor localExecutor, HttpInterface httpInterface, FormatWithUrl format) throws Exception { - try (YoutubePersistentHttpStream stream = new YoutubePersistentHttpStream(httpInterface, format.signedUrl, format.details.getContentLength())) { - if (format.details.getType().getMimeType().endsWith("/webm")) { - processDelegate(new MatroskaAudioTrack(trackInfo, stream), localExecutor); - } else { - processDelegate(new MpegAudioTrack(trackInfo, stream), localExecutor); - } - } - } - - private void processStream(LocalAudioTrackExecutor localExecutor, FormatWithUrl format) throws Exception { - if (MIME_AUDIO_WEBM.equals(format.details.getType().getMimeType())) { - throw new FriendlyException("YouTube WebM streams are currently not supported.", COMMON, null); - } else { - try (HttpInterface streamingInterface = sourceManager.getHttpInterface()) { - processDelegate(new YoutubeMpegStreamAudioTrack(trackInfo, streamingInterface, format.signedUrl), localExecutor); - } - } - } - - private FormatWithUrl loadBestFormatWithUrl(HttpInterface httpInterface) throws Exception { - JsonBrowser info = getTrackInfo(httpInterface); - - String playerScript = extractPlayerScriptFromInfo(info); - List formats = loadTrackFormats(info, httpInterface, playerScript); - YoutubeTrackFormat format = findBestSupportedFormat(formats); - - URI signedUrl = sourceManager.getCipherManager().getValidUrl(httpInterface, playerScript, format); - - return new FormatWithUrl(format, signedUrl); - } - - @Override - public AudioTrack makeClone() { - return new YoutubeAudioTrack(trackInfo, sourceManager); - } - - @Override - public AudioSourceManager getSourceManager() { - return sourceManager; - } - - private JsonBrowser getTrackInfo(HttpInterface httpInterface) throws Exception { - return sourceManager.getTrackInfoFromMainPage(httpInterface, getIdentifier(), true); - } - - private List loadTrackFormats(JsonBrowser info, HttpInterface httpInterface, String playerScript) throws Exception { - JsonBrowser args = info.safeGet("args"); - - String adaptiveFormats = args.safeGet("adaptive_fmts").text(); - if (adaptiveFormats != null) { - return loadTrackFormatsFromAdaptive(adaptiveFormats); - } - - String dashUrl = args.safeGet("dashmpd").text(); - if (dashUrl != null) { - return loadTrackFormatsFromDash(dashUrl, httpInterface, playerScript); - } - - String formatStreamMap = args.safeGet("url_encoded_fmt_stream_map").text(); - if (formatStreamMap != null) { - return loadTrackFormatsFromFormatStreamMap(formatStreamMap); - } - - throw new FriendlyException("Unable to play this YouTube track.", SUSPICIOUS, - new IllegalStateException("No adaptive formats, no dash, no stream map.")); - } - - private List loadTrackFormatsFromAdaptive(String adaptiveFormats) throws Exception { - List tracks = new ArrayList<>(); - - for (String formatString : adaptiveFormats.split(",")) { - Map format = convertToMapLayout(URLEncodedUtils.parse(formatString, Charset.forName(CHARSET))); - - tracks.add(new YoutubeTrackFormat( - ContentType.parse(format.get("type")), - Long.parseLong(format.get("bitrate")), - Long.parseLong(format.get("clen")), - format.get("url"), - format.get("s"), - format.getOrDefault("sp", DEFAULT_SIGNATURE_KEY) - )); - } - - return tracks; - } - - private List loadTrackFormatsFromFormatStreamMap(String adaptiveFormats) throws Exception { - List tracks = new ArrayList<>(); - - for (String formatString : adaptiveFormats.split(",")) { - Map format = convertToMapLayout(URLEncodedUtils.parse(formatString, Charset.forName(CHARSET))); - String url = format.get("url"); - String contentLength = DataFormatTools.extractBetween(url, "clen=", "&"); - - if (contentLength == null) { - log.debug("Could not find content length from URL {}, skipping format", url); - continue; - } - - tracks.add(new YoutubeTrackFormat( - ContentType.parse(format.get("type")), - qualityToBitrateValue(format.get("quality")), - Long.parseLong(contentLength), - url, - format.get("s"), - format.getOrDefault("sp", DEFAULT_SIGNATURE_KEY) - )); - } - - return tracks; - } - - private long qualityToBitrateValue(String quality) { - // Return negative bitrate values to indicate missing bitrate info, but still retain the relative order. - if ("small".equals(quality)) { - return -10; - } else if ("medium".equals(quality)) { - return -5; - } else if ("hd720".equals(quality)) { - return -4; - } else { - return -1; - } - } - - private List loadTrackFormatsFromDash(String dashUrl, HttpInterface httpInterface, String playerScript) throws Exception { - String resolvedDashUrl = sourceManager.getCipherManager().getValidDashUrl(httpInterface, playerScript, dashUrl); - - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(resolvedDashUrl))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for track info page response: " + statusCode); - } - - Document document = Jsoup.parse(response.getEntity().getContent(), CHARSET, "", Parser.xmlParser()); - return loadTrackFormatsFromDashDocument(document); - } - } - - private List loadTrackFormatsFromDashDocument(Document document) { - List tracks = new ArrayList<>(); - - for (Element adaptation : document.select("AdaptationSet")) { - String mimeType = adaptation.attr("mimeType"); - - for (Element representation : adaptation.select("Representation")) { - String url = representation.select("BaseURL").first().text(); - String contentLength = DataFormatTools.extractBetween(url, "/clen/", "/"); - String contentType = mimeType + "; codecs=" + representation.attr("codecs"); - - if (contentLength == null) { - log.debug("Skipping format {} because the content length is missing", contentType); - continue; - } - - tracks.add(new YoutubeTrackFormat( - ContentType.parse(contentType), - Long.parseLong(representation.attr("bandwidth")), - Long.parseLong(contentLength), - url, - null, - DEFAULT_SIGNATURE_KEY - )); - } - } - - return tracks; - } - - private static String extractPlayerScriptFromInfo(JsonBrowser info) { - return info.get("assets").get("js").text(); - } - - private static boolean isBetterFormat(YoutubeTrackFormat format, YoutubeTrackFormat other) { - YoutubeFormatInfo info = format.getInfo(); - - if (info == null) { - return false; - } else if (other == null) { - return true; - } else if (info.ordinal() != other.getInfo().ordinal()) { - return info.ordinal() < other.getInfo().ordinal(); - } else { - return format.getBitrate() > other.getBitrate(); - } - } - - private static YoutubeTrackFormat findBestSupportedFormat(List formats) throws Exception { - YoutubeTrackFormat bestFormat = null; - - for (YoutubeTrackFormat format : formats) { - if (isBetterFormat(format, bestFormat)) { - bestFormat = format; - } - } - - if (bestFormat == null) { - StringJoiner joiner = new StringJoiner(", "); - formats.forEach(format -> joiner.add(format.getType().toString())); - throw new IllegalStateException("No supported audio streams available, available types: " + joiner.toString()); - } - - return bestFormat; - } - - private static class FormatWithUrl { - private final YoutubeTrackFormat details; - private final URI signedUrl; - - private FormatWithUrl(YoutubeTrackFormat details, URI signedUrl) { - this.details = details; - this.signedUrl = signedUrl; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeCipherOperation.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeCipherOperation.java deleted file mode 100644 index 1fd63a9..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeCipherOperation.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -/** - * One cipher operation definition. - */ -public class YoutubeCipherOperation { - /** - * The type of the operation. - */ - public final YoutubeCipherOperationType type; - /** - * The parameter for the operation. - */ - public final int parameter; - - /** - * @param type The type of the operation. - * @param parameter The parameter for the operation. - */ - public YoutubeCipherOperation(YoutubeCipherOperationType type, int parameter) { - this.type = type; - this.parameter = parameter; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeCipherOperationType.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeCipherOperationType.java deleted file mode 100644 index 8a79385..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeCipherOperationType.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -/** - * Type of a signature cipher operation. - */ -public enum YoutubeCipherOperationType { - SWAP, - REVERSE, - SLICE, - SPLICE -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeFormatInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeFormatInfo.java deleted file mode 100644 index 503c0f4..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeFormatInfo.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -import org.apache.http.entity.ContentType; - -import static com.sedmelluq.discord.lavaplayer.container.Formats.*; - -/** - * The mime type and codec info of a Youtube track format. - */ -public enum YoutubeFormatInfo { - WEBM_OPUS(MIME_AUDIO_WEBM, CODEC_OPUS), - WEBM_VORBIS(MIME_AUDIO_WEBM, CODEC_VORBIS), - MP4_AAC_LC(MIME_AUDIO_MP4, CODEC_AAC_LC), - WEBM_VIDEO_VORBIS(MIME_VIDEO_WEBM, CODEC_VORBIS), - MP4_VIDEO_AAC_LC(MIME_VIDEO_MP4, CODEC_AAC_LC); - - /** - * Mime type of the format - */ - public final String mimeType; - /** - * Codec name of the format - */ - public final String codec; - - YoutubeFormatInfo(String mimeType, String codec) { - this.mimeType = mimeType; - this.codec = codec; - } - - /** - * Find a matching format info instance from a content type. - * - * @param contentType The content type to use for matching against known formats - * @return The format info entry that matches the content type - */ - public static YoutubeFormatInfo get(ContentType contentType) { - String mimeType = contentType.getMimeType(); - String codec = contentType.getParameter("codecs"); - - // Check accurate matches - for (YoutubeFormatInfo formatInfo : YoutubeFormatInfo.class.getEnumConstants()) { - if (formatInfo.mimeType.equals(mimeType) && formatInfo.codec.equals(codec)) { - return formatInfo; - } - } - - // Check for substring matches - for (YoutubeFormatInfo formatInfo : YoutubeFormatInfo.class.getEnumConstants()) { - if (formatInfo.mimeType.equals(mimeType) && codec.contains(formatInfo.codec)) { - return formatInfo; - } - } - - return null; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeMixProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeMixProvider.java deleted file mode 100644 index b4d7b34..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeMixProvider.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.track.*; -import com.sedmelluq.lava.common.tools.DaemonThreadFactory; -import com.sedmelluq.lava.common.tools.ExecutorTools; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.*; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Handles loading of YouTube mixes. - */ -public class YoutubeMixProvider { - private static final Logger log = LoggerFactory.getLogger(YoutubeMixProvider.class); - - private static final int MIX_QUEUE_CAPACITY = 5000; - - private final YoutubeAudioSourceManager sourceManager; - private final ThreadPoolExecutor mixLoadingExecutor; - - /** - * @param sourceManager YouTube source manager used for created tracks. - */ - public YoutubeMixProvider(YoutubeAudioSourceManager sourceManager) { - this.sourceManager = sourceManager; - mixLoadingExecutor = new ThreadPoolExecutor(0, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(MIX_QUEUE_CAPACITY), - new DaemonThreadFactory("yt-mix")); - } - - /** - * @param maximumPoolSize Maximum number of threads in mix loader thread pool. - */ - public void setLoaderMaximumPoolSize(int maximumPoolSize) { - mixLoadingExecutor.setMaximumPoolSize(maximumPoolSize); - } - - /** - * Shuts down mix loading threads. - */ - public void shutdown() { - ExecutorTools.shutdownExecutor(mixLoadingExecutor, "youtube mix"); - } - - /** - * Loads tracks from mix in parallel into a playlist entry. - * - * @param mixId ID of the mix - * @param selectedVideoId Selected track, {@link AudioPlaylist#getSelectedTrack()} will return this. - * @return Playlist of the tracks in the mix. - */ - public AudioItem loadMixWithId(String mixId, String selectedVideoId) { - List videoIds = new ArrayList<>(); - - try (HttpInterface httpInterface = sourceManager.getHttpInterface()) { - String mixUrl = "https://www.youtube.com/watch?v=" + selectedVideoId + "&list=" + mixId; - - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(mixUrl))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for mix response: " + statusCode); - } - - Document document = Jsoup.parse(response.getEntity().getContent(), StandardCharsets.UTF_8.name(), ""); - extractVideoIdsFromMix(document, videoIds); - - if (videoIds.isEmpty() && !document.select("#player-unavailable").isEmpty()) { - return AudioReference.NO_TRACK; - } - } - } catch (IOException e) { - throw new FriendlyException("Could not read mix page.", SUSPICIOUS, e); - } - - if (videoIds.isEmpty()) { - throw new FriendlyException("Could not find tracks from mix.", SUSPICIOUS, null); - } - - return loadTracksAsynchronously(videoIds, selectedVideoId); - } - - private void extractVideoIdsFromMix(Document document, List videoIds) { - for (Element videoList : document.select("#playlist-autoscroll-list")) { - for (Element item : videoList.select("li")) { - videoIds.add(item.attr("data-video-id")); - } - } - } - - private AudioPlaylist loadTracksAsynchronously(List videoIds, String selectedVideoId) { - ExecutorCompletionService completion = new ExecutorCompletionService<>(mixLoadingExecutor); - List tracks = new ArrayList<>(); - - for (final String videoId : videoIds) { - completion.submit(() -> sourceManager.loadTrackWithVideoId(videoId, true)); - } - - try { - fetchTrackResultsFromExecutor(completion, tracks, videoIds.size()); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - - AudioTrack selectedTrack = sourceManager.findSelectedTrack(tracks, selectedVideoId); - - if (tracks.isEmpty()) { - throw new FriendlyException("No tracks from the mix loaded succesfully.", SUSPICIOUS, null); - } else if (selectedTrack == null) { - throw new FriendlyException("The selected track of the mix failed to load.", SUSPICIOUS, null); - } - - return new BasicAudioPlaylist("YouTube mix", tracks, selectedTrack, false); - } - - private void fetchTrackResultsFromExecutor(ExecutorCompletionService completion, List tracks, int size) throws InterruptedException { - for (int i = 0; i < size; i++) { - try { - AudioItem item = completion.take().get(); - - if (item instanceof AudioTrack) { - tracks.add((AudioTrack) item); - } - } catch (ExecutionException e) { - if (e.getCause() instanceof FriendlyException) { - ExceptionTools.log(log, (FriendlyException) e.getCause(), "Loading a track from a mix."); - } else { - log.warn("Failed to load a track from a mix.", e); - } - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeMpegStreamAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeMpegStreamAudioTrack.java deleted file mode 100644 index 2430971..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeMpegStreamAudioTrack.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegAudioTrack; -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegFileLoader; -import com.sedmelluq.discord.lavaplayer.container.mpeg.MpegTrackConsumer; -import com.sedmelluq.discord.lavaplayer.container.mpeg.reader.MpegFileTrackProvider; -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioProcessingContext; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; -import org.apache.http.HttpStatus; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.utils.URIBuilder; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * YouTube segmented MPEG stream track. The base URL always gives the latest chunk. Every chunk contains the current - * sequence number in it, which is used to get the sequence number of the next segment. This is repeated until YouTube - * responds to a segment request with 204. - */ -public class YoutubeMpegStreamAudioTrack extends MpegAudioTrack { - private static final RequestConfig streamingRequestConfig = RequestConfig.custom().setConnectTimeout(10000).build(); - - private final HttpInterface httpInterface; - private final URI signedUrl; - - /** - * @param trackInfo Track info - * @param httpInterface HTTP interface to use for loading segments - * @param signedUrl URI of the base stream with signature resolved - */ - public YoutubeMpegStreamAudioTrack(AudioTrackInfo trackInfo, HttpInterface httpInterface, URI signedUrl) { - super(trackInfo, null); - - this.httpInterface = httpInterface; - this.signedUrl = signedUrl; - - // YouTube does not return a segment until it is ready, this might trigger a connect timeout otherwise. - httpInterface.getContext().setRequestConfig(streamingRequestConfig); - } - - @Override - public void process(LocalAudioTrackExecutor localExecutor) { - localExecutor.executeProcessingLoop(() -> { - execute(localExecutor); - }, null); - } - - private void execute(LocalAudioTrackExecutor localExecutor) throws InterruptedException { - TrackState state = new TrackState(signedUrl); - - try { - while (!state.finished) { - processNextSegment(localExecutor, state); - state.relativeSequence++; - } - } finally { - if (state.trackConsumer != null) { - state.trackConsumer.close(); - } - } - } - - private void processNextSegment(LocalAudioTrackExecutor localExecutor, TrackState state) throws InterruptedException { - URI segmentUrl = getNextSegmentUrl(state); - - try (YoutubePersistentHttpStream stream = new YoutubePersistentHttpStream(httpInterface, segmentUrl, Long.MAX_VALUE)) { - if (stream.checkStatusCode() == HttpStatus.SC_NO_CONTENT || stream.getContentLength() == 0) { - state.finished = true; - return; - } - - // If we were redirected, use that URL as a base for the next segment URL. Otherwise we will likely get redirected - // again on every other request, which is inefficient (redirects across domains, the original URL is always - // closing the connection, whereas the final URL is keep-alive). - state.baseUrl = httpInterface.getFinalLocation(); - - processSegmentStream(stream, localExecutor.getProcessingContext(), state); - - stream.releaseConnection(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void processSegmentStream(SeekableInputStream stream, AudioProcessingContext context, TrackState state) throws InterruptedException { - MpegFileLoader file = new MpegFileLoader(stream); - file.parseHeaders(); - - state.absoluteSequence = extractAbsoluteSequenceFromEvent(file.getLastEventMessage()); - - if (state.trackConsumer == null) { - state.trackConsumer = loadAudioTrack(file, context); - } - - MpegFileTrackProvider fileReader = file.loadReader(state.trackConsumer); - if (fileReader == null) { - throw new FriendlyException("Unknown MP4 format.", SUSPICIOUS, null); - } - - fileReader.provideFrames(); - } - - private URI getNextSegmentUrl(TrackState state) { - URIBuilder builder = new URIBuilder(state.baseUrl) - .setParameter("rn", String.valueOf(state.relativeSequence)) - .setParameter("rbuf", "0"); - - if (state.absoluteSequence != null) { - builder.setParameter("sq", String.valueOf(state.absoluteSequence + 1)); - } - - try { - return builder.build(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } - - private Long extractAbsoluteSequenceFromEvent(byte[] data) { - if (data == null) { - return null; - } - - String message = new String(data, StandardCharsets.UTF_8); - String sequence = DataFormatTools.extractBetween(message, "Sequence-Number: ", "\r\n"); - - return sequence != null ? Long.valueOf(sequence) : null; - } - - private static class TrackState { - private long relativeSequence; - private Long absoluteSequence; - private MpegTrackConsumer trackConsumer; - private boolean finished; - private URI baseUrl; - - public TrackState(URI baseUrl) { - this.baseUrl = baseUrl; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubePersistentHttpStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubePersistentHttpStream.java deleted file mode 100644 index 71a6526..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubePersistentHttpStream.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.PersistentHttpStream; -import org.apache.http.client.utils.URIBuilder; - -import java.net.URI; -import java.net.URISyntaxException; - -/** - * A persistent HTTP stream implementation that uses the range parameter instead of HTTP headers for specifying - * the start position at which to start reading on a new connection. - */ -public class YoutubePersistentHttpStream extends PersistentHttpStream { - - /** - * @param httpInterface The HTTP interface to use for requests - * @param contentUrl The URL of the resource - * @param contentLength The length of the resource in bytes - */ - public YoutubePersistentHttpStream(HttpInterface httpInterface, URI contentUrl, long contentLength) { - super(httpInterface, contentUrl, contentLength); - } - - @Override - protected URI getConnectUrl() { - if (position > 0) { - try { - return new URIBuilder(contentUrl).addParameter("range", position + "-" + contentLength).build(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } else { - return contentUrl; - } - } - - @Override - protected boolean useHeadersForRange() { - return false; - } - - @Override - public boolean canSeekHard() { - return true; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSearchProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSearchProvider.java deleted file mode 100644 index 40c76c4..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSearchProvider.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpConfigurable; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterfaceManager; -import com.sedmelluq.discord.lavaplayer.track.AudioItem; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.BasicAudioPlaylist; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClientBuilder; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Handles processing YouTube searches. - */ -public class YoutubeSearchProvider implements HttpConfigurable { - private static final Logger log = LoggerFactory.getLogger(YoutubeSearchProvider.class); - - private final YoutubeAudioSourceManager sourceManager; - private final HttpInterfaceManager httpInterfaceManager; - - /** - * @param sourceManager YouTube source manager used for created tracks. - */ - public YoutubeSearchProvider(YoutubeAudioSourceManager sourceManager) { - this.sourceManager = sourceManager; - this.httpInterfaceManager = HttpClientTools.createCookielessThreadLocalManager(); - } - - /** - * @param query Search query. - * @return Playlist of the first page of results. - */ - public AudioItem loadSearchResult(String query) { - log.debug("Performing a search with query {}", query); - - try (HttpInterface httpInterface = httpInterfaceManager.getInterface()) { - URI url = new URIBuilder("https://www.youtube.com/results").addParameter("search_query", query).build(); - - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(url))) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - throw new IOException("Invalid status code for search response: " + statusCode); - } - - Document document = Jsoup.parse(response.getEntity().getContent(), StandardCharsets.UTF_8.name(), ""); - return extractSearchResults(document, query); - } - } catch (Exception e) { - throw ExceptionTools.wrapUnfriendlyExceptions(e); - } - } - - private AudioItem extractSearchResults(Document document, String query) { - List tracks = new ArrayList<>(); - - for (Element results : document.select("#page > #content #results")) { - for (Element result : results.select(".yt-lockup-video")) { - if (!result.hasAttr("data-ad-impressions") && result.select(".standalone-ypc-badge-renderer-label").isEmpty()) { - extractTrackFromResultEntry(tracks, result); - } - } - } - - if (tracks.isEmpty()) { - return AudioReference.NO_TRACK; - } else { - return new BasicAudioPlaylist("Search results for: " + query, tracks, null, true); - } - } - - private void extractTrackFromResultEntry(List tracks, Element element) { - Element durationElement = element.select("[class^=video-time]").first(); - Element contentElement = element.select(".yt-lockup-content").first(); - String videoId = element.attr("data-context-item-id"); - - if (durationElement == null || contentElement == null || videoId.isEmpty()) { - return; - } - - long duration = DataFormatTools.durationTextToMillis(durationElement.text()); - - String title = contentElement.select(".yt-lockup-title > a").text(); - String author = contentElement.select(".yt-lockup-byline > a").text(); - - tracks.add(sourceManager.buildTrackObject(videoId, title, author, false, duration)); - } - - @Override - public void configureRequests(Function configurator) { - httpInterfaceManager.configureRequests(configurator); - } - - @Override - public void configureBuilder(Consumer configurator) { - httpInterfaceManager.configureBuilder(configurator); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSignatureCipher.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSignatureCipher.java deleted file mode 100644 index d149842..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSignatureCipher.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -import java.util.ArrayList; -import java.util.List; - -/** - * Describes one signature cipher - */ -public class YoutubeSignatureCipher { - private final List operations = new ArrayList<>(); - - /** - * @param text Text to apply the cipher on - * @return The result of the cipher on the input text - */ - public String apply(String text) { - StringBuilder builder = new StringBuilder(text); - - for (YoutubeCipherOperation operation : operations) { - switch (operation.type) { - case SWAP: - int position = operation.parameter % text.length(); - char temp = builder.charAt(0); - builder.setCharAt(0, builder.charAt(position)); - builder.setCharAt(position, temp); - break; - case REVERSE: - builder.reverse(); - break; - case SLICE: - case SPLICE: - builder.delete(0, operation.parameter); - break; - default: - throw new IllegalStateException("All branches should be covered"); - } - } - - return builder.toString(); - } - - /** - * @param operation The operation to add to this cipher - */ - public void addOperation(YoutubeCipherOperation operation) { - operations.add(operation); - } - - /** - * @return True if the cipher contains no operations. - */ - public boolean isEmpty() { - return operations.isEmpty(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSignatureCipherManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSignatureCipherManager.java deleted file mode 100644 index 239f6be..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeSignatureCipherManager.java +++ /dev/null @@ -1,255 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface; -import org.apache.commons.io.IOUtils; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * Handles parsing and caching of signature ciphers - */ -public class YoutubeSignatureCipherManager { - private static final Logger log = LoggerFactory.getLogger(YoutubeSignatureCipherManager.class); - - private static final String VARIABLE_PART = "[a-zA-Z_\\$][a-zA-Z_0-9]*"; - private static final String VARIABLE_PART_DEFINE = "\\\"?" + VARIABLE_PART + "\\\"?"; - private static final String BEFORE_ACCESS = "(?:\\[\\\"|\\.)"; - private static final String AFTER_ACCESS = "(?:\\\"\\]|)"; - private static final String VARIABLE_PART_ACCESS = BEFORE_ACCESS + VARIABLE_PART + AFTER_ACCESS; - private static final String REVERSE_PART = ":function\\(a\\)\\{(?:return )?a\\.reverse\\(\\)\\}"; - private static final String SLICE_PART = ":function\\(a,b\\)\\{return a\\.slice\\(b\\)\\}"; - private static final String SPLICE_PART = ":function\\(a,b\\)\\{a\\.splice\\(0,b\\)\\}"; - private static final String SWAP_PART = ":function\\(a,b\\)\\{" + - "var c=a\\[0\\];a\\[0\\]=a\\[b%a\\.length\\];a\\[b(?:%a.length|)\\]=c(?:;return a)?\\}"; - - private static final Pattern functionPattern = Pattern.compile("" + - "function(?: " + VARIABLE_PART + ")?\\(a\\)\\{" + - "a=a\\.split\\(\"\"\\);\\s*" + - "((?:(?:a=)?" + VARIABLE_PART + VARIABLE_PART_ACCESS + "\\(a,\\d+\\);)+)" + - "return a\\.join\\(\"\"\\)" + - "\\}" - ); - - private static final Pattern actionsPattern = Pattern.compile("" + - "var (" + VARIABLE_PART + ")=\\{((?:(?:" + - VARIABLE_PART_DEFINE + REVERSE_PART + "|" + - VARIABLE_PART_DEFINE + SLICE_PART + "|" + - VARIABLE_PART_DEFINE + SPLICE_PART + "|" + - VARIABLE_PART_DEFINE + SWAP_PART + - "),?\\n?)+)\\};" - ); - - private static final String PATTERN_PREFIX = "(?:^|,)\\\"?(" + VARIABLE_PART + ")\\\"?"; - - private static final Pattern reversePattern = Pattern.compile(PATTERN_PREFIX + REVERSE_PART, Pattern.MULTILINE); - private static final Pattern slicePattern = Pattern.compile(PATTERN_PREFIX + SLICE_PART, Pattern.MULTILINE); - private static final Pattern splicePattern = Pattern.compile(PATTERN_PREFIX + SPLICE_PART, Pattern.MULTILINE); - private static final Pattern swapPattern = Pattern.compile(PATTERN_PREFIX + SWAP_PART, Pattern.MULTILINE); - - private static final Pattern signatureExtraction = Pattern.compile("/s/([^/]+)/"); - - private final ConcurrentMap cipherCache; - private final Set dumpedScriptUrls; - private final Object cipherLoadLock; - - /** - * Create a new signature cipher manager - */ - public YoutubeSignatureCipherManager() { - this.cipherCache = new ConcurrentHashMap<>(); - this.dumpedScriptUrls = new HashSet<>(); - this.cipherLoadLock = new Object(); - } - - /** - * Produces a valid playback URL for the specified track - * - * @param httpInterface HTTP interface to use - * @param playerScript Address of the script which is used to decipher signatures - * @param format The track for which to get the URL - * @return Valid playback URL - * @throws IOException On network IO error - */ - public URI getValidUrl(HttpInterface httpInterface, String playerScript, YoutubeTrackFormat format) throws IOException { - String signature = format.getSignature(); - URI initialUrl = format.getUrl(); - - if (signature == null) { - return initialUrl; - } - - YoutubeSignatureCipher cipher = getCipherKeyFromScript(httpInterface, playerScript); - - try { - return new URIBuilder(initialUrl) - .setParameter("ratebypass", "yes") - .setParameter(format.getSignatureKey(), cipher.apply(signature)) - .build(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } - - /** - * Produces a valid dash XML URL from the possibly ciphered URL. - * - * @param httpInterface HTTP interface instance to use - * @param playerScript Address of the script which is used to decipher signatures - * @param dashUrl URL of the dash XML, possibly with a ciphered signature - * @return Valid dash XML URL - * @throws IOException On network IO error - */ - public String getValidDashUrl(HttpInterface httpInterface, String playerScript, String dashUrl) throws IOException { - Matcher matcher = signatureExtraction.matcher(dashUrl); - - if (!matcher.find()) { - return dashUrl; - } - - YoutubeSignatureCipher cipher = getCipherKeyFromScript(httpInterface, playerScript); - return matcher.replaceFirst("/signature/" + cipher.apply(matcher.group(1)) + "/"); - } - - private YoutubeSignatureCipher getCipherKeyFromScript(HttpInterface httpInterface, String cipherScriptUrl) throws IOException { - YoutubeSignatureCipher cipherKey = cipherCache.get(cipherScriptUrl); - - if (cipherKey == null) { - synchronized (cipherLoadLock) { - log.debug("Parsing cipher from player script {}.", cipherScriptUrl); - - try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(parseTokenScriptUrl(cipherScriptUrl)))) { - validateResponseCode(response); - - cipherKey = extractTokensFromScript(IOUtils.toString(response.getEntity().getContent(), "UTF-8"), cipherScriptUrl); - cipherCache.put(cipherScriptUrl, cipherKey); - } - } - } - - return cipherKey; - } - - private void validateResponseCode(CloseableHttpResponse response) throws IOException { - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode != 200) { - throw new IOException("Received non-success response code " + statusCode); - } - } - - private List getQuotedFunctions(String... functionNames) { - return Stream.of(functionNames) - .filter(Objects::nonNull) - .map(Pattern::quote) - .collect(Collectors.toList()); - } - - private void dumpProblematicScript(String script, String sourceUrl, String issue) { - if (!dumpedScriptUrls.add(sourceUrl)) { - return; - } - - try { - Path path = Files.createTempFile("lavaplayer-yt-player-script", ".js"); - Files.write(path, script.getBytes(StandardCharsets.UTF_8)); - - log.error("Problematic YouTube player script {} detected (issue detected with script: {}). Dumped to {}.", - sourceUrl, issue, path.toAbsolutePath()); - } catch (Exception e) { - log.error("Failed to dump problematic YouTube player script {} (issue detected with script: {})", sourceUrl, issue); - } - } - - private YoutubeSignatureCipher extractTokensFromScript(String script, String sourceUrl) { - Matcher actions = actionsPattern.matcher(script); - if (!actions.find()) { - dumpProblematicScript(script, sourceUrl, "no actions match"); - throw new IllegalStateException("Must find action functions from script: " + sourceUrl); - } - - String actionBody = actions.group(2); - - String reverseKey = extractDollarEscapedFirstGroup(reversePattern, actionBody); - String slicePart = extractDollarEscapedFirstGroup(slicePattern, actionBody); - String splicePart = extractDollarEscapedFirstGroup(splicePattern, actionBody); - String swapKey = extractDollarEscapedFirstGroup(swapPattern, actionBody); - - Pattern extractor = Pattern.compile( - "(?:a=)?" + Pattern.quote(actions.group(1)) + BEFORE_ACCESS + "(" + - String.join("|", getQuotedFunctions(reverseKey, slicePart, splicePart, swapKey)) + - ")" + AFTER_ACCESS + "\\(a,(\\d+)\\)" - ); - - Matcher functions = functionPattern.matcher(script); - if (!functions.find()) { - dumpProblematicScript(script, sourceUrl, "no decipher function match"); - throw new IllegalStateException("Must find decipher function from script."); - } - - Matcher matcher = extractor.matcher(functions.group(1)); - - YoutubeSignatureCipher cipherKey = new YoutubeSignatureCipher(); - - while (matcher.find()) { - String type = matcher.group(1); - - if (type.equals(swapKey)) { - cipherKey.addOperation(new YoutubeCipherOperation(YoutubeCipherOperationType.SWAP, Integer.parseInt(matcher.group(2)))); - } else if (type.equals(reverseKey)) { - cipherKey.addOperation(new YoutubeCipherOperation(YoutubeCipherOperationType.REVERSE, 0)); - } else if (type.equals(slicePart)) { - cipherKey.addOperation(new YoutubeCipherOperation(YoutubeCipherOperationType.SLICE, Integer.parseInt(matcher.group(2)))); - } else if (type.equals(splicePart)) { - cipherKey.addOperation(new YoutubeCipherOperation(YoutubeCipherOperationType.SPLICE, Integer.parseInt(matcher.group(2)))); - } else { - dumpProblematicScript(script, sourceUrl, "unknown cipher operation found"); - } - } - - if (cipherKey.isEmpty()) { - log.error("No operations detected from cipher extracted from {}.", sourceUrl); - dumpProblematicScript(script, sourceUrl, "no cipher operations"); - } - - return cipherKey; - } - - private static String extractDollarEscapedFirstGroup(Pattern pattern, String text) { - Matcher matcher = pattern.matcher(text); - return matcher.find() ? matcher.group(1).replace("$", "\\$") : null; - } - - private static URI parseTokenScriptUrl(String urlString) { - try { - if (urlString.startsWith("//")) { - return new URI("https:" + urlString); - } else if (urlString.startsWith("/")) { - return new URI("https://s.ytimg.com" + urlString); - } else { - return new URI(urlString); - } - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeTrackFormat.java b/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeTrackFormat.java deleted file mode 100644 index 9998842..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/source/youtube/YoutubeTrackFormat.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.source.youtube; - -import org.apache.http.entity.ContentType; - -import java.net.URI; -import java.net.URISyntaxException; - -/** - * Describes an available media format for a track - */ -public class YoutubeTrackFormat { - private final YoutubeFormatInfo info; - private final ContentType type; - private final long bitrate; - private final long contentLength; - private final String url; - private final String signature; - private final String signatureKey; - - /** - * @param type Mime type of the format - * @param bitrate Bitrate of the format - * @param contentLength Length in bytes of the media - * @param url Base URL for the playback of this format - * @param signature Cipher signature for this format - * @param signatureKey The key to use for deciphered signature in the final playback URL - */ - public YoutubeTrackFormat(ContentType type, long bitrate, long contentLength, String url, String signature, - String signatureKey) { - - this.info = YoutubeFormatInfo.get(type); - this.type = type; - this.bitrate = bitrate; - this.contentLength = contentLength; - this.url = url; - this.signature = signature; - this.signatureKey = signatureKey; - } - - /** - * @return Format container and codec info - */ - public YoutubeFormatInfo getInfo() { - return info; - } - - /** - * @return Mime type of the format - */ - public ContentType getType() { - return type; - } - - /** - * @return Bitrate of the format - */ - public long getBitrate() { - return bitrate; - } - - /** - * @return Base URL for the playback of this format - */ - public URI getUrl() { - try { - return new URI(url); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } - - /** - * @return Length in bytes of the media - */ - public long getContentLength() { - return contentLength; - } - - /** - * @return Cipher signature for this format - */ - public String getSignature() { - return signature; - } - - /** - * @return The key to use for deciphered signature in the final playback URL - */ - public String getSignatureKey() { - return signatureKey; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/DataFormatTools.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/DataFormatTools.java deleted file mode 100644 index 81fae07..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/DataFormatTools.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools; - -import org.apache.commons.io.IOUtils; -import org.apache.http.NameValuePair; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Pattern; - -/** - * Helper methods related to strings and maps. - */ -public class DataFormatTools { - private static final Pattern lineSplitPattern = Pattern.compile("[\\r\\n\\s]*\\n[\\r\\n\\s]*"); - - /** - * Extract text between the first subsequent occurrences of start and end in haystack - * - * @param haystack The text to search from - * @param start The text after which to start extracting - * @param end The text before which to stop extracting - * @return The extracted string - */ - public static String extractBetween(String haystack, String start, String end) { - int startMatch = haystack.indexOf(start); - - if (startMatch >= 0) { - int startPosition = startMatch + start.length(); - int endPosition = haystack.indexOf(end, startPosition); - - if (endPosition >= 0) { - return haystack.substring(startPosition, endPosition); - } - } - - return null; - } - - /** - * Converts name value pairs to a map, with the last entry for each name being present. - * - * @param pairs Name value pairs to convert - * @return The resulting map - */ - public static Map convertToMapLayout(Collection pairs) { - Map map = new HashMap<>(); - for (NameValuePair pair : pairs) { - map.put(pair.getName(), pair.getValue()); - } - return map; - } - - /** - * Returns the specified default value if the value itself is null. - * - * @param value Value to check - * @param defaultValue Default value to return if value is null - * @param The type of the value - * @return Value or default value - */ - public static T defaultOnNull(T value, T defaultValue) { - return value == null ? defaultValue : value; - } - - /** - * Consumes a stream and returns it as lines. - * - * @param inputStream Input stream to consume. - * @param charset Character set of the stream - * @return Lines from the stream - * @throws IOException On read error - */ - public static String[] streamToLines(InputStream inputStream, Charset charset) throws IOException { - String text = IOUtils.toString(inputStream, charset); - return lineSplitPattern.split(text); - } - - /** - * Converts duration in the format HH:mm:ss (or mm:ss or ss) to milliseconds. Does not support day count. - * - * @param durationText Duration in text format. - * @return Duration in milliseconds. - */ - public static long durationTextToMillis(String durationText) { - int length = 0; - - for (String part : durationText.split("[:.]")) { - length = length * 60 + Integer.valueOf(part); - } - - return length * 1000L; - } - - /** - * Writes a string to output with the additional information whether it is null or not. Compatible with - * {@link #readNullableText(DataInput)}. - * - * @param output Output to write to. - * @param text Text to write. - * @throws IOException On write error. - */ - public static void writeNullableText(DataOutput output, String text) throws IOException { - output.writeBoolean(text != null); - - if (text != null) { - output.writeUTF(text); - } - } - - /** - * Reads a string from input which may be null. Compatible with - * {@link #writeNullableText(DataOutput, String)}. - * - * @param input Input to read from. - * @return The string that was read, or null. - * @throws IOException On read error. - */ - public static String readNullableText(DataInput input) throws IOException { - boolean exists = input.readBoolean(); - return exists ? input.readUTF() : null; - } - - public static boolean arrayRangeEquals(byte[] array, int offset, byte[] segment) { - if (array.length < offset + segment.length) { - return false; - } - - for (int i = 0; i < segment.length; i++) { - if (segment[i] != array[i + offset]) { - return false; - } - } - - return true; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/DecodedException.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/DecodedException.java deleted file mode 100644 index 586742e..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/DecodedException.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools; - -/** - * Decoded serialized exception. The original exception class is not restored, instead all exceptions will be instances - * of this class and contain the original class name and message as fields and as the message. - */ -public class DecodedException extends Exception { - /** - * Original exception class name - */ - public final String className; - /** - * Original exception message - */ - public final String originalMessage; - - /** - * @param className Original exception class name - * @param originalMessage Original exception message - * @param cause Cause of this exception - */ - public DecodedException(String className, String originalMessage, DecodedException cause) { - super(className + ": " + originalMessage, cause, true, true); - - this.className = className; - this.originalMessage = originalMessage; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/ExceptionTools.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/ExceptionTools.java deleted file mode 100644 index 473febc..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/ExceptionTools.java +++ /dev/null @@ -1,219 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools; - -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * Contains common helper methods for dealing with exceptions. - */ -public class ExceptionTools { - private static final Logger log = LoggerFactory.getLogger(ExceptionTools.class); - - /** - * Sometimes it is necessary to catch Throwable instances for logging or reporting purposes. However, unless for - * specific known cases, Error instances should not be blocked from propagating, so rethrow them. - * - * @param throwable The Throwable to check, it is rethrown if it is an Error - */ - public static void rethrowErrors(Throwable throwable) { - if (throwable instanceof Error) { - throw (Error) throwable; - } - } - - /** - * If the exception is not a FriendlyException, wrap with a FriendlyException with the given message - * - * @param message Message of the new FriendlyException if needed - * @param severity Severity of the new FriendlyException - * @param throwable The exception to potentially wrap - * @return Original or wrapped exception - */ - public static FriendlyException wrapUnfriendlyExceptions(String message, Severity severity, Throwable throwable) { - if (throwable instanceof FriendlyException) { - return (FriendlyException) throwable; - } else { - return new FriendlyException(message, severity, throwable); - } - } - - /** - * If the exception is not a FriendlyException, wrap with a RuntimeException - * - * @param throwable The exception to potentially wrap - * @return Original or wrapped exception - */ - public static RuntimeException wrapUnfriendlyExceptions(Throwable throwable) { - if (throwable instanceof FriendlyException) { - return (FriendlyException) throwable; - } else { - return new RuntimeException(throwable); - } - } - - /** - * Finds the first exception which is an instance of the specified class from the throwable cause chain. - * - * @param throwable Throwable to scan. - * @param klass The throwable class to scan for. - * @param The throwable class to scan for. - * @return The first exception in the cause chain (including itself) which is an instance of the specified class. - */ - public static T findDeepException(Throwable throwable, Class klass) { - while (throwable != null) { - if (klass.isAssignableFrom(throwable.getClass())) { - return (T) throwable; - } - - throwable = throwable.getCause(); - } - - return null; - } - - /** - * Makes sure thread is set to interrupted state when the throwable is an InterruptedException - * - * @param throwable Throwable to check - */ - public static void keepInterrupted(Throwable throwable) { - if (throwable instanceof InterruptedException) { - Thread.currentThread().interrupt(); - } - } - - /** - * Log a FriendlyException appropriately according to its severity. - * - * @param log Logger instance to log it to - * @param exception The exception itself - * @param context An object that is included in the log - */ - public static void log(Logger log, FriendlyException exception, Object context) { - switch (exception.severity) { - case COMMON: - log.debug("Common failure for {}: {}", context, exception.getMessage()); - break; - case SUSPICIOUS: - log.warn("Suspicious exception for {}", context, exception); - break; - case FAULT: - default: - log.error("Error in {}", context, exception); - break; - } - } - - /** - * Encode an exception to an output stream - * - * @param output Data output - * @param exception Exception to encode - * @throws IOException On IO error - */ - public static void encodeException(DataOutput output, FriendlyException exception) throws IOException { - List causes = new ArrayList<>(); - Throwable next = exception.getCause(); - - while (next != null) { - causes.add(next); - next = next.getCause(); - } - - for (int i = causes.size() - 1; i >= 0; i--) { - Throwable cause = causes.get(i); - output.writeBoolean(true); - - String message; - - if (cause instanceof DecodedException) { - output.writeUTF(((DecodedException) cause).className); - message = ((DecodedException) cause).originalMessage; - } else { - output.writeUTF(cause.getClass().getName()); - message = cause.getMessage(); - } - - output.writeBoolean(message != null); - if (message != null) { - output.writeUTF(message); - } - - encodeStackTrace(output, cause); - } - - output.writeBoolean(false); - output.writeUTF(exception.getMessage()); - output.writeInt(exception.severity.ordinal()); - - encodeStackTrace(output, exception); - } - - /** - * Closes the specified closeable object. In case that throws an error, logs the error with WARN level, but does not - * rethrow. - * - * @param closeable Object to close. - */ - public static void closeWithWarnings(AutoCloseable closeable) { - try { - closeable.close(); - } catch (Exception e) { - log.warn("Failed to close.", e); - } - } - - private static void encodeStackTrace(DataOutput output, Throwable throwable) throws IOException { - StackTraceElement[] trace = throwable.getStackTrace(); - output.writeInt(trace.length); - - for (StackTraceElement element : trace) { - output.writeUTF(element.getClassName()); - output.writeUTF(element.getMethodName()); - - String fileName = element.getFileName(); - output.writeBoolean(fileName != null); - if (fileName != null) { - output.writeUTF(fileName); - } - output.writeInt(element.getLineNumber()); - } - } - - /** - * Decode an exception from an input stream - * - * @param input Data input - * @return Decoded exception - * @throws IOException On IO error - */ - public static FriendlyException decodeException(DataInput input) throws IOException { - DecodedException cause = null; - - while (input.readBoolean()) { - cause = new DecodedException(input.readUTF(), input.readBoolean() ? input.readUTF() : null, cause); - cause.setStackTrace(decodeStackTrace(input)); - } - - FriendlyException exception = new FriendlyException(input.readUTF(), Severity.class.getEnumConstants()[input.readInt()], cause); - exception.setStackTrace(decodeStackTrace(input)); - return exception; - } - - private static StackTraceElement[] decodeStackTrace(DataInput input) throws IOException { - StackTraceElement[] trace = new StackTraceElement[input.readInt()]; - - for (int i = 0; i < trace.length; i++) { - trace[i] = new StackTraceElement(input.readUTF(), input.readUTF(), input.readBoolean() ? input.readUTF() : null, input.readInt()); - } - - return trace; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/FriendlyException.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/FriendlyException.java deleted file mode 100644 index 54bf649..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/FriendlyException.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools; - -/** - * An exception with a friendly message. - */ -public class FriendlyException extends RuntimeException { - /** - * Severity of the exception - */ - public final Severity severity; - - /** - * @param friendlyMessage A message which is understandable to end-users - * @param severity Severity of the exception - * @param cause The cause of the exception with technical details - */ - public FriendlyException(String friendlyMessage, Severity severity, Throwable cause) { - super(friendlyMessage, cause); - - this.severity = severity; - } - - /** - * Severity levels for FriendlyException - */ - public enum Severity { - /** - * The cause is known and expected, indicates that there is nothing wrong with the library itself. - */ - COMMON, - /** - * The cause might not be exactly known, but is possibly caused by outside factors. For example when an outside - * service responds in a format that we do not expect. - */ - SUSPICIOUS, - /** - * If the probable cause is an issue with the library or when there is no way to tell what the cause might be. - * This is the default level and other levels are used in cases where the thrower has more in-depth knowledge - * about the error. - */ - FAULT - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/GarbageCollectionMonitor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/GarbageCollectionMonitor.java deleted file mode 100644 index a6a6937..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/GarbageCollectionMonitor.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools; - -import com.sun.management.GarbageCollectionNotificationInfo; -import com.sun.management.GcInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.management.ListenerNotFoundException; -import javax.management.Notification; -import javax.management.NotificationEmitter; -import javax.management.NotificationListener; -import javax.management.openmbean.CompositeData; -import java.lang.management.GarbageCollectorMXBean; -import java.lang.management.ManagementFactory; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -import static com.sun.management.GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION; -import static com.sun.management.GarbageCollectionNotificationInfo.from; - -/** - * Garbage collection monitor which records all GC pause lengths and logs them. In case the GC pause statistics are - * considered bad for latency, the statistics are logged at a warning level. - */ -public class GarbageCollectionMonitor implements NotificationListener, Runnable { - private static final Logger log = LoggerFactory.getLogger(GarbageCollectionMonitor.class); - - private static final long REPORTING_FREQUENCY = TimeUnit.MINUTES.toMillis(2); - private static final long[] BUCKETS = new long[]{2000, 500, 200, 50, 20, 0}; - - private final ScheduledExecutorService reportingExecutor; - private final int[] bucketCounters; - private final AtomicBoolean enabled; - private final AtomicReference> executorFuture; - - /** - * Create an instance of GC monitor. Does nothing until enabled. - * - * @param reportingExecutor Executor to use for scheduling reporting task - */ - public GarbageCollectionMonitor(ScheduledExecutorService reportingExecutor) { - this.reportingExecutor = reportingExecutor; - bucketCounters = new int[BUCKETS.length]; - enabled = new AtomicBoolean(); - executorFuture = new AtomicReference<>(); - } - - /** - * Enable GC monitoring and reporting. - */ - public void enable() { - if (enabled.compareAndSet(false, true)) { - registerBeanListener(); - - executorFuture.set(reportingExecutor.scheduleAtFixedRate(this, REPORTING_FREQUENCY, REPORTING_FREQUENCY, TimeUnit.MILLISECONDS)); - - log.info("GC monitoring enabled, reporting results every 2 minutes."); - } - } - - /** - * Disable GC monitoring and reporting. - */ - public void disable() { - if (enabled.compareAndSet(true, false)) { - unregisterBeanListener(); - - ScheduledFuture scheduledTask = executorFuture.getAndSet(null); - if (scheduledTask != null) { - scheduledTask.cancel(false); - } - - log.info("GC monitoring disabled."); - } - } - - private void registerBeanListener() { - for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) { - if (gcBean instanceof NotificationEmitter) { - ((NotificationEmitter) gcBean).addNotificationListener(this, null, gcBean); - } - } - } - - private void unregisterBeanListener() { - for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) { - if (gcBean instanceof NotificationEmitter) { - try { - ((NotificationEmitter) gcBean).removeNotificationListener(this); - } catch (ListenerNotFoundException e) { - log.debug("No listener found on bean {}, should have been there.", gcBean, e); - } - } - } - } - - private void registerPause(long duration) { - synchronized (bucketCounters) { - for (int i = 0; i < bucketCounters.length; i++) { - if (duration >= BUCKETS[i]) { - bucketCounters[i]++; - break; - } - } - } - } - - @Override - public void handleNotification(Notification notification, Object handback) { - if (GARBAGE_COLLECTION_NOTIFICATION.equals(notification.getType())) { - GarbageCollectionNotificationInfo notificationInfo = from((CompositeData) notification.getUserData()); - GcInfo info = notificationInfo.getGcInfo(); - - if (info != null && !"No GC".equals(notificationInfo.getGcCause())) { - registerPause(info.getDuration()); - } - } - } - - @Override - public void run() { - StringBuilder statistics = new StringBuilder(); - boolean hasBadLatency; - - synchronized (bucketCounters) { - hasBadLatency = bucketCounters[3] > 1 || bucketCounters[2] > 0; - - for (int i = bucketCounters.length - 1; i >= 0; i--) { - statistics.append(String.format("[Bucket %d = %d] ", BUCKETS[i], bucketCounters[i])); - bucketCounters[i] = 0; - } - } - - if (hasBadLatency) { - log.warn("Suspicious GC results for the last 2 minutes: {}", statistics); - } else { - log.debug("GC results for the last 2 minutes: {}", statistics); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/JsonBrowser.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/JsonBrowser.java deleted file mode 100644 index 8547550..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/JsonBrowser.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools; - -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Allows to easily navigate in decoded JSON data - */ -public class JsonBrowser { - private static final ObjectMapper mapper = setupMapper(); - - private final Object value; - - private JsonBrowser(Object value) { - this.value = value; - } - - /** - * @return True if the value represents a list. - */ - public boolean isList() { - return value instanceof List; - } - - /** - * @return True if the value represents a map. - */ - public boolean isMap() { - return value instanceof Map; - } - - /** - * Get an element at an index for a list value - * - * @param index List index - * @return JsonBrowser instance which wraps the value at the specified index - */ - public JsonBrowser index(int index) { - if (value instanceof List) { - return new JsonBrowser(((List) value).get(index)); - } else { - throw new IllegalStateException("Index only works on a list"); - } - } - - /** - * Get an element by key from a map value - * - * @param key Map key - * @return JsonBrowser instance which wraps the value with the specified key - */ - public JsonBrowser get(Object key) { - if (value instanceof Map) { - return new JsonBrowser(((Map) value).get(key)); - } else { - throw new IllegalStateException("Get only works on a map"); - } - } - - /** - * Get an element by key from a map value - * - * @param key Map key - * @return JsonBrowser instance which wraps the value with the specified key - */ - public JsonBrowser safeGet(Object key) { - if (value instanceof Map) { - return new JsonBrowser(((Map) value).get(key)); - } else { - return new JsonBrowser(null); - } - } - - /** - * Put a value into the map if this instance contains a map. - * - * @param key The map entry key - * @param item The map entry value - */ - @SuppressWarnings("unchecked") - public void put(String key, Object item) { - if (value instanceof Map) { - ((Map) value).put(key, item); - } else { - throw new IllegalStateException("Put only works on a map"); - } - } - - /** - * Returns a list of all the values in this element - * - * @return The list of values as JsonBrowser elements - */ - public List values() { - List values = new ArrayList<>(); - if (value instanceof Map) { - for (Object object : ((Map) value).values()) { - values.add(new JsonBrowser(object)); - } - } else if (value instanceof List) { - for (Object object : (List) value) { - values.add(new JsonBrowser(object)); - } - } - return values; - } - - /** - * Attempt to retrieve the value in the specified format - * - * @param klass The class to retrieve the value as - * @return The value as an instance of the specified class - * @throws IllegalArgumentException If conversion is impossible - */ - public T as(Class klass) { - return mapper.convertValue(value, klass); - } - - /** - * @return The value of the element as text - */ - public String text() { - return value != null ? value.toString() : null; - } - - /** - * @return The value of the element as text - */ - public boolean isNull() { - return value == null; - } - - /** - * Parse from string. - * - * @param json The JSON object as a string - * @return JsonBrowser instance for navigating in the result - * @throws IOException When parsing the JSON failed - */ - public static JsonBrowser parse(String json) throws IOException { - return new JsonBrowser(mapper.readValue(json, Object.class)); - } - - /** - * Parse from string. - * - * @param stream The JSON object as a stream - * @return JsonBrowser instance for navigating in the result - * @throws IOException When parsing the JSON failed - */ - public static JsonBrowser parse(InputStream stream) throws IOException { - return new JsonBrowser(mapper.readValue(stream, Object.class)); - } - - private static ObjectMapper setupMapper() { - JsonFactory jsonFactory = new JsonFactory(); - jsonFactory.enable(JsonParser.Feature.ALLOW_COMMENTS); - jsonFactory.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES); - return new ObjectMapper(jsonFactory); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/OrderedExecutor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/OrderedExecutor.java deleted file mode 100644 index 6b89a0d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/OrderedExecutor.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools; - -import java.util.concurrent.*; - -/** - * Wrapper for executor services which ensures that tasks with the same key are processed in order. - */ -public class OrderedExecutor { - private final ExecutorService delegateService; - private final ConcurrentMap> states; - - /** - * @param delegateService Executor service where to delegate the actual execution to - */ - public OrderedExecutor(ExecutorService delegateService) { - this.delegateService = delegateService; - this.states = new ConcurrentHashMap<>(); - } - - /** - * @param orderingKey Key for the ordering channel - * @param runnable Runnable to submit to the executor service - * @return Future for the task - */ - public Future submit(Object orderingKey, Runnable runnable) { - RunnableFuture runnableFuture = newTaskFor(runnable, null); - queueOrSubmit(new ChannelRunnable(orderingKey), runnableFuture); - return runnableFuture; - } - - /** - * @param orderingKey Key for the ordering channel - * @param callable Callable to submit to the executor service - * @return Future for the task - */ - public Future submit(Object orderingKey, Callable callable) { - RunnableFuture runnableFuture = newTaskFor(callable); - queueOrSubmit(new ChannelRunnable(orderingKey), runnableFuture); - return runnableFuture; - } - - private void queueOrSubmit(ChannelRunnable runnable, Runnable delegate) { - BlockingQueue newQueue = new LinkedBlockingQueue<>(); - newQueue.add(delegate); - - BlockingQueue existing = states.putIfAbsent(runnable.key, newQueue); - - if (existing != null) { - existing.add(delegate); - - if (states.putIfAbsent(runnable.key, existing) == null) { - delegateService.execute(new ChannelRunnable(runnable.key)); - } - } else { - delegateService.execute(runnable); - } - } - - private RunnableFuture newTaskFor(Runnable runnable, T value) { - return new FutureTask<>(runnable, value); - } - - private RunnableFuture newTaskFor(Callable callable) { - return new FutureTask<>(callable); - } - - private class ChannelRunnable implements Runnable { - private final Object key; - - private ChannelRunnable(Object key) { - this.key = key; - } - - @Override - public void run() { - BlockingQueue queue = states.get(key); - - if (queue != null) { - executeQueue(queue); - } - } - - private void executeQueue(BlockingQueue queue) { - Runnable next; - - while ((next = queue.poll()) != null) { - boolean finished = false; - - try { - next.run(); - finished = true; - } finally { - if (!finished) { - delegateService.execute(new ChannelRunnable(key)); - } - } - } - - states.remove(key, queue); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/PlayerLibrary.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/PlayerLibrary.java deleted file mode 100644 index 260e38b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/PlayerLibrary.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools; - -import org.apache.commons.io.IOUtils; - -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - -/** - * Contains constants with metadata about the library. - */ -public class PlayerLibrary { - /** - * The currently loaded version of the library. - */ - public static final String VERSION = readVersion(); - - private static String readVersion() { - InputStream stream = PlayerLibrary.class.getResourceAsStream("version.txt"); - - try { - if (stream != null) { - return IOUtils.toString(stream, StandardCharsets.UTF_8); - } - } catch (Exception e) { - // Something went wrong. - } - - return "UNKNOWN"; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/RingBufferMath.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/RingBufferMath.java deleted file mode 100644 index 9cbc975..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/RingBufferMath.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools; - -import java.util.function.Function; - -/** - * Utility class for calculating averages on the last N values, with input and output transformers. - */ -public class RingBufferMath { - private final double[] values; - private final Function inputProcessor; - private final Function outputProcessor; - private double sum; - private int position; - private int size; - - /** - * @param size Maximum number of values to remember. - * @param inputProcessor Input transformer. - * @param outputProcessor Output transformer. - */ - public RingBufferMath(int size, Function inputProcessor, Function outputProcessor) { - this.values = new double[size]; - this.inputProcessor = inputProcessor; - this.outputProcessor = outputProcessor; - } - - /** - * @param value Original value to add (before transformation) - */ - public void add(double value) { - value = inputProcessor.apply(value); - - sum -= values[position]; - values[position] = value; - sum += values[position]; - - position = (position + 1) == values.length ? 0 : position + 1; - size = Math.min(values.length, size + 1); - } - - /** - * @return Transformed mean of the internal values. - */ - public double mean() { - if (size == 0) { - return outputProcessor.apply(0.0); - } else { - return outputProcessor.apply(sum / size); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/AbstractHttpInterfaceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/AbstractHttpInterfaceManager.java deleted file mode 100644 index 75dc7fc..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/AbstractHttpInterfaceManager.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Base class for an HTTP interface manager with lazily initialized http client instance. - */ -public abstract class AbstractHttpInterfaceManager implements HttpInterfaceManager { - private static final Logger log = LoggerFactory.getLogger(AbstractHttpInterfaceManager.class); - - private final HttpClientBuilder clientBuilder; - private final Object lock; - private boolean closed; - private CloseableHttpClient sharedClient; - private RequestConfig requestConfig; - - /** - * @param clientBuilder HTTP client builder to use for creating the client instance. - * @param requestConfig Request config used by the client builder - */ - public AbstractHttpInterfaceManager(HttpClientBuilder clientBuilder, RequestConfig requestConfig) { - this.clientBuilder = clientBuilder; - this.requestConfig = requestConfig; - this.lock = new Object(); - } - - @Override - public void close() throws IOException { - synchronized (lock) { - closed = true; - - if (sharedClient != null) { - CloseableHttpClient client = sharedClient; - sharedClient = null; - client.close(); - } - } - } - - @Override - public void configureRequests(Function configurator) { - synchronized (lock) { - try { - close(); - } catch (Exception e) { - log.warn("Failed to close HTTP client.", e); - } - - closed = false; - requestConfig = configurator.apply(requestConfig); - clientBuilder.setDefaultRequestConfig(requestConfig); - } - } - - @Override - public void configureBuilder(Consumer configurator) { - synchronized (lock) { - try { - close(); - } catch (Exception e) { - log.warn("Failed to close HTTP client.", e); - } - - closed = false; - configurator.accept(clientBuilder); - } - } - - protected CloseableHttpClient getSharedClient() { - synchronized (lock) { - if (closed) { - throw new IllegalStateException("Cannot get http client for a closed manager."); - } - - if (sharedClient == null) { - sharedClient = clientBuilder.build(); - } - - return sharedClient; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitBufferReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitBufferReader.java deleted file mode 100644 index f0cf165..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitBufferReader.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * Helper for reading a specific number of bits at a time from a byte buffer. - */ -public class BitBufferReader extends BitStreamReader { - private final ByteBuffer buffer; - - /** - * @param buffer Byte buffer to read bytes from - */ - public BitBufferReader(ByteBuffer buffer) { - super(null); - - this.buffer = buffer; - } - - @Override - public long asLong(int bitsNeeded) { - try { - return super.asLong(bitsNeeded); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public int asInteger(int bitsNeeded) { - try { - return super.asInteger(bitsNeeded); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - protected int readByte() throws IOException { - return buffer.get() & 0xFF; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitStreamReader.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitStreamReader.java deleted file mode 100644 index 6c21032..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitStreamReader.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; - -/** - * Helper for reading a specific number of bits at a time from a stream. - */ -public class BitStreamReader { - private final InputStream stream; - private int currentByte; - private int bitsLeft; - - /** - * @param stream The underlying stream - */ - public BitStreamReader(InputStream stream) { - this.stream = stream; - } - - /** - * Get the specified number of bits as a long value - * - * @param bitsNeeded Number of bits to retrieve - * @return The value of those bits as a long - * @throws IOException On read error - */ - public long asLong(int bitsNeeded) throws IOException { - long value = 0; - - while (bitsNeeded > 0) { - fill(); - - int chunk = Math.min(bitsNeeded, bitsLeft); - int mask = (1 << chunk) - 1; - - value <<= chunk; - value |= (currentByte >> (bitsLeft - chunk)) & mask; - - bitsNeeded -= chunk; - bitsLeft -= chunk; - } - - return value; - } - - /** - * Get the specific number of bits as a signed long value (highest order bit is sign) - * - * @param bitsNeeded Number of bits needed - * @return The signed value - * @throws IOException On read error - */ - public long asSignedLong(int bitsNeeded) throws IOException { - long value = asLong(bitsNeeded); - - if ((value & (1L << (bitsNeeded - 1))) != 0) { - return value | ~((1L << bitsNeeded) - 1); - } else { - return value; - } - } - - /** - * Get the specified number of bits as an integer value - * - * @param bitsNeeded Number of bits to retrieve - * @return The value of those bits as an integer - * @throws IOException On read error - */ - public int asInteger(int bitsNeeded) throws IOException { - return Math.toIntExact(asLong(bitsNeeded)); - } - - /** - * Get the specific number of bits as a signed integer value (highest order bit is sign) - * - * @param bitsNeeded Number of bits needed - * @return The signed value - * @throws IOException On read error - */ - public int asSignedInteger(int bitsNeeded) throws IOException { - return Math.toIntExact(asSignedLong(bitsNeeded)); - } - - /** - * Reads bits from the stream until a set bit is reached. - * - * @return The number of zeroes read - * @throws IOException On read error - */ - public int readAllZeroes() throws IOException { - int count = 0; - fill(); - - while ((currentByte & (1 << --bitsLeft)) == 0) { - count++; - fill(); - } - - return count; - } - - /** - * Reads the number of bits it requires to make the reader align on a byte. - * - * @return The read bits as an unsigned value - */ - public int readRemainingBits() { - int value = currentByte & ((1 << bitsLeft) - 1); - bitsLeft = 0; - return value; - } - - private void fill() throws IOException { - if (bitsLeft == 0) { - currentByte = readByte(); - bitsLeft = 8; - - if (currentByte == -1) { - throw new EOFException("Bit stream needs more bytes"); - } - } - } - - protected int readByte() throws IOException { - return stream.read(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitStreamWriter.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitStreamWriter.java deleted file mode 100644 index 4693cdc..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/BitStreamWriter.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Helper for writing a specific number of bits at a time to a stream. - */ -public class BitStreamWriter { - private final OutputStream stream; - private int currentByte; - private int bitsUnused; - - /** - * @param stream The underlying stream - */ - public BitStreamWriter(OutputStream stream) { - this.stream = stream; - bitsUnused = 8; - } - - /** - * @param value The value to take the bits from (lower order bits first) - * @param bits Number of bits to write - * @throws IOException On write error - */ - public void write(long value, int bits) throws IOException { - int bitsToPush = bits; - - while (bitsToPush > 0) { - int chunk = Math.min(bitsUnused, bitsToPush); - int mask = (1 << chunk) - 1; - - currentByte |= (((int) (value >> (bitsToPush - chunk))) & mask) << (bitsUnused - chunk); - - sendOnFullByte(); - - bitsToPush -= chunk; - bitsUnused -= chunk; - } - } - - private void sendOnFullByte() throws IOException { - if (bitsUnused == 0) { - stream.write(currentByte); - bitsUnused = 8; - currentByte = 0; - } - } - - /** - * Flush the current byte even if there are remaining unused bits left - * - * @throws IOException On write error - */ - public void flush() throws IOException { - if (bitsUnused < 8) { - stream.write(currentByte); - } - - bitsUnused = 8; - currentByte = 0; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ByteBufferInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ByteBufferInputStream.java deleted file mode 100644 index 9939557..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ByteBufferInputStream.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; - -/** - * A byte buffer exposed as an input stream. - */ -public class ByteBufferInputStream extends InputStream { - private final ByteBuffer buffer; - - /** - * @param buffer The buffer to read from. - */ - public ByteBufferInputStream(ByteBuffer buffer) { - this.buffer = buffer; - } - - @Override - public int read() throws IOException { - if (buffer.hasRemaining()) { - return buffer.get() & 0xFF; - } else { - return -1; - } - } - - @Override - public int read(byte[] array, int offset, int length) throws IOException { - if (buffer.hasRemaining()) { - int chunk = Math.min(buffer.remaining(), length); - buffer.get(array, offset, length); - return chunk; - } else { - return -1; - } - } - - @Override - public int available() throws IOException { - return buffer.remaining(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ByteBufferOutputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ByteBufferOutputStream.java deleted file mode 100644 index 943380a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ByteBufferOutputStream.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -/** - * A byte buffer wrapped in an output stream. - */ -public class ByteBufferOutputStream extends OutputStream { - private final ByteBuffer buffer; - - /** - * @param buffer The underlying byte buffer - */ - public ByteBufferOutputStream(ByteBuffer buffer) { - this.buffer = buffer; - } - - @Override - public void write(int b) throws IOException { - buffer.put((byte) b); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - buffer.put(b, off, len); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ChainedInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ChainedInputStream.java deleted file mode 100644 index 0c2b7c7..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ChainedInputStream.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Input stream which can swap the underlying input stream if the current one ends. - */ -public class ChainedInputStream extends InputStream { - private final Provider provider; - private InputStream currentStream; - private boolean streamEnded; - - /** - * @param provider Provider for input streams to chain. - */ - public ChainedInputStream(Provider provider) { - this.provider = provider; - } - - private boolean loadNextStream() throws IOException { - if (!streamEnded) { - close(); - - currentStream = provider.next(); - - if (currentStream == null) { - streamEnded = true; - } - } - - return !streamEnded; - } - - @Override - public int read() throws IOException { - if (streamEnded || (currentStream == null && !loadNextStream())) { - return -1; - } - - int result; - int emptyStreamCount = 0; - - while ((result = currentStream.read()) == -1 && ++emptyStreamCount < 5) { - if (!loadNextStream()) { - return -1; - } - } - - return result; - } - - @Override - public int read(byte[] buffer, int offset, int length) throws IOException { - if (streamEnded || (currentStream == null && !loadNextStream())) { - return -1; - } - - int result; - int emptyStreamCount = 0; - - while ((result = currentStream.read(buffer, offset, length)) == -1 && ++emptyStreamCount < 5) { - if (!loadNextStream()) { - return -1; - } - } - - return result; - } - - @Override - public long skip(long distance) throws IOException { - if (streamEnded || (currentStream == null && !loadNextStream())) { - return -1; - } - - long result; - int emptyStreamCount = 0; - - while ((result = currentStream.skip(distance)) == 0 && ++emptyStreamCount < 5) { - if (!loadNextStream()) { - return 0; - } - } - - return result; - } - - @Override - public void close() throws IOException { - if (currentStream != null) { - currentStream.close(); - currentStream = null; - } - } - - @Override - public boolean markSupported() { - return false; - } - - /** - * Provider for next input stream of a chained stream. - */ - public interface Provider { - /** - * @return Next input stream, null to cause EOF on the chained stream. - * @throws IOException On read error. - */ - InputStream next() throws IOException; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/DetachedByteChannel.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/DetachedByteChannel.java deleted file mode 100644 index bbe2627..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/DetachedByteChannel.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.ClosedChannelException; -import java.nio.channels.ReadableByteChannel; - -/** - * Creates a readable byte channel which can be closed without closing the underlying channel. - */ -public class DetachedByteChannel implements ReadableByteChannel { - private final ReadableByteChannel delegate; - private boolean closed; - - /** - * @param delegate The underlying channel - */ - public DetachedByteChannel(ReadableByteChannel delegate) { - this.delegate = delegate; - } - - @Override - public int read(ByteBuffer output) throws IOException { - if (closed) { - throw new ClosedChannelException(); - } - - return delegate.read(output); - } - - @Override - public boolean isOpen() { - return !closed && delegate.isOpen(); - } - - @Override - public void close() throws IOException { - closed = true; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/DirectBufferStreamBroker.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/DirectBufferStreamBroker.java deleted file mode 100644 index 3d1e3f3..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/DirectBufferStreamBroker.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; - -/** - * A helper class to consume the entire contents of a stream into a direct byte buffer. Designed for cases where this is - * repeated several times, as it supports resetting. - */ -public class DirectBufferStreamBroker { - private final byte[] copyBuffer; - private final int initialSize; - private int readByteCount; - private ByteBuffer currentBuffer; - - /** - * @param initialSize Initial size of the underlying direct buffer. - */ - public DirectBufferStreamBroker(int initialSize) { - this.initialSize = initialSize; - this.copyBuffer = new byte[512]; - this.currentBuffer = ByteBuffer.allocateDirect(initialSize); - } - - /** - * Reset the buffer to its initial size. - */ - public void resetAndCompact() { - currentBuffer = ByteBuffer.allocateDirect(initialSize); - } - - /** - * Clear the underlying buffer. - */ - public void clear() { - currentBuffer.clear(); - } - - /** - * @return A duplicate of the underlying buffer. - */ - public ByteBuffer getBuffer() { - ByteBuffer buffer = currentBuffer.duplicate(); - buffer.flip(); - return buffer; - } - - public boolean isTruncated() { - return currentBuffer.position() < readByteCount; - } - - /** - * Copies the final state after a {@link #consumeNext(InputStream, int, int)} operation into a new byte array. - * - * @return New byte array containing consumed data. - */ - public byte[] extractBytes() { - byte[] data = new byte[currentBuffer.position()]; - currentBuffer.position(0); - currentBuffer.get(data, 0, data.length); - return data; - } - - /** - * Consume an entire stream and append it into the buffer (or clear first if clear parameter is true). - * - * @param inputStream The input stream to fully consume. - * @param maximumSavedBytes Maximum number of bytes to save internally. If this is exceeded, it will continue reading - * and discarding until maximum read byte count is reached. - * @param maximumReadBytes Maximum number of bytes to read. - * @return If stream was fully read before {@code maximumReadBytes} was reached, returns {@code true}. Returns - * {@code false} if the number of bytes read is {@code maximumReadBytes}, even if no more data is left in the - * stream. - * @throws IOException On read error - */ - public boolean consumeNext(InputStream inputStream, int maximumSavedBytes, int maximumReadBytes) throws IOException { - currentBuffer.clear(); - readByteCount = 0; - - ensureCapacity(Math.min(maximumSavedBytes, inputStream.available())); - - while (readByteCount < maximumReadBytes) { - int maximumReadFragment = Math.min(copyBuffer.length, maximumReadBytes - readByteCount); - int fragmentLength = inputStream.read(copyBuffer, 0, maximumReadFragment); - - if (fragmentLength == -1) { - return true; - } - - int bytesToSave = Math.min(fragmentLength, maximumSavedBytes - readByteCount); - - if (bytesToSave > 0) { - ensureCapacity(currentBuffer.position() + bytesToSave); - currentBuffer.put(copyBuffer, 0, bytesToSave); - } - } - - return false; - } - - private void ensureCapacity(int capacity) { - if (capacity > currentBuffer.capacity()) { - ByteBuffer newBuffer = ByteBuffer.allocateDirect(currentBuffer.capacity() << 1); - currentBuffer.flip(); - - newBuffer.put(currentBuffer); - currentBuffer = newBuffer; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/EmptyInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/EmptyInputStream.java deleted file mode 100644 index 93dca6e..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/EmptyInputStream.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.InputStream; - -/** - * Represents an empty input stream. - */ -public class EmptyInputStream extends InputStream { - public static final EmptyInputStream INSTANCE = new EmptyInputStream(); - - @Override - public int available() { - return 0; - } - - @Override - public int read() { - return -1; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ExtendedBufferedInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ExtendedBufferedInputStream.java deleted file mode 100644 index eaf8927..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ExtendedBufferedInputStream.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.BufferedInputStream; -import java.io.InputStream; - -/** - * A buffered input stream that gives with the ability to get the number of bytes left in the buffer and a method for - * discarding the buffer. - */ -public class ExtendedBufferedInputStream extends BufferedInputStream { - /** - * @param in Underlying input stream - */ - public ExtendedBufferedInputStream(InputStream in) { - super(in); - } - - /** - * @param in Underlying input stream - * @param size Size of the buffer - */ - public ExtendedBufferedInputStream(InputStream in, int size) { - super(in, size); - } - - /** - * @return The number of bytes left in the buffer. This is useful for calculating the actual position in the buffer - * if the position in the underlying buffer is known. - */ - public int getBufferedByteCount() { - return count - pos; - } - - /** - * Discard the remaining buffer. This should be called after seek has been performed on the underlying stream. - */ - public void discardBuffer() { - pos = count; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/GreedyInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/GreedyInputStream.java deleted file mode 100644 index 63e48da..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/GreedyInputStream.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * Input stream wrapper which reads or skips until EOF or requested length. - */ -public class GreedyInputStream extends FilterInputStream { - /** - * @param in Underlying input stream. - */ - public GreedyInputStream(InputStream in) { - super(in); - } - - @Override - public int read(byte[] buffer, int offset, int length) throws IOException { - int read = 0; - - while (read < length) { - int chunk = in.read(buffer, offset + read, length - read); - if (chunk == -1) { - return read == 0 ? -1 : read; - } - read += chunk; - } - - return read; - } - - @Override - public long skip(long maximum) throws IOException { - long skipped = 0; - - while (skipped < maximum) { - long chunk = in.skip(maximum - skipped); - if (chunk == 0) { - if (in.read() == -1) { - break; - } else { - chunk = 1; - } - } - skipped += chunk; - } - - return skipped; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpClientTools.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpClientTools.java deleted file mode 100644 index 53baae0..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpClientTools.java +++ /dev/null @@ -1,391 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser; -import org.apache.http.*; -import org.apache.http.client.CookieStore; -import org.apache.http.client.RedirectStrategy; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.config.MessageConstraints; -import org.apache.http.config.Registry; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.conn.ssl.DefaultHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.util.PublicSuffixMatcherLoader; -import org.apache.http.impl.DefaultHttpResponseFactory; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.conn.DefaultHttpResponseParser; -import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.io.SessionInputBuffer; -import org.apache.http.message.BasicLineParser; -import org.apache.http.message.LineParser; -import org.apache.http.message.ParserCursor; -import org.apache.http.protocol.HttpContext; -import org.apache.http.ssl.SSLContexts; -import org.apache.http.util.CharArrayBuffer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLException; -import javax.net.ssl.X509TrustManager; -import java.io.IOException; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; - -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.COMMON; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; - -/** - * Tools for working with HttpClient - */ -public class HttpClientTools { - private static final Logger log = LoggerFactory.getLogger(HttpClientTools.class); - - private static final SSLContext defaultSslContext = setupSslContext(); - - public static final RequestConfig DEFAULT_REQUEST_CONFIG = RequestConfig.custom() - .setConnectTimeout(3000) - .setCookieSpec(CookieSpecs.STANDARD) - .build(); - - private static final RequestConfig NO_COOKIES_REQUEST_CONFIG = RequestConfig.custom() - .setConnectTimeout(3000) - .setCookieSpec(CookieSpecs.IGNORE_COOKIES) - .build(); - - /** - * @return An HttpClientBuilder which uses the same cookie store for all clients - */ - public static HttpClientBuilder createSharedCookiesHttpBuilder() { - return createHttpBuilder(DEFAULT_REQUEST_CONFIG); - } - - /** - * @return Default HTTP interface manager with thread-local context - */ - public static HttpInterfaceManager createDefaultThreadLocalManager() { - return new ThreadLocalHttpInterfaceManager(createSharedCookiesHttpBuilder(), DEFAULT_REQUEST_CONFIG); - } - - /** - * @return HTTP interface manager with thread-local context, ignores cookies - */ - public static HttpInterfaceManager createCookielessThreadLocalManager() { - return new ThreadLocalHttpInterfaceManager(createHttpBuilder(NO_COOKIES_REQUEST_CONFIG), NO_COOKIES_REQUEST_CONFIG); - } - - private static HttpClientBuilder createHttpBuilder(RequestConfig requestConfig) { - CookieStore cookieStore = new BasicCookieStore(); - - return new CustomHttpClientBuilder() - .setDefaultCookieStore(cookieStore) - .setRetryHandler(NoResponseRetryHandler.RETRY_INSTANCE) - .setDefaultRequestConfig(requestConfig); - } - - private static SSLContext setupSslContext() { - try { - X509TrustManager trustManager = new TrustManagerBuilder() - .addBuiltinCertificates() - .addFromResourceDirectory("/certificates") - .build(); - - SSLContext context = SSLContext.getInstance("TLS"); - context.init(null, new X509TrustManager[]{trustManager}, null); - return context; - } catch (Exception e) { - log.error("Failed to build custom SSL context, using default one.", e); - return SSLContexts.createDefault(); - } - } - - private static class GarbageAllergicHttpResponseParser extends DefaultHttpResponseParser { - public GarbageAllergicHttpResponseParser(SessionInputBuffer buffer, LineParser lineParser, HttpResponseFactory responseFactory, MessageConstraints constraints) { - super(buffer, lineParser, responseFactory, constraints); - } - - @Override - protected boolean reject(CharArrayBuffer line, int count) { - if (line.length() > 4 && "ICY ".equals(line.substring(0, 4))) { - throw new FriendlyException("ICY protocol is not supported.", COMMON, null); - } else if (count > 10) { - throw new FriendlyException("The server is giving us garbage.", SUSPICIOUS, null); - } - - return false; - } - } - - private static class IcyHttpLineParser extends BasicLineParser { - private static final IcyHttpLineParser ICY_INSTANCE = new IcyHttpLineParser(); - private static final ProtocolVersion ICY_PROTOCOL = new ProtocolVersion("HTTP", 1, 0); - - @Override - public ProtocolVersion parseProtocolVersion(CharArrayBuffer buffer, ParserCursor cursor) { - int index = cursor.getPos(); - int bound = cursor.getUpperBound(); - - if (bound >= index + 4 && "ICY ".equals(buffer.substring(index, index + 4))) { - cursor.updatePos(index + 4); - return ICY_PROTOCOL; - } - - return super.parseProtocolVersion(buffer, cursor); - } - - @Override - public boolean hasProtocolVersion(CharArrayBuffer buffer, ParserCursor cursor) { - int index = cursor.getPos(); - int bound = cursor.getUpperBound(); - - if (bound >= index + 4 && "ICY ".equals(buffer.substring(index, index + 4))) { - return true; - } - - return super.hasProtocolVersion(buffer, cursor); - } - } - - /** - * Custom HTTP client builder which applies our custom modifications. - */ - public static class CustomHttpClientBuilder extends HttpClientBuilder { - private SSLContext sslContextOverride; - - @Override - public synchronized CloseableHttpClient build() { - setConnectionManager(createConnectionManager()); - CloseableHttpClient httpClient = super.build(); - setConnectionManager(null); - return httpClient; - } - - /** - * @param sslContextOverride SSL context to make the built clients use. Note that calling - * {@link #setSSLContext(SSLContext)} has no effect because this class cannot access the - * instance set with that nor override the method. - */ - public void setSslContextOverride(SSLContext sslContextOverride) { - this.sslContextOverride = sslContextOverride; - } - - private HttpClientConnectionManager createConnectionManager() { - PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(createConnectionSocketFactory(), - createConnectionFactory()); - - manager.setMaxTotal(3000); - manager.setDefaultMaxPerRoute(1500); - - return manager; - } - - private Registry createConnectionSocketFactory() { - HostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(PublicSuffixMatcherLoader.getDefault()); - ConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextOverride != null ? - sslContextOverride : defaultSslContext, hostnameVerifier); - - return RegistryBuilder.create() - .register("http", PlainConnectionSocketFactory.getSocketFactory()) - .register("https", sslSocketFactory) - .build(); - } - - private static ManagedHttpClientConnectionFactory createConnectionFactory() { - return new ManagedHttpClientConnectionFactory(null, (buffer, constraints) -> { - return new GarbageAllergicHttpResponseParser(buffer, IcyHttpLineParser.ICY_INSTANCE, DefaultHttpResponseFactory.INSTANCE, constraints); - }); - } - } - - /** - * A redirect strategy which does not follow any redirects. - */ - public static class NoRedirectsStrategy implements RedirectStrategy { - @Override - public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException { - return false; - } - - @Override - public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException { - return null; - } - } - - /** - * @param requestUrl URL of the original request. - * @param response Response object. - * @return A redirect location if the status code indicates a redirect and the Location header is present. - */ - public static String getRedirectLocation(String requestUrl, HttpResponse response) { - if (!isRedirectStatus(response.getStatusLine().getStatusCode())) { - return null; - } - - Header header = response.getFirstHeader("Location"); - if (header == null) { - return null; - } - - String location = header.getValue(); - - try { - return new URI(requestUrl).resolve(location).toString(); - } catch (URISyntaxException e) { - log.debug("Failed to parse URI.", e); - return location; - } - } - - private static boolean isRedirectStatus(int statusCode) { - switch (statusCode) { - case HttpStatus.SC_MOVED_PERMANENTLY: - case HttpStatus.SC_MOVED_TEMPORARILY: - case HttpStatus.SC_SEE_OTHER: - case HttpStatus.SC_TEMPORARY_REDIRECT: - return true; - default: - return false; - } - } - - /** - * @param statusCode The status code of a response. - * @return True if this status code indicates a success with a response body - */ - public static boolean isSuccessWithContent(int statusCode) { - return statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_PARTIAL_CONTENT; - } - - /** - * @param exception Exception to check. - * @return True if retrying to connect after receiving this exception is likely to succeed. - */ - public static boolean isRetriableNetworkException(Throwable exception) { - return isConnectionResetException(exception) || - isSocketTimeoutException(exception) || - isIncorrectSslShutdownException(exception) || - isPrematureEndException(exception) || - isRetriableConscryptException(exception) || - isRetriableNestedSslException(exception); - } - - private static boolean isConnectionResetException(Throwable exception) { - return exception instanceof SocketException && "Connection reset".equals(exception.getMessage()); - } - - private static boolean isSocketTimeoutException(Throwable exception) { - return exception instanceof SocketTimeoutException && "Read timed out".equals(exception.getMessage()); - } - - private static boolean isIncorrectSslShutdownException(Throwable exception) { - return exception instanceof SSLException && "SSL peer shut down incorrectly".equals(exception.getMessage()); - } - - private static boolean isPrematureEndException(Throwable exception) { - return exception instanceof ConnectionClosedException && exception.getMessage() != null && - exception.getMessage().startsWith("Premature end of Content-Length"); - } - - private static boolean isRetriableConscryptException(Throwable exception) { - if (exception instanceof SSLException) { - String message = exception.getMessage(); - - if (message != null && message.contains("I/O error during system call")) { - return message.contains("No error") || - message.contains("Connection reset by peer") || - message.contains("Connection timed out"); - } - } - - return false; - } - - private static boolean isRetriableNestedSslException(Throwable exception) { - return exception instanceof SSLException && isRetriableNetworkException(exception.getCause()); - } - - /** - * Executes an HTTP request and returns the response as a JsonBrowser instance. - * - * @param httpInterface HTTP interface to use for the request. - * @param request Request to perform. - * @return Response as a JsonBrowser instance. null in case of 404. - * @throws IOException On network error or for non-200 response code. - */ - public static JsonBrowser fetchResponseAsJson(HttpInterface httpInterface, HttpUriRequest request) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(request)) { - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode == HttpStatus.SC_NOT_FOUND) { - return null; - } else if (statusCode != HttpStatus.SC_OK) { - throw new FriendlyException("Server responded with an error.", SUSPICIOUS, - new IllegalStateException("Response code from channel info is " + statusCode)); - } - - return JsonBrowser.parse(response.getEntity().getContent()); - } - } - - /** - * Executes an HTTP request and returns the response as an array of lines. - * - * @param httpInterface HTTP interface to use for the request. - * @param request Request to perform. - * @param name Name of the operation to include in exception messages. - * @return Array of lines from the response - * @throws IOException On network error or for non-200 response code. - */ - public static String[] fetchResponseLines(HttpInterface httpInterface, HttpUriRequest request, String name) throws IOException { - try (CloseableHttpResponse response = httpInterface.execute(request)) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != HttpStatus.SC_OK) { - throw new IOException("Unexpected response code " + statusCode + " from " + name); - } - - return DataFormatTools.streamToLines(response.getEntity().getContent(), StandardCharsets.UTF_8); - } - } - - /** - * @param response Http response to get the header value from. - * @param name Name of the header. - * @return Value if header was present, null otherwise. - */ - public static String getHeaderValue(HttpResponse response, String name) { - Header header = response.getFirstHeader(name); - return header != null ? header.getValue() : null; - } - - private static class NoResponseRetryHandler extends DefaultHttpRequestRetryHandler { - private static final NoResponseRetryHandler RETRY_INSTANCE = new NoResponseRetryHandler(); - - @Override - public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { - boolean retry = super.retryRequest(exception, executionCount, context); - - if (!retry && exception instanceof NoHttpResponseException && executionCount < 5) { - return true; - } else { - return retry; - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpConfigurable.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpConfigurable.java deleted file mode 100644 index 4d16be2..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpConfigurable.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.HttpClientBuilder; - -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Represents a class where HTTP request configuration can be changed. - */ -public interface HttpConfigurable { - /** - * @param configurator Function to reconfigure request config. - */ - void configureRequests(Function configurator); - - /** - * @param configurator Function to reconfigure HTTP builder. - */ - void configureBuilder(Consumer configurator); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpInterface.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpInterface.java deleted file mode 100644 index b4059ce..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpInterface.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.impl.client.CloseableHttpClient; - -import java.io.Closeable; -import java.io.IOException; -import java.net.URI; -import java.util.List; - -/** - * An HTTP interface for performing HTTP requests in one specific thread. This also means it is not thread safe and should - * not be used in a thread it was not obtained in. For multi-thread use {@link HttpInterfaceManager#getInterface()}, - * should be called in each thread separately. - */ -public class HttpInterface implements Closeable { - private final CloseableHttpClient client; - private final HttpClientContext context; - private final boolean ownedClient; - private HttpUriRequest lastRequest; - private boolean available; - - /** - * @param client The http client instance used. - * @param context The http context instance used. - * @param ownedClient True if the client should be closed when this instance is closed. - */ - public HttpInterface(CloseableHttpClient client, HttpClientContext context, boolean ownedClient) { - this.client = client; - this.context = context; - this.ownedClient = ownedClient; - this.available = true; - } - - /** - * Acquire exclusive use of this instance. This is released by calling close. - * - * @return True if this instance was not exclusively used when this method was called. - */ - public boolean acquire() { - if (!available) { - return false; - } - - available = false; - return true; - } - - /** - * Executes the given query using the client and context stored in this instance. - * - * @param request The request to execute. - * @return Closeable response from the server. - * @throws IOException On network error. - */ - public CloseableHttpResponse execute(HttpUriRequest request) throws IOException { - lastRequest = request; - return client.execute(request, context); - } - - /** - * @return The final URL after redirects for the last processed request. Original URL if no redirects were performed. - * Null if no requests have been executed. Undefined state if last request threw an exception. - */ - public URI getFinalLocation() { - List redirectLocations = context.getRedirectLocations(); - - if (redirectLocations != null && !redirectLocations.isEmpty()) { - return redirectLocations.get(redirectLocations.size() - 1); - } else { - return lastRequest != null ? lastRequest.getURI() : null; - } - } - - /** - * @return Http client context used by this interface. - */ - public HttpClientContext getContext() { - return context; - } - - /** - * @return Http client instance used by this instance. - */ - public CloseableHttpClient getHttpClient() { - return client; - } - - @Override - public void close() throws IOException { - available = true; - - if (ownedClient) { - client.close(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpInterfaceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpInterfaceManager.java deleted file mode 100644 index 3208736..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/HttpInterfaceManager.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.Closeable; - -/** - * A thread-safe manager for HTTP interfaces. - */ -public interface HttpInterfaceManager extends HttpConfigurable, Closeable { - /** - * @return An HTTP interface for use by the current thread. - */ - HttpInterface getInterface(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/MessageInput.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/MessageInput.java deleted file mode 100644 index 44dc130..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/MessageInput.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.input.BoundedInputStream; -import org.apache.commons.io.input.CountingInputStream; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * An input for messages with their size known so unknown messages can be skipped. - */ -public class MessageInput { - private final CountingInputStream countingInputStream; - private final DataInputStream dataInputStream; - private int messageSize; - private int messageFlags; - - /** - * @param inputStream Input stream to read from. - */ - public MessageInput(InputStream inputStream) { - this.countingInputStream = new CountingInputStream(inputStream); - this.dataInputStream = new DataInputStream(inputStream); - } - - /** - * @return Data input for the next message. Note that it does not automatically skip over the last message if it was - * not fully read, for that purpose, skipRemainingBytes() should be explicitly called after reading every - * message. A null return value indicates the position where MessageOutput#finish() had written the end - * marker. - * @throws IOException On IO error - */ - public DataInput nextMessage() throws IOException { - int value = dataInputStream.readInt(); - messageFlags = (int) ((value & 0xC0000000L) >> 30L); - messageSize = value & 0x3FFFFFFF; - - if (messageSize == 0) { - return null; - } - - return new DataInputStream(new BoundedInputStream(countingInputStream, messageSize)); - } - - /** - * @return Flags (values 0-3) of the last message for which nextMessage() was called. - */ - public int getMessageFlags() { - return messageFlags; - } - - /** - * Skip the remaining bytes of the last message returned from nextMessage(). This must be called if it is not certain - * that all of the bytes of the message were consumed. - * - * @throws IOException On IO error - */ - public void skipRemainingBytes() throws IOException { - long count = countingInputStream.resetByteCount(); - - if (count < messageSize) { - IOUtils.skipFully(dataInputStream, messageSize - count); - } - - messageSize = 0; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/MessageOutput.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/MessageOutput.java deleted file mode 100644 index f21c289..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/MessageOutput.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.*; - -/** - * An output for a series of messages which each have sizes specified before the start of the message. Even when the - * decoder does not recognize some of the messages, it can skip over the message since it knows its size in advance. - */ -public class MessageOutput { - private final OutputStream outputStream; - private final DataOutputStream dataOutputStream; - private final ByteArrayOutputStream messageByteOutput; - private final DataOutputStream messageDataOutput; - - /** - * @param outputStream Output stream to write the messages to - */ - public MessageOutput(OutputStream outputStream) { - this.outputStream = outputStream; - this.dataOutputStream = new DataOutputStream(outputStream); - this.messageByteOutput = new ByteArrayOutputStream(); - this.messageDataOutput = new DataOutputStream(messageByteOutput); - } - - /** - * @return Data output for a new message - */ - public DataOutput startMessage() { - messageByteOutput.reset(); - return messageDataOutput; - } - - /** - * Commit previously started message to the underlying output stream. - * - * @throws IOException On IO error - */ - public void commitMessage() throws IOException { - dataOutputStream.writeInt(messageByteOutput.size()); - messageByteOutput.writeTo(outputStream); - } - - /** - * Commit previously started message to the underlying output stream. - * - * @param flags Flags to use when committing the message (0-3). - * @throws IOException On IO error - */ - public void commitMessage(int flags) throws IOException { - dataOutputStream.writeInt(messageByteOutput.size() | flags << 30); - messageByteOutput.writeTo(outputStream); - } - - /** - * Write an end marker to the stream so that decoder knows to return null at this position. - * - * @throws IOException On IO error - */ - public void finish() throws IOException { - dataOutputStream.writeInt(0); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/PersistentHttpStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/PersistentHttpStream.java deleted file mode 100644 index 215059d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/PersistentHttpStream.java +++ /dev/null @@ -1,301 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoBuilder; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoProvider; -import org.apache.http.Header; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.Collections; -import java.util.List; - -import static com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools.getHeaderValue; - -/** - * Use an HTTP endpoint as a stream, where the connection resetting is handled gracefully by reopening the connection - * and using a closed stream will just reopen the connection. - */ -public class PersistentHttpStream extends SeekableInputStream implements AutoCloseable { - private static final Logger log = LoggerFactory.getLogger(PersistentHttpStream.class); - - private static final long MAX_SKIP_DISTANCE = 512L * 1024L; - - private final HttpInterface httpInterface; - protected final URI contentUrl; - private int lastStatusCode; - private CloseableHttpResponse currentResponse; - private InputStream currentContent; - protected long position; - - /** - * @param httpInterface The HTTP interface to use for requests - * @param contentUrl The URL of the resource - * @param contentLength The length of the resource in bytes - */ - public PersistentHttpStream(HttpInterface httpInterface, URI contentUrl, Long contentLength) { - super(contentLength == null ? Long.MAX_VALUE : contentLength, MAX_SKIP_DISTANCE); - - this.httpInterface = httpInterface; - this.contentUrl = contentUrl; - this.position = 0; - } - - /** - * Connect and return status code or return last status code if already connected. This causes the internal status - * code checker to be disabled, so non-success status codes will be returned instead of being thrown as they would - * be otherwise. - * - * @return The status code when connecting to the URL - * @throws IOException On IO error - */ - public int checkStatusCode() throws IOException { - connect(true); - - return lastStatusCode; - } - - /** - * @return An HTTP response if one is currently open. - */ - public HttpResponse getCurrentResponse() { - return currentResponse; - } - - protected URI getConnectUrl() { - return contentUrl; - } - - protected boolean useHeadersForRange() { - return true; - } - - private static boolean validateStatusCode(HttpResponse response, boolean returnOnServerError) { - int statusCode = response.getStatusLine().getStatusCode(); - if (returnOnServerError && statusCode >= HttpStatus.SC_INTERNAL_SERVER_ERROR) { - return false; - } else if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_PARTIAL_CONTENT) { - throw new RuntimeException("Not success status code: " + statusCode); - } - return true; - } - - private HttpGet getConnectRequest() { - HttpGet request = new HttpGet(getConnectUrl()); - - if (position > 0 && useHeadersForRange()) { - request.setHeader(HttpHeaders.RANGE, "bytes=" + position + "-"); - } - - return request; - } - - private void connect(boolean skipStatusCheck) throws IOException { - if (currentResponse == null) { - for (int i = 1; i >= 0; i--) { - if (attemptConnect(skipStatusCheck, i > 0)) { - break; - } - } - } - } - - private boolean attemptConnect(boolean skipStatusCheck, boolean retryOnServerError) throws IOException { - currentResponse = httpInterface.execute(getConnectRequest()); - lastStatusCode = currentResponse.getStatusLine().getStatusCode(); - - if (!skipStatusCheck && !validateStatusCode(currentResponse, retryOnServerError)) { - return false; - } - - if (currentResponse.getEntity() == null) { - currentContent = EmptyInputStream.INSTANCE; - contentLength = 0; - return true; - } - - currentContent = new BufferedInputStream(currentResponse.getEntity().getContent()); - - if (contentLength == Long.MAX_VALUE) { - Header header = currentResponse.getFirstHeader("Content-Length"); - - if (header != null) { - contentLength = Long.valueOf(header.getValue()); - } - } - - return true; - } - - private void handleNetworkException(IOException exception, boolean attemptReconnect) throws IOException { - if (!attemptReconnect || !HttpClientTools.isRetriableNetworkException(exception)) { - throw exception; - } - - close(); - - log.debug("Encountered retriable exception on url {}.", contentUrl, exception); - } - - private int internalRead(boolean attemptReconnect) throws IOException { - connect(false); - - try { - int result = currentContent.read(); - if (result >= 0) { - position++; - } - return result; - } catch (IOException e) { - handleNetworkException(e, attemptReconnect); - return internalRead(false); - } - } - - @Override - public int read() throws IOException { - return internalRead(true); - } - - private int internalRead(byte[] b, int off, int len, boolean attemptReconnect) throws IOException { - connect(false); - - try { - int result = currentContent.read(b, off, len); - if (result >= 0) { - position += result; - } - return result; - } catch (IOException e) { - handleNetworkException(e, attemptReconnect); - return internalRead(b, off, len, false); - } - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - return internalRead(b, off, len, true); - } - - private long internalSkip(long n, boolean attemptReconnect) throws IOException { - connect(false); - - try { - long result = currentContent.skip(n); - if (result >= 0) { - position += result; - } - return result; - } catch (IOException e) { - handleNetworkException(e, attemptReconnect); - return internalSkip(n, false); - } - } - - @Override - public long skip(long n) throws IOException { - return internalSkip(n, true); - } - - private int internalAvailable(boolean attemptReconnect) throws IOException { - connect(false); - - try { - return currentContent.available(); - } catch (IOException e) { - handleNetworkException(e, attemptReconnect); - return internalAvailable(false); - } - } - - @Override - public int available() throws IOException { - return internalAvailable(true); - } - - @Override - public synchronized void reset() throws IOException { - throw new IOException("mark/reset not supported"); - } - - @Override - public boolean markSupported() { - return false; - } - - @Override - public void close() throws IOException { - if (currentResponse != null) { - try { - currentResponse.close(); - } catch (IOException e) { - log.debug("Failed to close response.", e); - } - - currentResponse = null; - currentContent = null; - } - } - - /** - * Detach from the current connection, making sure not to close the connection when the stream is closed. - */ - public void releaseConnection() { - if (currentContent != null) { - try { - currentContent.close(); - } catch (IOException e) { - log.debug("Failed to close response stream.", e); - } - } - - currentResponse = null; - currentContent = null; - } - - @Override - public long getPosition() { - return position; - } - - @Override - protected void seekHard(long position) throws IOException { - close(); - - this.position = position; - } - - @Override - public boolean canSeekHard() { - return contentLength != Long.MAX_VALUE; - } - - @Override - public List getTrackInfoProviders() { - if (currentResponse != null) { - return Collections.singletonList(createIceCastHeaderProvider()); - } else { - return Collections.emptyList(); - } - } - - private AudioTrackInfoProvider createIceCastHeaderProvider() { - AudioTrackInfoBuilder builder = AudioTrackInfoBuilder.empty() - .setTitle(getHeaderValue(currentResponse, "icy-description")) - .setAuthor(getHeaderValue(currentResponse, "icy-name")); - - if (builder.getTitle() == null) { - builder.setTitle(getHeaderValue(currentResponse, "icy-url")); - } - - return builder; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ResettableBoundedInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ResettableBoundedInputStream.java deleted file mode 100644 index 1f26454..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ResettableBoundedInputStream.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.IOException; -import java.io.InputStream; - -import static org.apache.commons.io.IOUtils.EOF; - -/** - * Bounded input stream where the limit can be set dynamically. - */ -public class ResettableBoundedInputStream extends InputStream { - private final InputStream delegate; - - private long limit; - private long position; - - /** - * @param delegate Underlying input stream. - */ - public ResettableBoundedInputStream(InputStream delegate) { - this.delegate = delegate; - this.limit = Long.MAX_VALUE; - this.position = 0; - } - - /** - * Make this input stream return EOF after the specified number of bytes. - * - * @param limit Maximum number of bytes that can be read. - */ - public void resetLimit(long limit) { - this.position = 0; - this.limit = limit; - } - - @Override - public int read() throws IOException { - if (position >= limit) { - return -1; - } - - int result = delegate.read(); - if (result != -1) { - position++; - } - - return result; - } - - @Override - public int read(byte[] buffer, int offset, int length) throws IOException { - if (position >= limit) { - return EOF; - } - - int chunk = (int) Math.min(length, limit - position); - int read = delegate.read(buffer, offset, chunk); - - if (read == -1) { - return -1; - } - - position += read; - return read; - } - - @Override - public long skip(final long distance) throws IOException { - int chunk = (int) Math.min(distance, limit - position); - long skipped = delegate.skip(chunk); - position += skipped; - return skipped; - } - - @Override - public int available() throws IOException { - return (int) Math.min(limit - position, delegate.available()); - } - - @Override - public void close() throws IOException { - // Nothing to do - } - - @Override - public boolean markSupported() { - return false; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SavedHeadSeekableInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SavedHeadSeekableInputStream.java deleted file mode 100644 index 6ba0767..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SavedHeadSeekableInputStream.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoProvider; - -import java.io.IOException; -import java.util.List; - -/** - * A wrapper around a seekable input stream which saves the beginning of the stream into a buffer. Seeking within the - * saved beginning does not cause any IO to be done on the underlying input stream. - */ -public class SavedHeadSeekableInputStream extends SeekableInputStream { - private final SeekableInputStream delegate; - private final byte[] savedHead; - private boolean usingHead; - private boolean allowDirectReads; - private long headPosition; - private long savedUntilPosition; - - /** - * @param delegate The seekable stream to delegate reading to - * @param savedSize Number of bytes to buffer - */ - public SavedHeadSeekableInputStream(SeekableInputStream delegate, int savedSize) { - super(delegate.getContentLength(), delegate.getMaxSkipDistance()); - this.delegate = delegate; - this.savedHead = new byte[savedSize]; - this.allowDirectReads = true; - } - - public void setAllowDirectReads(boolean allowDirectReads) { - this.allowDirectReads = allowDirectReads; - } - - /** - * Load the number of bytes specified in the constructor into the saved buffer. - * - * @throws IOException On IO error - */ - public void loadHead() throws IOException { - delegate.seek(0); - savedUntilPosition = read(savedHead, 0, savedHead.length); - usingHead = savedUntilPosition > 0; - headPosition = 0; - } - - @Override - public long getPosition() { - if (usingHead) { - return headPosition; - } else { - return delegate.getPosition(); - } - } - - @Override - protected void seekHard(long position) throws IOException { - if (position >= savedUntilPosition) { - if (allowDirectReads) { - usingHead = false; - delegate.seekHard(position); - } else { - throw new IndexOutOfBoundsException("Reads beyond saved head are disabled."); - } - } else { - usingHead = true; - headPosition = position; - } - } - - @Override - public boolean canSeekHard() { - return delegate.canSeekHard(); - } - - @Override - public List getTrackInfoProviders() { - return delegate.getTrackInfoProviders(); - } - - @Override - public int read() throws IOException { - if (usingHead) { - byte result = savedHead[(int) headPosition]; - - if (++headPosition == savedUntilPosition) { - delegate.seek(savedUntilPosition); - usingHead = false; - } - - return result & 0xFF; - } else if (allowDirectReads) { - return delegate.read(); - } else { - throw new IndexOutOfBoundsException("Reads beyond saved head are disabled."); - } - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (usingHead) { - return super.read(b, off, len); - } else if (allowDirectReads) { - return delegate.read(b, off, len); - } else { - throw new IndexOutOfBoundsException("Reads beyond saved head are disabled."); - } - } - - @Override - public long skip(long n) throws IOException { - if (usingHead) { - return super.skip(n); - } else if (allowDirectReads) { - return delegate.skip(n); - } else { - throw new IndexOutOfBoundsException("Reads beyond saved head are disabled."); - } - } - - @Override - public int available() throws IOException { - if (usingHead) { - return (int) (savedUntilPosition - headPosition); - } else if (allowDirectReads) { - return delegate.available(); - } else { - throw new IndexOutOfBoundsException("Reads beyond saved head are disabled."); - } - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean markSupported() { - return false; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SeekableInputStream.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SeekableInputStream.java deleted file mode 100644 index e8c7df2..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SeekableInputStream.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoProvider; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -/** - * An input stream that is seekable. - */ -public abstract class SeekableInputStream extends InputStream { - protected long contentLength; - private final long maxSkipDistance; - - /** - * @param contentLength Total stream length - * @param maxSkipDistance Maximum distance that should be skipped by reading and discarding - */ - public SeekableInputStream(long contentLength, long maxSkipDistance) { - this.contentLength = contentLength; - this.maxSkipDistance = maxSkipDistance; - } - - /** - * @return Length of the stream - */ - public long getContentLength() { - return contentLength; - } - - /** - * @return Maximum distance that this stream will skip without doing a direct seek on the underlying resource. - */ - public long getMaxSkipDistance() { - return maxSkipDistance; - } - - /** - * @return Current position in the stream - */ - public abstract long getPosition(); - - protected abstract void seekHard(long position) throws IOException; - - /** - * @return true if it is possible to seek to an arbitrary position in this stream, even when it is behind - * the current position. - */ - public abstract boolean canSeekHard(); - - /** - * Skip the specified number of bytes in the stream. The result is either that the requested number of bytes were - * skipped or an EOFException was thrown. - * - * @param distance The number of bytes to skip - * @throws IOException On IO error - */ - public void skipFully(long distance) throws IOException { - long current = getPosition(); - long target = current + distance; - - while (current < target) { - long skipped = skip(target - current); - - if (skipped == 0) { - if (read() == -1) { - throw new EOFException("Cannot skip any further."); - } else { - skipped = 1; - } - } - - current += skipped; - } - } - - /** - * Seek to the specified position - * - * @param position The position to seek to - * @throws IOException On a read error or if the position is beyond EOF - */ - public void seek(long position) throws IOException { - long current = getPosition(); - - if (current != position) { - if (current <= position && position - current <= maxSkipDistance) { - skipFully(position - current); - } else if (!canSeekHard()) { - if (current > position) { - seekHard(0); - skipFully(position); - } else { - skipFully(position - current); - } - } else { - seekHard(position); - } - } - } - - public abstract List getTrackInfoProviders(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SimpleHttpInterfaceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SimpleHttpInterfaceManager.java deleted file mode 100644 index 92e2317..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/SimpleHttpInterfaceManager.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.impl.client.HttpClientBuilder; - -/** - * HTTP interface manager which creates a new HTTP context for each interface. - */ -public class SimpleHttpInterfaceManager extends AbstractHttpInterfaceManager { - /** - * @param clientBuilder HTTP client builder to use for creating the client instance. - * @param requestConfig Request config used by the client builder - */ - public SimpleHttpInterfaceManager(HttpClientBuilder clientBuilder, RequestConfig requestConfig) { - super(clientBuilder, requestConfig); - } - - @Override - public HttpInterface getInterface() { - return new HttpInterface(getSharedClient(), HttpClientContext.create(), false); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/StreamTools.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/StreamTools.java deleted file mode 100644 index 9f41b14..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/StreamTools.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Utility methods for streams. - */ -public class StreamTools { - /** - * Reads from the stream until either the length number of bytes is read, or the stream ends. Note that neither case - * throws an exception. - * - * @param in The stream to read from. - * @param buffer Buffer to write the data that is read from the stream. - * @param offset Offset in the buffer to start writing from. - * @param length Maximum number of bytes to read from the stream. - * @return The number of bytes read from the stream. - * @throws IOException On read error. - */ - public static int readUntilEnd(InputStream in, byte[] buffer, int offset, int length) throws IOException { - int position = 0; - - while (position < length) { - int count = in.read(buffer, offset + position, length - position); - if (count < 0) { - break; - } - - position += count; - } - - return position; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ThreadLocalHttpInterfaceManager.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ThreadLocalHttpInterfaceManager.java deleted file mode 100644 index 608fcf0..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/ThreadLocalHttpInterfaceManager.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; - -/** - * HTTP interface manager which reuses an HttpContext by keeping it as a thread local. In case a new interface is - * requested before the previous one has been closed, it creates a new context for the returned interface. The HTTP - * client instance used is created lazily. - */ -public class ThreadLocalHttpInterfaceManager extends AbstractHttpInterfaceManager { - private final ThreadLocal httpInterfaces; - - /** - * @param clientBuilder HTTP client builder to use for creating the client instance. - * @param requestConfig Request config used by the client builder - */ - public ThreadLocalHttpInterfaceManager(HttpClientBuilder clientBuilder, RequestConfig requestConfig) { - super(clientBuilder, requestConfig); - - this.httpInterfaces = ThreadLocal.withInitial(() -> - new HttpInterface(getSharedClient(), HttpClientContext.create(), false) - ); - } - - @Override - public HttpInterface getInterface() { - CloseableHttpClient client = getSharedClient(); - - HttpInterface httpInterface = httpInterfaces.get(); - if (httpInterface.getHttpClient() != client) { - httpInterfaces.remove(); - httpInterface = httpInterfaces.get(); - } - - if (httpInterface.acquire()) { - return httpInterface; - } - - httpInterface = new HttpInterface(client, HttpClientContext.create(), false); - httpInterface.acquire(); - return httpInterface; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/TrustManagerBuilder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/TrustManagerBuilder.java deleted file mode 100644 index ad12348..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/TrustManagerBuilder.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.tools.io; - -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import org.apache.commons.io.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.security.KeyStore; -import java.security.cert.Certificate; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; - -/** - * Builder for a trust manager with custom certificates. - */ -public class TrustManagerBuilder { - private static final Logger log = LoggerFactory.getLogger(TrustManagerBuilder.class); - - private final List certificates = new ArrayList<>(); - - /** - * Add certificates from the default trust store - * - * @return this - * @throws Exception In case anything explodes. - */ - public TrustManagerBuilder addBuiltinCertificates() throws Exception { - TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - factory.init((KeyStore) null); - - X509TrustManager builtInTrustManager = findFirstX509TrustManager(factory); - if (builtInTrustManager != null) { - addFromTrustManager(builtInTrustManager); - } - return this; - } - - /** - * Add certificates from the specified resource directory, using {path}/bundled.txt and {path}/extended.txt as the - * list of JKS file names to laoad from that directory. - * - * @param path Path to the resource directory. - * @return this - * @throws Exception In case anything explodes. - */ - public TrustManagerBuilder addFromResourceDirectory(String path) throws Exception { - addFromResourceList(path, path + "/bundled.txt"); - addFromResourceList(path, path + "/extended.txt"); - return this; - } - - /** - * @return A trust manager with the loaded certificates. - * @throws Exception In case anything explodes. - */ - public X509TrustManager build() throws Exception { - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(null, null); - - for (int i = 0; i < certificates.size(); i++) { - keyStore.setCertificateEntry(String.valueOf(i), certificates.get(i)); - } - - TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - factory.init(keyStore); - - return findFirstX509TrustManager(factory); - } - - private X509TrustManager findFirstX509TrustManager(TrustManagerFactory factory) { - for (TrustManager trustManager : factory.getTrustManagers()) { - if (trustManager instanceof X509TrustManager) { - return (X509TrustManager) trustManager; - } - } - - return null; - } - - private void addFromTrustManager(X509TrustManager trustManager) { - for (Certificate certificate : trustManager.getAcceptedIssuers()) { - certificates.add(certificate); - } - } - - private void addFromResourceList(String basePath, String listPath) throws Exception { - InputStream listFileStream = TrustManagerBuilder.class.getResourceAsStream(listPath); - - if (listFileStream == null) { - log.debug("Certificate list {} not present in classpath.", listPath); - return; - } - - try { - for (String line : IOUtils.readLines(listFileStream, StandardCharsets.UTF_8)) { - String fileName = line.trim(); - - if (!fileName.isEmpty()) { - addFromResourceFile(basePath + "/" + fileName); - } - } - } finally { - ExceptionTools.closeWithWarnings(listFileStream); - } - } - - private void addFromResourceFile(String resourcePath) throws Exception { - InputStream fileStream = TrustManagerBuilder.class.getResourceAsStream(resourcePath); - - if (fileStream == null) { - log.warn("Certificate {} not present in classpath.", resourcePath); - return; - } - - try { - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(fileStream, null); - addFromKeyStore(keyStore); - } finally { - ExceptionTools.closeWithWarnings(fileStream); - } - } - - private void addFromKeyStore(KeyStore keyStore) throws Exception { - for (Enumeration enumeration = keyStore.aliases(); enumeration.hasMoreElements(); ) { - String alias = enumeration.nextElement(); - - if (keyStore.isCertificateEntry(alias)) { - certificates.add(keyStore.getCertificate(alias)); - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioItem.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioItem.java deleted file mode 100644 index d53e3ff..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioItem.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -/** - * Marker interface for all loadable items - */ -public interface AudioItem { -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioPlaylist.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioPlaylist.java deleted file mode 100644 index 7ae4e19..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioPlaylist.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -import java.util.List; - -/** - * Playlist of audio tracks - */ -public interface AudioPlaylist extends AudioItem { - /** - * @return Name of the playlist - */ - String getName(); - - /** - * @return List of tracks in the playlist - */ - List getTracks(); - - /** - * @return Track that is explicitly selected, may be null. This same instance occurs in the track list. - */ - AudioTrack getSelectedTrack(); - - /** - * @return True if the playlist was created from search results. - */ - boolean isSearchResult(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioReference.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioReference.java deleted file mode 100644 index ac1b2a8..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioReference.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -import com.sedmelluq.discord.lavaplayer.container.MediaContainerDescriptor; -import com.sedmelluq.discord.lavaplayer.track.info.AudioTrackInfoProvider; - -/** - * An audio item which refers to an unloaded audio item. Source managers can return this to indicate a redirection, - * which means that the item referred to in it is loaded instead. - */ -public class AudioReference implements AudioItem, AudioTrackInfoProvider { - public static final AudioReference NO_TRACK = new AudioReference(null, null, null); - - /** - * The identifier of the other item. - */ - public final String identifier; - /** - * The title of the other item, if known. - */ - public final String title; - /** - * Known probe and probe settings of the item to be loaded. - */ - public final MediaContainerDescriptor containerDescriptor; - - /** - * @param identifier The identifier of the other item. - * @param title The title of the other item, if known. - */ - public AudioReference(String identifier, String title) { - this(identifier, title, null); - } - - /** - * @param identifier The identifier of the other item. - * @param title The title of the other item, if known. - */ - public AudioReference(String identifier, String title, MediaContainerDescriptor containerDescriptor) { - this.identifier = identifier; - this.title = title; - this.containerDescriptor = containerDescriptor; - } - - @Override - public String getTitle() { - return title; - } - - @Override - public String getAuthor() { - return null; - } - - @Override - public Long getLength() { - return null; - } - - @Override - public String getIdentifier() { - return identifier; - } - - @Override - public String getUri() { - return identifier; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrack.java deleted file mode 100644 index f15a51f..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrack.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; - -/** - * A playable audio track - */ -public interface AudioTrack extends AudioItem { - /** - * @return Track meta information - */ - AudioTrackInfo getInfo(); - - /** - * @return The identifier of the track - */ - String getIdentifier(); - - /** - * @return The current execution state of the track - */ - AudioTrackState getState(); - - /** - * Stop the track if it is currently playing - */ - void stop(); - - /** - * @return True if the track is seekable. - */ - boolean isSeekable(); - - /** - * @return Get the current position of the track in milliseconds - */ - long getPosition(); - - /** - * Seek to the specified position. - * - * @param position New position of the track in milliseconds - */ - void setPosition(long position); - - /** - * @param marker Track position marker to place - */ - void setMarker(TrackMarker marker); - - /** - * @return Duration of the track in milliseconds - */ - long getDuration(); - - /** - * @return Clone of this track which does not share the execution state of this track - */ - AudioTrack makeClone(); - - /** - * @return The source manager which created this track. Null if not created by a source manager directly. - */ - AudioSourceManager getSourceManager(); - - /** - * Attach an object with this track which can later be retrieved with {@link #getUserData()}. Useful for retrieving - * application-specific object from the track in callbacks. - * - * @param userData Object to store. - */ - void setUserData(Object userData); - - /** - * @return Object previously stored with {@link #setUserData(Object)} - */ - Object getUserData(); - - /** - * @param klass The expected class of the user data (or a superclass of it). - * @return Object previously stored with {@link #setUserData(Object)} if it is of the specified type. If it is set, - * but with a different type, null is returned. - */ - T getUserData(Class klass); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackEndReason.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackEndReason.java deleted file mode 100644 index eb05867..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackEndReason.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -/** - * Reason why a track stopped playing. - */ -public enum AudioTrackEndReason { - /** - * This means that the track itself emitted a terminator. This is usually caused by the track reaching the end, - * however it will also be used when it ends due to an exception. - */ - FINISHED(true), - /** - * This means that the track failed to start, throwing an exception before providing any audio. - */ - LOAD_FAILED(true), - /** - * The track was stopped due to the player being stopped by either calling stop() or playTrack(null). - */ - STOPPED(false), - /** - * The track stopped playing because a new track started playing. Note that with this reason, the old track will still - * play until either its buffer runs out or audio from the new track is available. - */ - REPLACED(false), - /** - * The track was stopped because the cleanup threshold for the audio player was reached. This triggers when the amount - * of time passed since the last call to AudioPlayer#provide() has reached the threshold specified in player manager - * configuration. This may also indicate either a leaked audio player which was discarded, but not stopped. - */ - CLEANUP(false); - - /** - * Indicates whether a new track should be started on receiving this event. If this is false, either this event is - * already triggered because another track started (REPLACED) or because the player is stopped (STOPPED, CLEANUP). - */ - public final boolean mayStartNext; - - AudioTrackEndReason(boolean mayStartNext) { - this.mayStartNext = mayStartNext; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackInfo.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackInfo.java deleted file mode 100644 index 3dfde42..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackInfo.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -/** - * Meta info for an audio track - */ -public class AudioTrackInfo { - /** - * Track title - */ - public final String title; - /** - * Track author, if known - */ - public final String author; - /** - * Length of the track in milliseconds, Long.MAX_VALUE for streams - */ - public final long length; - /** - * Audio source specific track identifier - */ - public final String identifier; - /** - * True if this track is a stream - */ - public final boolean isStream; - /** - * URL of the track, or local path to the file. - */ - public final String uri; - - /** - * @param title Track title - * @param author Track author, if known - * @param length Length of the track in milliseconds - * @param identifier Audio source specific track identifier - * @param isStream True if this track is a stream - * @param uri URL of the track or path to its file. - */ - public AudioTrackInfo(String title, String author, long length, String identifier, boolean isStream, String uri) { - this.title = title; - this.author = author; - this.length = length; - this.identifier = identifier; - this.isStream = isStream; - this.uri = uri; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackState.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackState.java deleted file mode 100644 index 38860dc..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/AudioTrackState.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -/** - * The execution state of an audio track - */ -public enum AudioTrackState { - INACTIVE, - LOADING, - PLAYING, - SEEKING, - STOPPING, - FINISHED -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/BaseAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/BaseAudioTrack.java deleted file mode 100644 index 6eabeda..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/BaseAudioTrack.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioTrackExecutor; -import com.sedmelluq.discord.lavaplayer.track.playback.MutableAudioFrame; -import com.sedmelluq.discord.lavaplayer.track.playback.PrimordialAudioTrackExecutor; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; - -/** - * Abstract base for all audio tracks with an executor - */ -public abstract class BaseAudioTrack implements InternalAudioTrack { - private final PrimordialAudioTrackExecutor initialExecutor; - private final AtomicBoolean executorAssigned; - private volatile AudioTrackExecutor activeExecutor; - protected final AudioTrackInfo trackInfo; - protected final AtomicLong accurateDuration; - private volatile Object userData; - - /** - * @param trackInfo Track info - */ - public BaseAudioTrack(AudioTrackInfo trackInfo) { - this.initialExecutor = new PrimordialAudioTrackExecutor(trackInfo); - this.executorAssigned = new AtomicBoolean(); - this.activeExecutor = null; - this.trackInfo = trackInfo; - this.accurateDuration = new AtomicLong(); - } - - @Override - public void assignExecutor(AudioTrackExecutor executor, boolean applyPrimordialState) { - if (executorAssigned.compareAndSet(false, true)) { - if (applyPrimordialState) { - initialExecutor.applyStateToExecutor(executor); - } - activeExecutor = executor; - } else { - throw new IllegalStateException("Cannot play the same instance of a track twice, use track.makeClone()."); - } - } - - @Override - public AudioTrackExecutor getActiveExecutor() { - AudioTrackExecutor executor = activeExecutor; - return executor != null ? executor : initialExecutor; - } - - @Override - public void stop() { - getActiveExecutor().stop(); - } - - @Override - public AudioTrackState getState() { - return getActiveExecutor().getState(); - } - - @Override - public String getIdentifier() { - return trackInfo.identifier; - } - - @Override - public boolean isSeekable() { - return !trackInfo.isStream; - } - - @Override - public long getPosition() { - return getActiveExecutor().getPosition(); - } - - @Override - public void setPosition(long position) { - getActiveExecutor().setPosition(position); - } - - @Override - public void setMarker(TrackMarker marker) { - getActiveExecutor().setMarker(marker); - } - - @Override - public AudioFrame provide() { - return getActiveExecutor().provide(); - } - - @Override - public AudioFrame provide(long timeout, TimeUnit unit) throws TimeoutException, InterruptedException { - return getActiveExecutor().provide(timeout, unit); - } - - @Override - public boolean provide(MutableAudioFrame targetFrame) { - return getActiveExecutor().provide(targetFrame); - } - - @Override - public boolean provide(MutableAudioFrame targetFrame, long timeout, TimeUnit unit) - throws TimeoutException, InterruptedException { - - return getActiveExecutor().provide(targetFrame, timeout, unit); - } - - @Override - public AudioTrackInfo getInfo() { - return trackInfo; - } - - @Override - public long getDuration() { - long accurate = accurateDuration.get(); - - if (accurate == 0) { - return trackInfo.length; - } else { - return accurate; - } - } - - @Override - public AudioTrack makeClone() { - throw new UnsupportedOperationException(); - } - - @Override - public AudioSourceManager getSourceManager() { - return null; - } - - @Override - public AudioTrackExecutor createLocalExecutor(AudioPlayerManager playerManager) { - return null; - } - - @Override - public void setUserData(Object userData) { - this.userData = userData; - } - - @Override - public Object getUserData() { - return userData; - } - - @Override - @SuppressWarnings("unchecked") - public T getUserData(Class klass) { - Object data = userData; - - if (data != null && klass.isAssignableFrom(data.getClass())) { - return (T) data; - } else { - return null; - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/BasicAudioPlaylist.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/BasicAudioPlaylist.java deleted file mode 100644 index 0aa532e..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/BasicAudioPlaylist.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -import java.util.List; - -/** - * The basic implementation of AudioPlaylist - */ -public class BasicAudioPlaylist implements AudioPlaylist { - private final String name; - private final List tracks; - private final AudioTrack selectedTrack; - private final boolean isSearchResult; - - /** - * @param name Name of the playlist - * @param tracks List of tracks in the playlist - * @param selectedTrack Track that is explicitly selected - * @param isSearchResult True if the playlist was created from search results - */ - public BasicAudioPlaylist(String name, List tracks, AudioTrack selectedTrack, boolean isSearchResult) { - this.name = name; - this.tracks = tracks; - this.selectedTrack = selectedTrack; - this.isSearchResult = isSearchResult; - } - - @Override - public String getName() { - return name; - } - - @Override - public List getTracks() { - return tracks; - } - - @Override - public AudioTrack getSelectedTrack() { - return selectedTrack; - } - - @Override - public boolean isSearchResult() { - return isSearchResult; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/DecodedTrackHolder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/DecodedTrackHolder.java deleted file mode 100644 index 71afd95..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/DecodedTrackHolder.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -/** - * The result of decoding a track. - */ -public class DecodedTrackHolder { - /** - * The decoded track. This may be null if there was a track to decode, but the decoding could not be performed because - * of an older serialization version or because the track source it used is not loaded. - */ - public final AudioTrack decodedTrack; - - /** - * @param decodedTrack The decoded track - */ - public DecodedTrackHolder(AudioTrack decodedTrack) { - this.decodedTrack = decodedTrack; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/DelegatedAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/DelegatedAudioTrack.java deleted file mode 100644 index 5c0a0bf..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/DelegatedAudioTrack.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; - -/** - * Audio track which delegates its processing to another track. The delegate does not have to be known when the - * track is created, but is passed when processDelegate() is called. - */ -public abstract class DelegatedAudioTrack extends BaseAudioTrack { - private InternalAudioTrack delegate; - - /** - * @param trackInfo Track info - */ - public DelegatedAudioTrack(AudioTrackInfo trackInfo) { - super(trackInfo); - } - - protected synchronized void processDelegate(InternalAudioTrack delegate, LocalAudioTrackExecutor localExecutor) throws Exception { - if (this.delegate != null) { - throw new IllegalStateException("Cannot assign delegate twice."); - } - - this.delegate = delegate; - - delegate.assignExecutor(localExecutor, false); - delegate.process(localExecutor); - } - - @Override - public long getDuration() { - if (delegate != null) { - return delegate.getDuration(); - } else { - synchronized (this) { - if (delegate != null) { - return delegate.getDuration(); - } else { - return super.getDuration(); - } - } - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/InternalAudioTrack.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/InternalAudioTrack.java deleted file mode 100644 index 36370b2..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/InternalAudioTrack.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameProvider; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioTrackExecutor; -import com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor; - -/** - * Methods of an audio track that should not be visible outside of the library - */ -public interface InternalAudioTrack extends AudioTrack, AudioFrameProvider { - /** - * @param executor Executor to assign to the track - * @param applyPrimordialState True if the state previously applied to this track should be copied to new executor. - */ - void assignExecutor(AudioTrackExecutor executor, boolean applyPrimordialState); - - /** - * @return Get the active track executor - */ - AudioTrackExecutor getActiveExecutor(); - - /** - * Perform any necessary loading and then enter the read/seek loop - * - * @param executor The local executor which processes this track - * @throws Exception In case anything explodes. - */ - void process(LocalAudioTrackExecutor executor) throws Exception; - - /** - * @param playerManager The player manager which is executing this track - * @return A custom local executor for this track. Unless this track requires a special executor, this should return - * null as the default one will be used in that case. - */ - AudioTrackExecutor createLocalExecutor(AudioPlayerManager playerManager); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarker.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarker.java deleted file mode 100644 index 0946e16..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarker.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -/** - * A track position marker. This makes the specified handler get called when the specified position is reached or - * reaching that position has become impossible. This guarantees that whenever a marker is set and the track is played, - * its handler will always be called. - */ -public class TrackMarker { - /** - * The position of the track in milliseconds when this marker should trigger. - */ - public final long timecode; - /** - * The handler for the marker. The handler is guaranteed to be never called more than once, and guaranteed to be - * called at least once if the track is started on a player. - */ - public final TrackMarkerHandler handler; - - /** - * @param timecode The position of the track in milliseconds when this marker should trigger. - * @param handler The handler for the marker. - */ - public TrackMarker(long timecode, TrackMarkerHandler handler) { - this.timecode = timecode; - this.handler = handler; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarkerHandler.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarkerHandler.java deleted file mode 100644 index 2e87acb..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarkerHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -/** - * A track marker handler. - */ -public interface TrackMarkerHandler { - /** - * @param state The state of the marker when it is triggered. - */ - void handle(MarkerState state); - - /** - * The state of the marker at the moment the handle method is called. - */ - enum MarkerState { - /** - * The specified position has been reached with normal playback. - */ - REACHED, - /** - * The marker has been removed by setting the marker of the track to null. - */ - REMOVED, - /** - * The marker has been overwritten by setting the marker of the track to another non-null marker. - */ - OVERWRITTEN, - /** - * A seek was performed which jumped over the marked position. - */ - BYPASSED, - /** - * The track was stopped before it ended, before the marked position was reached. - */ - STOPPED, - /** - * The playback position was already beyond the marked position when the marker was placed. - */ - LATE, - /** - * The track ended without the marker being triggered (either due to an exception or because the track duration was - * smaller than the marked position). - */ - ENDED - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarkerTracker.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarkerTracker.java deleted file mode 100644 index 2dbe346..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackMarkerTracker.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -import java.util.concurrent.atomic.AtomicReference; - -import static com.sedmelluq.discord.lavaplayer.track.TrackMarkerHandler.MarkerState.*; - -/** - * Tracks the state of a track position marker. - */ -public class TrackMarkerTracker { - private final AtomicReference current = new AtomicReference<>(); - - /** - * Set a new track position marker. - * - * @param marker Marker - * @param currentTimecode Current timecode of the track when this marker is set - */ - public void set(TrackMarker marker, long currentTimecode) { - TrackMarker previous = current.getAndSet(marker); - - if (previous != null) { - previous.handler.handle(marker != null ? OVERWRITTEN : REMOVED); - } - - if (marker != null && currentTimecode >= marker.timecode) { - trigger(marker, LATE); - } - } - - /** - * Remove the current marker. - * - * @return The removed marker. - */ - public TrackMarker remove() { - return current.getAndSet(null); - } - - /** - * Trigger and remove the marker with the specified state. - * - * @param state The state of the marker to pass to the handler. - */ - public void trigger(TrackMarkerHandler.MarkerState state) { - TrackMarker marker = current.getAndSet(null); - - if (marker != null) { - marker.handler.handle(state); - } - } - - /** - * Check a timecode which was reached by normal playback, trigger REACHED if necessary. - * - * @param timecode Timecode which was reached by normal playback. - */ - public void checkPlaybackTimecode(long timecode) { - TrackMarker marker = current.get(); - - if (marker != null && timecode >= marker.timecode) { - trigger(marker, REACHED); - } - } - - /** - * Check a timecode which was reached by seeking, trigger BYPASSED if necessary. - * - * @param timecode Timecode which was reached by seeking. - */ - public void checkSeekTimecode(long timecode) { - TrackMarker marker = current.get(); - - if (marker != null && timecode >= marker.timecode) { - trigger(marker, BYPASSED); - } - } - - private void trigger(TrackMarker marker, TrackMarkerHandler.MarkerState state) { - if (current.compareAndSet(marker, null)) { - marker.handler.handle(state); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackStateListener.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackStateListener.java deleted file mode 100644 index ba04929..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/TrackStateListener.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track; - -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; - -/** - * Listener of track execution events. - */ -public interface TrackStateListener { - /** - * Called when an exception occurs while a track is playing or loading. This is always fatal, but it may have left - * some data in the audio buffer which can still play until the buffer clears out. - * - * @param track The audio track for which the exception occurred - * @param exception The exception that occurred - */ - void onTrackException(AudioTrack track, FriendlyException exception); - - /** - * Called when an exception occurs while a track is playing or loading. This is always fatal, but it may have left - * some data in the audio buffer which can still play until the buffer clears out. - * - * @param track The audio track for which the exception occurred - * @param thresholdMs The wait threshold that was exceeded for this event to trigger - */ - void onTrackStuck(AudioTrack track, long thresholdMs); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/info/AudioTrackInfoBuilder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/info/AudioTrackInfoBuilder.java deleted file mode 100644 index ff41e77..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/info/AudioTrackInfoBuilder.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.info; - -import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; -import com.sedmelluq.discord.lavaplayer.tools.io.SeekableInputStream; -import com.sedmelluq.discord.lavaplayer.track.AudioReference; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; - -/** - * Builder for {@link AudioTrackInfo}. - */ -public class AudioTrackInfoBuilder implements AudioTrackInfoProvider { - private static final String UNKNOWN_TITLE = "Unknown title"; - private static final String UNKNOWN_ARTIST = "Unknown artist"; - - private String title; - private String author; - private Long length; - private String identifier; - private String uri; - private Boolean isStream; - - private AudioTrackInfoBuilder() { - - } - - @Override - public String getTitle() { - return title; - } - - @Override - public String getAuthor() { - return author; - } - - @Override - public Long getLength() { - return length; - } - - @Override - public String getIdentifier() { - return identifier; - } - - @Override - public String getUri() { - return uri; - } - - public AudioTrackInfoBuilder setTitle(String value) { - title = DataFormatTools.defaultOnNull(value, title); - return this; - } - - public AudioTrackInfoBuilder setAuthor(String value) { - author = DataFormatTools.defaultOnNull(value, author); - return this; - } - - public AudioTrackInfoBuilder setLength(Long value) { - length = DataFormatTools.defaultOnNull(value, length); - return this; - } - - public AudioTrackInfoBuilder setIdentifier(String value) { - identifier = DataFormatTools.defaultOnNull(value, identifier); - return this; - } - - public AudioTrackInfoBuilder setUri(String value) { - uri = DataFormatTools.defaultOnNull(value, uri); - return this; - } - - public AudioTrackInfoBuilder setIsStream(Boolean stream) { - isStream = stream; - return this; - } - - /** - * @param provider The track info provider to apply to the builder. - * @return this - */ - public AudioTrackInfoBuilder apply(AudioTrackInfoProvider provider) { - if (provider == null) { - return this; - } - - return setTitle(provider.getTitle()) - .setAuthor(provider.getAuthor()) - .setLength(provider.getLength()) - .setIdentifier(provider.getIdentifier()) - .setUri(provider.getUri()); - } - - /** - * @return Audio track info instance. - */ - public AudioTrackInfo build() { - long finalLength = DataFormatTools.defaultOnNull(length, Long.MAX_VALUE); - - return new AudioTrackInfo( - title, - author, - finalLength, - identifier, - DataFormatTools.defaultOnNull(isStream, finalLength == Long.MAX_VALUE), - uri - ); - } - - /** - * Creates an instance of an audio track builder based on an audio reference and a stream. - * - * @param reference Audio reference to use as the starting point for the builder. - * @param stream Stream to get additional data from. - * @return An instance of the builder with the reference and track info providers from the stream preapplied. - */ - public static AudioTrackInfoBuilder create(AudioReference reference, SeekableInputStream stream) { - AudioTrackInfoBuilder builder = new AudioTrackInfoBuilder() - .setAuthor(UNKNOWN_ARTIST) - .setTitle(UNKNOWN_TITLE) - .setLength(Long.MAX_VALUE); - - builder.apply(reference); - - if (stream != null) { - for (AudioTrackInfoProvider provider : stream.getTrackInfoProviders()) { - builder.apply(provider); - } - } - - return builder; - } - - /** - * @return Empty instance of audio track builder. - */ - public static AudioTrackInfoBuilder empty() { - return new AudioTrackInfoBuilder(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/info/AudioTrackInfoProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/info/AudioTrackInfoProvider.java deleted file mode 100644 index 69ed0ea..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/info/AudioTrackInfoProvider.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.info; - -/** - * Provider for audio track info. - */ -public interface AudioTrackInfoProvider { - /** - * @return Track title, or null if this provider does not know it. - */ - String getTitle(); - - /** - * @return Track author, or null if this provider does not know it. - */ - String getAuthor(); - - /** - * @return Track length in milliseconds, or null if this provider does not know it. - */ - Long getLength(); - - /** - * @return Track identifier, or null if this provider does not know it. - */ - String getIdentifier(); - - /** - * @return Track URI, or null if this provider does not know it. - */ - String getUri(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AbstractAudioFrameBuffer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AbstractAudioFrameBuffer.java deleted file mode 100644 index bd43a96..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AbstractAudioFrameBuffer.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; - -/** - * Common parts of a frame buffer which are not likely to depend on the specific implementation. - */ -public abstract class AbstractAudioFrameBuffer implements AudioFrameBuffer { - protected final AudioDataFormat format; - protected final Object synchronizer; - protected volatile boolean locked; - protected volatile boolean receivedFrames; - protected boolean terminated; - protected boolean terminateOnEmpty; - protected boolean clearOnInsert; - - protected AbstractAudioFrameBuffer(AudioDataFormat format) { - this.format = format; - this.synchronizer = new Object(); - locked = false; - receivedFrames = false; - terminated = false; - terminateOnEmpty = false; - clearOnInsert = false; - } - - @Override - public void waitForTermination() throws InterruptedException { - synchronized (synchronizer) { - while (!terminated) { - synchronizer.wait(); - } - } - } - - @Override - public void setTerminateOnEmpty() { - synchronized (synchronizer) { - // Count this also as inserting the terminator frame, hence trigger clearOnInsert - if (clearOnInsert) { - clear(); - clearOnInsert = false; - } - - if (!terminated) { - terminateOnEmpty = true; - signalWaiters(); - } - } - } - - @Override - public void setClearOnInsert() { - synchronized (synchronizer) { - clearOnInsert = true; - terminateOnEmpty = false; - } - } - - @Override - public boolean hasClearOnInsert() { - return clearOnInsert; - } - - @Override - public void lockBuffer() { - locked = true; - } - - @Override - public boolean hasReceivedFrames() { - return receivedFrames; - } - - protected abstract void signalWaiters(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AbstractMutableAudioFrame.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AbstractMutableAudioFrame.java deleted file mode 100644 index 4121236..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AbstractMutableAudioFrame.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; - -/** - * Base class for mutable audio frames. - */ -public abstract class AbstractMutableAudioFrame implements AudioFrame { - private long timecode; - private int volume; - private AudioDataFormat format; - private boolean terminator; - - @Override - public long getTimecode() { - return timecode; - } - - public void setTimecode(long timecode) { - this.timecode = timecode; - } - - @Override - public int getVolume() { - return volume; - } - - public void setVolume(int volume) { - this.volume = volume; - } - - @Override - public AudioDataFormat getFormat() { - return format; - } - - public void setFormat(AudioDataFormat format) { - this.format = format; - } - - @Override - public boolean isTerminator() { - return terminator; - } - - public void setTerminator(boolean terminator) { - this.terminator = terminator; - } - - /** - * @return An immutable instance created from this mutable audio frame. In an ideal flow, this should never be called. - */ - public ImmutableAudioFrame freeze() { - return new ImmutableAudioFrame(timecode, getData(), volume, format); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AllocatingAudioFrameBuffer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AllocatingAudioFrameBuffer.java deleted file mode 100644 index e3b9246..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AllocatingAudioFrameBuffer.java +++ /dev/null @@ -1,205 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * A frame buffer. Stores the specified duration worth of frames in the internal buffer. - * Consumes frames in a blocking manner and provides frames in a non-blocking manner. - */ -public class AllocatingAudioFrameBuffer extends AbstractAudioFrameBuffer { - private static final Logger log = LoggerFactory.getLogger(AudioFrameBuffer.class); - - private final int fullCapacity; - private final ArrayBlockingQueue audioFrames; - private final AtomicBoolean stopping; - - /** - * @param bufferDuration The length of the internal buffer in milliseconds - * @param format The format of the frames held in this buffer - * @param stopping Atomic boolean which has true value when the track is in a state of pending stop. - */ - public AllocatingAudioFrameBuffer(int bufferDuration, AudioDataFormat format, AtomicBoolean stopping) { - super(format); - this.fullCapacity = bufferDuration / 20 + 1; - this.audioFrames = new ArrayBlockingQueue<>(fullCapacity); - this.stopping = stopping; - } - - /** - * @return Number of frames that can be added to the buffer without blocking. - */ - @Override - public int getRemainingCapacity() { - return audioFrames.remainingCapacity(); - } - - /** - * @return Total number of frames that the buffer can hold. - */ - @Override - public int getFullCapacity() { - return fullCapacity; - } - - @Override - public AudioFrame provide() { - AudioFrame frame = audioFrames.poll(); - - if (frame == null) { - return fetchPendingTerminator(); - } - - return filterFrame(frame); - } - - @Override - public AudioFrame provide(long timeout, TimeUnit unit) throws TimeoutException, InterruptedException { - AudioFrame frame = audioFrames.poll(); - - if (frame == null) { - AudioFrame terminator = fetchPendingTerminator(); - if (terminator != null) { - return terminator; - } - - if (timeout > 0) { - frame = audioFrames.poll(timeout, unit); - - if (frame == null || frame.isTerminator()) { - terminator = fetchPendingTerminator(); - return terminator != null ? terminator : frame; - } - } - } else if (frame.isTerminator()) { - fetchPendingTerminator(); - return frame; - } - - return filterFrame(frame); - } - - @Override - public boolean provide(MutableAudioFrame targetFrame) { - return passToMutable(provide(), targetFrame); - } - - @Override - public boolean provide(MutableAudioFrame targetFrame, long timeout, TimeUnit unit) - throws TimeoutException, InterruptedException { - - return passToMutable(provide(timeout, unit), targetFrame); - } - - private boolean passToMutable(AudioFrame frame, MutableAudioFrame targetFrame) { - if (targetFrame != null) { - if (frame.isTerminator()) { - targetFrame.setTerminator(true); - } else { - targetFrame.setTimecode(frame.getTimecode()); - targetFrame.setVolume(frame.getVolume()); - targetFrame.store(frame.getData(), 0, frame.getDataLength()); - targetFrame.setTerminator(false); - } - - return true; - } - - return false; - } - - @Override - public void clear() { - audioFrames.clear(); - } - - @Override - public void rebuild(AudioFrameRebuilder rebuilder) { - List frames = new ArrayList<>(); - int frameCount = audioFrames.drainTo(frames); - - log.debug("Running rebuilder {} on {} buffered frames.", rebuilder.getClass().getSimpleName(), frameCount); - - for (AudioFrame frame : frames) { - audioFrames.add(rebuilder.rebuild(frame)); - } - } - - /** - * @return The timecode of the last frame in the buffer, null if the buffer is empty or is marked to be cleared upon - * receiving the next frame. - */ - @Override - public Long getLastInputTimecode() { - Long lastTimecode = null; - - synchronized (synchronizer) { - if (!clearOnInsert) { - for (AudioFrame frame : audioFrames) { - lastTimecode = frame.getTimecode(); - } - } - } - - return lastTimecode; - } - - @Override - public void consume(AudioFrame frame) throws InterruptedException { - // If an interrupt sent along with setting the stopping status was silently consumed elsewhere, this check should - // still trigger. Guarantees that stopped tracks cannot get stuck in this method. Possible performance improvement: - // offer with timeout, check stopping if timed out, then put? - if (stopping != null && stopping.get()) { - throw new InterruptedException(); - } - - if (!locked) { - receivedFrames = true; - - if (clearOnInsert) { - audioFrames.clear(); - clearOnInsert = false; - } - - if (frame instanceof AbstractMutableAudioFrame) { - frame = ((AbstractMutableAudioFrame) frame).freeze(); - } - - audioFrames.put(frame); - } - } - - private AudioFrame fetchPendingTerminator() { - synchronized (synchronizer) { - if (terminateOnEmpty) { - terminateOnEmpty = false; - terminated = true; - synchronizer.notifyAll(); - return TerminatorAudioFrame.INSTANCE; - } - } - - return null; - } - - private AudioFrame filterFrame(AudioFrame frame) { - if (frame != null && frame.getVolume() == 0) { - return new ImmutableAudioFrame(frame.getTimecode(), format.silenceBytes(), 0, format); - } - - return frame; - } - - @Override - protected void signalWaiters() { - audioFrames.offer(TerminatorAudioFrame.INSTANCE); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrame.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrame.java deleted file mode 100644 index 172cece..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrame.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; - -/** - * Represents an audio frame. - */ -public interface AudioFrame { - /** - * @return Absolute timecode of the frame in milliseconds. - */ - long getTimecode(); - - /** - * @return Volume of the current frame. - */ - int getVolume(); - - /** - * @return Length of the data of this frame. - */ - int getDataLength(); - - /** - * @return Byte array with the frame data. - */ - byte[] getData(); - - /** - * Before calling this method, the caller should verify that the data fits in the buffer using - * {@link #getDataLength()}. - * - * @param buffer Buffer to write the frame data to. - * @param offset Offset in the buffer to start writing at. - */ - void getData(byte[] buffer, int offset); - - /** - * @return The data format of this buffer. - */ - AudioDataFormat getFormat(); - - /** - * @return Whether this frame is a terminator. This is an internal concept of the player and should never be - * true in any frames received by the user. - */ - boolean isTerminator(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameBuffer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameBuffer.java deleted file mode 100644 index 6da6bae..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameBuffer.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -/** - * A frame buffer. Stores the specified duration worth of frames in the internal buffer. - * Consumes frames in a blocking manner and provides frames in a non-blocking manner. - */ -public interface AudioFrameBuffer extends AudioFrameProvider, AudioFrameConsumer { - - /** - * @return Number of frames that can be added to the buffer without blocking. - */ - int getRemainingCapacity(); - - /** - * @return Total number of frames that the buffer can hold. - */ - int getFullCapacity(); - - /** - * Wait until another thread has consumed a terminator frame from this buffer - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void waitForTermination() throws InterruptedException; - - /** - * Signal that no more input is expected and if the content frames have been consumed, emit a terminator frame. - */ - void setTerminateOnEmpty(); - - /** - * Signal that the next frame provided to the buffer will clear the frames before it. This is useful when the next - * data is not contiguous with the current frame buffer, but the remaining frames in the buffer should be used until - * the next data arrives to prevent a situation where the buffer cannot provide any frames for a while. - */ - void setClearOnInsert(); - - /** - * @return Whether the next frame is set to clear the buffer. - */ - boolean hasClearOnInsert(); - - /** - * Clear the buffer. - */ - void clear(); - - /** - * Lock the buffer so no more incoming frames are accepted. - */ - void lockBuffer(); - - /** - * @return True if this buffer has received any input frames. - */ - boolean hasReceivedFrames(); - - /** - * @return The timecode of the last frame in the buffer, null if the buffer is empty or is marked to be cleared upon - * receiving the next frame. - */ - Long getLastInputTimecode(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameBufferFactory.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameBufferFactory.java deleted file mode 100644 index 0be9e40..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameBufferFactory.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Factory for audio frame buffers. - */ -public interface AudioFrameBufferFactory { - /** - * @param bufferDuration Maximum duration of the buffer. The buffer may actually hold less in case the average size of - * frames exceeds {@link AudioDataFormat#expectedChunkSize()}. - * @param format The format of the frames held in this buffer. - * @param stopping Atomic boolean which has true value when the track is in a state of pending stop. - * @return A new frame buffer instance. - */ - AudioFrameBuffer create(int bufferDuration, AudioDataFormat format, AtomicBoolean stopping); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameConsumer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameConsumer.java deleted file mode 100644 index d434b51..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameConsumer.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -/** - * A consumer for audio frames - */ -public interface AudioFrameConsumer { - /** - * Consumes the frame, may block - * - * @param frame The frame to consume - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void consume(AudioFrame frame) throws InterruptedException; - - /** - * Rebuild all caches frames - * - * @param rebuilder The rebuilder to use - */ - void rebuild(AudioFrameRebuilder rebuilder); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameProvider.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameProvider.java deleted file mode 100644 index 76e78f2..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * A provider for audio frames - */ -public interface AudioFrameProvider { - /** - * @return Provided frame, or null if none available - */ - AudioFrame provide(); - - /** - * @param timeout Specifies the maximum time to wait for data. Pass 0 for non-blocking mode. - * @param unit Specifies the time unit of the maximum wait time. - * @return Provided frame. In case wait time is above zero, null indicates that no data is not available at the - * current moment, otherwise null means the end of the track. - * @throws TimeoutException When wait time is above zero, but no track info is found in that time. - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - AudioFrame provide(long timeout, TimeUnit unit) throws TimeoutException, InterruptedException; - - /** - * @param targetFrame Frame to update with the details and data of the provided frame. - * @return true if a frame was provided. - */ - boolean provide(MutableAudioFrame targetFrame); - - /** - * @param targetFrame Frame to update with the details and data of the provided frame. - * @param timeout Timeout. - * @param unit Time unit for the timeout value. - * @return true if a frame was provided. - * @throws TimeoutException If no frame became available within the timeout. - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - boolean provide(MutableAudioFrame targetFrame, long timeout, TimeUnit unit) - throws TimeoutException, InterruptedException; -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameProviderTools.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameProviderTools.java deleted file mode 100644 index 335cc6b..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameProviderTools.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * Encapsulates common behavior shared by different audio frame providers. - */ -public class AudioFrameProviderTools { - /** - * @param provider Delegates a call to frame provide without timeout to the timed version of it. - * @return The audio frame from provide method. - */ - public static AudioFrame delegateToTimedProvide(AudioFrameProvider provider) { - try { - return provider.provide(0, TimeUnit.MILLISECONDS); - } catch (TimeoutException | InterruptedException e) { - ExceptionTools.keepInterrupted(e); - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameRebuilder.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameRebuilder.java deleted file mode 100644 index d228021..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioFrameRebuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -/** - * Interface for classes which can rebuild audio frames. - */ -public interface AudioFrameRebuilder { - /** - * Rebuilds a frame (for example by reencoding) - * - * @param frame The audio frame - * @return The new frame (may be the same as input) - */ - AudioFrame rebuild(AudioFrame frame); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioProcessingContext.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioProcessingContext.java deleted file mode 100644 index 90c63eb..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioProcessingContext.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; -import com.sedmelluq.discord.lavaplayer.player.AudioPlayerOptions; - -/** - * Context for processing audio. Contains configuration for encoding and the output where the frames go to. - */ -public class AudioProcessingContext { - /** - * Audio encoding or filtering related configuration - */ - public final AudioConfiguration configuration; - /** - * Consumer for the produced audio frames - */ - public final AudioFrameBuffer frameBuffer; - /** - * Mutable volume level for the audio - */ - public final AudioPlayerOptions playerOptions; - /** - * Output format to use throughout this processing cycle - */ - public final AudioDataFormat outputFormat; - /** - * Whether filter factory change is applied to already playing tracks. - */ - public final boolean filterHotSwapEnabled; - - /** - * @param configuration Audio encoding or filtering related configuration - * @param frameBuffer Frame buffer for the produced audio frames - * @param playerOptions State of the audio player. - * @param outputFormat Output format to use throughout this processing cycle - */ - public AudioProcessingContext(AudioConfiguration configuration, AudioFrameBuffer frameBuffer, - AudioPlayerOptions playerOptions, AudioDataFormat outputFormat) { - - this.configuration = configuration; - this.frameBuffer = frameBuffer; - this.playerOptions = playerOptions; - this.outputFormat = outputFormat; - this.filterHotSwapEnabled = configuration.isFilterHotSwapEnabled(); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioTrackExecutor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioTrackExecutor.java deleted file mode 100644 index ff7f7ac..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/AudioTrackExecutor.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.track.AudioTrackState; -import com.sedmelluq.discord.lavaplayer.track.TrackMarker; -import com.sedmelluq.discord.lavaplayer.track.TrackStateListener; - -/** - * Executor which handles track execution and all operations on playing tracks. - */ -public interface AudioTrackExecutor extends AudioFrameProvider { - /** - * @return The audio buffer of this executor. - */ - AudioFrameBuffer getAudioBuffer(); - - /** - * Execute the track, which means that this thread will fill the frame buffer until the track finishes or is stopped. - * - * @param listener Listener for track state events - */ - void execute(TrackStateListener listener); - - /** - * Stop playing the track, terminating the thread that is filling the frame buffer. - */ - void stop(); - - /** - * @return Timecode of the last played frame or in case a seek is in progress, the timecode of the frame being seeked to. - */ - long getPosition(); - - /** - * Perform seek to the specified timecode. - * - * @param timecode The timecode in milliseconds - */ - void setPosition(long timecode); - - /** - * @return Current state of the executor - */ - AudioTrackState getState(); - - /** - * Set track position marker. - * - * @param marker Track position marker to set. - */ - void setMarker(TrackMarker marker); - - /** - * @return True if this track threw an exception before it provided any audio. - */ - boolean failedBeforeLoad(); -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/ImmutableAudioFrame.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/ImmutableAudioFrame.java deleted file mode 100644 index 25af86d..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/ImmutableAudioFrame.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; - -/** - * A single audio frame. - */ -public class ImmutableAudioFrame implements AudioFrame { - /** - * Timecode of this frame in milliseconds. - */ - public final long timecode; - - /** - * Buffer for this frame, in the format specified in the format field. - */ - public final byte[] data; - - /** - * Volume level of the audio in this frame. Internally when this value is 0, the data may actually contain a - * non-silent frame. This is to allow frames with 0 volume to be modified later. These frames should still be - * handled as silent frames. - */ - public final int volume; - - /** - * Specifies the format of audio in the data buffer. - */ - public final AudioDataFormat format; - - /** - * @param timecode Timecode of this frame in milliseconds. - * @param data Buffer for this frame, in the format specified in the format field. - * @param volume Volume level of the audio in this frame. - * @param format Specifies the format of audio in the data buffer. - */ - public ImmutableAudioFrame(long timecode, byte[] data, int volume, AudioDataFormat format) { - this.timecode = timecode; - this.data = data; - this.volume = volume; - this.format = format; - } - - @Override - public long getTimecode() { - return timecode; - } - - @Override - public int getVolume() { - return volume; - } - - @Override - public int getDataLength() { - return data.length; - } - - @Override - public byte[] getData() { - return data; - } - - @Override - public void getData(byte[] buffer, int offset) { - System.arraycopy(data, 0, buffer, offset, data.length); - } - - @Override - public AudioDataFormat getFormat() { - return format; - } - - @Override - public boolean isTerminator() { - return false; - } -} \ No newline at end of file diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/LocalAudioTrackExecutor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/LocalAudioTrackExecutor.java deleted file mode 100644 index ad8b876..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/LocalAudioTrackExecutor.java +++ /dev/null @@ -1,470 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; -import com.sedmelluq.discord.lavaplayer.player.AudioPlayerOptions; -import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.InterruptedIOException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; - -import static com.sedmelluq.discord.lavaplayer.tools.ExceptionTools.findDeepException; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.FAULT; -import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.SUSPICIOUS; -import static com.sedmelluq.discord.lavaplayer.track.TrackMarkerHandler.MarkerState.ENDED; -import static com.sedmelluq.discord.lavaplayer.track.TrackMarkerHandler.MarkerState.STOPPED; - -/** - * Handles the execution and output buffering of an audio track. - */ -public class LocalAudioTrackExecutor implements AudioTrackExecutor { - private static final Logger log = LoggerFactory.getLogger(LocalAudioTrackExecutor.class); - - private final InternalAudioTrack audioTrack; - private final AudioProcessingContext processingContext; - private final boolean useSeekGhosting; - private final AudioFrameBuffer frameBuffer; - private final AtomicReference playingThread = new AtomicReference<>(); - private final AtomicBoolean queuedStop = new AtomicBoolean(false); - private final AtomicLong queuedSeek = new AtomicLong(-1); - private final AtomicLong lastFrameTimecode = new AtomicLong(0); - private final AtomicReference state = new AtomicReference<>(AudioTrackState.INACTIVE); - private final Object actionSynchronizer = new Object(); - private final TrackMarkerTracker markerTracker = new TrackMarkerTracker(); - private boolean interruptibleForSeek = false; - private volatile Throwable trackException; - - /** - * @param audioTrack The audio track that this executor executes - * @param configuration Configuration to use for audio processing - * @param playerOptions Mutable player options (for example volume). - * @param useSeekGhosting Whether to keep providing old frames continuing from the previous position during a seek - * until frames from the new position arrive. - * @param bufferDuration The size of the frame buffer in milliseconds - */ - public LocalAudioTrackExecutor(InternalAudioTrack audioTrack, AudioConfiguration configuration, - AudioPlayerOptions playerOptions, boolean useSeekGhosting, int bufferDuration) { - - this.audioTrack = audioTrack; - AudioDataFormat currentFormat = configuration.getOutputFormat(); - this.frameBuffer = configuration.getFrameBufferFactory().create(bufferDuration, currentFormat, queuedStop); - this.processingContext = new AudioProcessingContext(configuration, frameBuffer, playerOptions, currentFormat); - this.useSeekGhosting = useSeekGhosting; - } - - public AudioProcessingContext getProcessingContext() { - return processingContext; - } - - @Override - public AudioFrameBuffer getAudioBuffer() { - return frameBuffer; - } - - @Override - public void execute(TrackStateListener listener) { - InterruptedException interrupt = null; - - if (Thread.interrupted()) { - log.debug("Cleared a stray interrupt."); - } - - if (playingThread.compareAndSet(null, Thread.currentThread())) { - log.debug("Starting to play track {} locally with listener {}", audioTrack.getInfo().identifier, listener); - - state.set(AudioTrackState.LOADING); - - try { - audioTrack.process(this); - - log.debug("Playing track {} finished or was stopped.", audioTrack.getIdentifier()); - } catch (Throwable e) { - // Temporarily clear the interrupted status so it would not disrupt listener methods. - interrupt = findInterrupt(e); - - if (interrupt != null && checkStopped()) { - log.debug("Track {} was interrupted outside of execution loop.", audioTrack.getIdentifier()); - } else { - frameBuffer.setTerminateOnEmpty(); - - FriendlyException exception = ExceptionTools.wrapUnfriendlyExceptions("Something broke when playing the track.", FAULT, e); - ExceptionTools.log(log, exception, "playback of " + audioTrack.getIdentifier()); - - trackException = exception; - listener.onTrackException(audioTrack, exception); - - ExceptionTools.rethrowErrors(e); - } - } finally { - synchronized (actionSynchronizer) { - interrupt = interrupt != null ? interrupt : findInterrupt(null); - - playingThread.compareAndSet(Thread.currentThread(), null); - - markerTracker.trigger(ENDED); - state.set(AudioTrackState.FINISHED); - } - - if (interrupt != null) { - Thread.currentThread().interrupt(); - } - } - } else { - log.warn("Tried to start an already playing track {}", audioTrack.getIdentifier()); - } - } - - @Override - public void stop() { - synchronized (actionSynchronizer) { - Thread thread = playingThread.get(); - - if (thread != null) { - log.debug("Requesting stop for track {}", audioTrack.getIdentifier()); - - queuedStop.compareAndSet(false, true); - thread.interrupt(); - } else { - log.debug("Tried to stop track {} which is not playing.", audioTrack.getIdentifier()); - } - } - } - - /** - * @return True if the track has been scheduled to stop and then clears the scheduled stop bit. - */ - public boolean checkStopped() { - if (queuedStop.compareAndSet(true, false)) { - state.set(AudioTrackState.STOPPING); - return true; - } - - return false; - } - - /** - * Wait until all the frames from the frame buffer have been consumed. Keeps the buffering thread alive to keep it - * interruptible for seeking until buffer is empty. - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - public void waitOnEnd() throws InterruptedException { - frameBuffer.setTerminateOnEmpty(); - frameBuffer.waitForTermination(); - } - - /** - * Interrupt the buffering thread, either stop or seek should have been set beforehand. - * - * @return True if there was a thread to interrupt. - */ - public boolean interrupt() { - synchronized (actionSynchronizer) { - Thread thread = playingThread.get(); - - if (thread != null) { - thread.interrupt(); - return true; - } - - return false; - } - } - - @Override - public long getPosition() { - long seek = queuedSeek.get(); - return seek != -1 ? seek : lastFrameTimecode.get(); - } - - @Override - public void setPosition(long timecode) { - if (!audioTrack.isSeekable()) { - return; - } - - synchronized (actionSynchronizer) { - if (timecode < 0) { - timecode = 0; - } - - queuedSeek.set(timecode); - - if (!useSeekGhosting) { - frameBuffer.clear(); - } - - interruptForSeek(); - } - } - - @Override - public AudioTrackState getState() { - return state.get(); - } - - /** - * @return True if this track is currently in the middle of a seek. - */ - private boolean isPerformingSeek() { - return queuedSeek.get() != -1 || (useSeekGhosting && frameBuffer.hasClearOnInsert()); - } - - @Override - public void setMarker(TrackMarker marker) { - markerTracker.set(marker, getPosition()); - } - - @Override - public boolean failedBeforeLoad() { - return trackException != null && !frameBuffer.hasReceivedFrames(); - } - - /** - * Execute the read and seek loop for the track. - * - * @param readExecutor Callback for reading the track - * @param seekExecutor Callback for performing a seek on the track, may be null on a non-seekable track - */ - public void executeProcessingLoop(ReadExecutor readExecutor, SeekExecutor seekExecutor) { - boolean proceed = true; - - if (checkPendingSeek(seekExecutor) == SeekResult.EXTERNAL_SEEK) { - return; - } - - while (proceed) { - state.set(AudioTrackState.PLAYING); - proceed = false; - - try { - // An interrupt may have been placed while we were handling the previous one. - if (Thread.interrupted() && !handlePlaybackInterrupt(null, seekExecutor)) { - break; - } - - setInterruptibleForSeek(true); - readExecutor.performRead(); - setInterruptibleForSeek(false); - - // Must not finish before terminator frame has been consumed the user may still want to perform seeks until then - waitOnEnd(); - } catch (Exception e) { - setInterruptibleForSeek(false); - InterruptedException interruption = findInterrupt(e); - - if (interruption != null) { - proceed = handlePlaybackInterrupt(interruption, seekExecutor); - } else { - throw ExceptionTools.wrapUnfriendlyExceptions("Something went wrong when decoding the track.", FAULT, e); - } - } - } - } - - private void setInterruptibleForSeek(boolean state) { - synchronized (actionSynchronizer) { - interruptibleForSeek = state; - } - } - - private void interruptForSeek() { - boolean interrupted = false; - - synchronized (actionSynchronizer) { - if (interruptibleForSeek) { - interruptibleForSeek = false; - Thread thread = playingThread.get(); - - if (thread != null) { - thread.interrupt(); - interrupted = true; - } - } - } - - if (interrupted) { - log.debug("Interrupting playing thread to perform a seek {}", audioTrack.getIdentifier()); - } else { - log.debug("Seeking on track {} while not in playback loop.", audioTrack.getIdentifier()); - } - } - - private boolean handlePlaybackInterrupt(InterruptedException interruption, SeekExecutor seekExecutor) { - Thread.interrupted(); - - if (checkStopped()) { - markerTracker.trigger(STOPPED); - return false; - } - - SeekResult seekResult = checkPendingSeek(seekExecutor); - - if (seekResult != SeekResult.NO_SEEK) { - // Double-check, might have received a stop request while seeking - if (checkStopped()) { - markerTracker.trigger(STOPPED); - return false; - } else { - return seekResult == SeekResult.INTERNAL_SEEK; - } - } else if (interruption != null) { - Thread.currentThread().interrupt(); - throw new FriendlyException("The track was unexpectedly terminated.", SUSPICIOUS, interruption); - } else { - return true; - } - } - - private InterruptedException findInterrupt(Throwable throwable) { - InterruptedException exception = findDeepException(throwable, InterruptedException.class); - - if (exception == null) { - InterruptedIOException ioException = findDeepException(throwable, InterruptedIOException.class); - - if (ioException != null && (ioException.getMessage() == null || !ioException.getMessage().contains("timed out"))) { - exception = new InterruptedException(ioException.getMessage()); - } - } - - if (exception == null && Thread.interrupted()) { - return new InterruptedException(); - } - - return exception; - } - - /** - * Performs a seek if it scheduled. - * - * @param seekExecutor Callback for performing a seek on the track - * @return True if a seek was performed - */ - private SeekResult checkPendingSeek(SeekExecutor seekExecutor) { - if (!audioTrack.isSeekable()) { - return SeekResult.NO_SEEK; - } - - long seekPosition; - - synchronized (actionSynchronizer) { - seekPosition = queuedSeek.get(); - - if (seekPosition == -1) { - return SeekResult.NO_SEEK; - } - - log.debug("Track {} interrupted for seeking to {}.", audioTrack.getIdentifier(), seekPosition); - applySeekState(seekPosition); - } - - if (seekExecutor != null) { - try { - seekExecutor.performSeek(seekPosition); - } catch (Exception e) { - throw ExceptionTools.wrapUnfriendlyExceptions("Something went wrong when seeking to a position.", FAULT, e); - } - - return SeekResult.INTERNAL_SEEK; - } else { - return SeekResult.EXTERNAL_SEEK; - } - } - - private void applySeekState(long seekPosition) { - state.set(AudioTrackState.SEEKING); - - if (useSeekGhosting) { - frameBuffer.setClearOnInsert(); - } else { - frameBuffer.clear(); - } - - queuedSeek.set(-1); - markerTracker.checkSeekTimecode(seekPosition); - } - - @Override - public AudioFrame provide() { - AudioFrame frame = frameBuffer.provide(); - processProvidedFrame(frame); - return frame; - } - - @Override - public AudioFrame provide(long timeout, TimeUnit unit) throws TimeoutException, InterruptedException { - AudioFrame frame = frameBuffer.provide(timeout, unit); - processProvidedFrame(frame); - return frame; - } - - @Override - public boolean provide(MutableAudioFrame targetFrame) { - if (frameBuffer.provide(targetFrame)) { - processProvidedFrame(targetFrame); - return true; - } - - return false; - } - - @Override - public boolean provide(MutableAudioFrame targetFrame, long timeout, TimeUnit unit) - throws TimeoutException, InterruptedException { - - if (frameBuffer.provide(targetFrame, timeout, unit)) { - processProvidedFrame(targetFrame); - return true; - } - - return true; - } - - private void processProvidedFrame(AudioFrame frame) { - if (frame != null && !frame.isTerminator()) { - if (!isPerformingSeek()) { - markerTracker.checkPlaybackTimecode(frame.getTimecode()); - } - - lastFrameTimecode.set(frame.getTimecode()); - } - } - - /** - * Read executor, see method description - */ - public interface ReadExecutor { - /** - * Reads until interrupted or EOF. - * - * @throws InterruptedException When interrupted externally (or for seek/stop). - */ - void performRead() throws InterruptedException; - } - - /** - * Seek executor, see method description - */ - public interface SeekExecutor { - /** - * Perform a seek to the specified position - * - * @param position Position in milliseconds - */ - void performSeek(long position); - } - - private enum SeekResult { - NO_SEEK, - INTERNAL_SEEK, - EXTERNAL_SEEK - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/MutableAudioFrame.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/MutableAudioFrame.java deleted file mode 100644 index 59e2369..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/MutableAudioFrame.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import java.nio.ByteBuffer; - -/** - * A mutable audio frame. - */ -public class MutableAudioFrame extends AbstractMutableAudioFrame { - private ByteBuffer frameBuffer; - private int framePosition; - private int frameLength; - - /** - * This should be called only by the requester of a frame. - * - * @param frameBuffer Buffer to use internally. - */ - public void setBuffer(ByteBuffer frameBuffer) { - this.frameBuffer = frameBuffer; - this.framePosition = frameBuffer.position(); - this.frameLength = frameBuffer.remaining(); - } - - /** - * This should be called only by the provider of a frame. - * - * @param buffer Buffer to copy data from into the internal buffer of this instance. - * @param offset Offset in the buffer. - * @param length Length of the data to copy. - */ - public void store(byte[] buffer, int offset, int length) { - frameBuffer.position(framePosition); - frameBuffer.limit(frameBuffer.capacity()); - frameBuffer.put(buffer, offset, length); - frameLength = length; - } - - @Override - public int getDataLength() { - return frameLength; - } - - @Override - public byte[] getData() { - byte[] data = new byte[getDataLength()]; - getData(data, 0); - return data; - } - - @Override - public void getData(byte[] buffer, int offset) { - int previous = frameBuffer.position(); - frameBuffer.position(framePosition); - frameBuffer.get(buffer, offset, frameLength); - frameBuffer.position(previous); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/NonAllocatingAudioFrameBuffer.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/NonAllocatingAudioFrameBuffer.java deleted file mode 100644 index cf19352..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/NonAllocatingAudioFrameBuffer.java +++ /dev/null @@ -1,320 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Audio frame buffer implementation which never allocates any new objects after creation. All instances of mutable - * frames are preallocated, and for the data there is one byte buffer which is used as a ring buffer for the frame data. - */ -public class NonAllocatingAudioFrameBuffer extends AbstractAudioFrameBuffer { - private static final Logger log = LoggerFactory.getLogger(NonAllocatingAudioFrameBuffer.class); - - private final int worstCaseFrameCount; - private final ReferenceMutableAudioFrame[] frames; - private final ReferenceMutableAudioFrame silentFrame; - private final AtomicBoolean stopping; - private MutableAudioFrame bridgeFrame; - - private final byte[] frameBuffer; - private int firstFrame; - private int frameCount; - - /** - * @param bufferDuration The length of the internal buffer in milliseconds - * @param format The format of the frames held in this buffer - * @param stopping Atomic boolean which has true value when the track is in a state of pending stop. - */ - public NonAllocatingAudioFrameBuffer(int bufferDuration, AudioDataFormat format, AtomicBoolean stopping) { - super(format); - int maximumFrameCount = bufferDuration / (int) format.frameDuration() + 1; - frames = createFrames(maximumFrameCount, format); - silentFrame = createSilentFrame(format); - this.frameBuffer = new byte[format.expectedChunkSize() * maximumFrameCount]; - worstCaseFrameCount = frameBuffer.length / format.maximumChunkSize(); - this.stopping = stopping; - } - - /** - * @return Number of frames that can be added to the buffer without blocking. - */ - @Override - public int getRemainingCapacity() { - synchronized (synchronizer) { - if (frameCount == 0) { - return worstCaseFrameCount; - } - - int lastFrame = wrappedFrameIndex(firstFrame + frameCount - 1); - - int bufferHead = frames[firstFrame].getFrameOffset(); - int bufferTail = frames[lastFrame].getFrameEndOffset(); - - int maximumFrameSize = format.maximumChunkSize(); - - if (bufferHead < bufferTail) { - return (frameBuffer.length - bufferTail) / maximumFrameSize + bufferHead / maximumFrameSize; - } else { - return (bufferHead - bufferTail) / maximumFrameSize; - } - } - } - - /** - * @return Total number of frames that the buffer can hold. - */ - @Override - public int getFullCapacity() { - return worstCaseFrameCount; - } - - @Override - public void consume(AudioFrame frame) throws InterruptedException { - // If an interrupt sent along with setting the stopping status was silently consumed elsewhere, this check should - // still trigger. Guarantees that stopped tracks cannot get stuck in this method. Possible performance improvement: - // offer with timeout, check stopping if timed out, then put? - if (stopping != null && stopping.get()) { - throw new InterruptedException(); - } - - synchronized (synchronizer) { - if (!locked) { - receivedFrames = true; - - if (clearOnInsert) { - clear(); - clearOnInsert = false; - } - - while (!attemptStore(frame)) { - synchronizer.wait(); - } - - synchronizer.notifyAll(); - } - } - } - - @Override - public AudioFrame provide() { - synchronized (synchronizer) { - if (provide(getBridgeFrame())) { - return unwrapBridgeFrame(); - } - - return null; - } - } - - @Override - public AudioFrame provide(long timeout, TimeUnit unit) throws TimeoutException, InterruptedException { - synchronized (synchronizer) { - if (provide(getBridgeFrame(), timeout, unit)) { - return unwrapBridgeFrame(); - } - - return null; - } - } - - @Override - public boolean provide(MutableAudioFrame targetFrame) { - synchronized (synchronizer) { - if (frameCount == 0) { - if (terminateOnEmpty) { - popPendingTerminator(targetFrame); - synchronizer.notifyAll(); - return true; - } - return false; - } else { - popFrame(targetFrame); - synchronizer.notifyAll(); - return true; - } - } - } - - @Override - public boolean provide(MutableAudioFrame targetFrame, long timeout, TimeUnit unit) - throws TimeoutException, InterruptedException { - - long currentTime = System.nanoTime(); - long endTime = currentTime + unit.toMillis(timeout); - - synchronized (synchronizer) { - while (frameCount == 0) { - if (terminateOnEmpty) { - popPendingTerminator(targetFrame); - synchronizer.notifyAll(); - return true; - } - - synchronizer.wait(endTime - currentTime); - currentTime = System.nanoTime(); - - if (currentTime >= endTime) { - throw new TimeoutException(); - } - } - - popFrame(targetFrame); - synchronizer.notifyAll(); - return true; - } - } - - private void popFrame(MutableAudioFrame targetFrame) { - ReferenceMutableAudioFrame frame = frames[firstFrame]; - - if (frame.getVolume() == 0) { - silentFrame.setTimecode(frame.getTimecode()); - frame = silentFrame; - } - - targetFrame.setTimecode(frame.getTimecode()); - targetFrame.setVolume(frame.getVolume()); - targetFrame.setTerminator(false); - targetFrame.store(frame.getFrameBuffer(), frame.getFrameOffset(), frame.getDataLength()); - - firstFrame = wrappedFrameIndex(firstFrame + 1); - frameCount--; - } - - private void popPendingTerminator(MutableAudioFrame frame) { - terminateOnEmpty = false; - terminated = true; - - frame.setTerminator(true); - } - - @Override - public void clear() { - synchronized (synchronizer) { - frameCount = 0; - } - } - - @Override - public void rebuild(AudioFrameRebuilder rebuilder) { - log.debug("Frame rebuild not supported on non-allocating frame buffer yet."); - } - - @Override - public Long getLastInputTimecode() { - synchronized (synchronizer) { - if (!clearOnInsert && frameCount > 0) { - return frames[wrappedFrameIndex(firstFrame + frameCount - 1)].getTimecode(); - } - } - - return null; - } - - private boolean attemptStore(AudioFrame frame) { - if (frameCount >= frames.length) { - return false; - } - - int frameLength = frame.getDataLength(); - int frameBufferLength = frameBuffer.length; - - if (frameCount == 0) { - firstFrame = 0; - - if (frameLength > frameBufferLength) { - throw new IllegalArgumentException("Frame is too big for buffer."); - } - - store(frame, 0, 0, frameLength); - } else { - int lastFrame = wrappedFrameIndex(firstFrame + frameCount - 1); - int nextFrame = wrappedFrameIndex(lastFrame + 1); - - int bufferHead = frames[firstFrame].getFrameOffset(); - int bufferTail = frames[lastFrame].getFrameEndOffset(); - - if (bufferHead < bufferTail) { - if (bufferTail + frameLength <= frameBufferLength) { - store(frame, nextFrame, bufferTail, frameLength); - } else if (bufferHead >= frameLength) { - store(frame, nextFrame, 0, frameLength); - } else { - return false; - } - } else if (bufferTail + frameLength <= bufferHead) { - store(frame, nextFrame, bufferTail, frameLength); - } else { - return false; - } - } - - return true; - } - - private int wrappedFrameIndex(int index) { - int maximumFrameCount = frames.length; - return index >= maximumFrameCount ? index - maximumFrameCount : index; - } - - private void store(AudioFrame frame, int index, int frameOffset, int frameLength) { - ReferenceMutableAudioFrame targetFrame = frames[index]; - targetFrame.setTimecode(frame.getTimecode()); - targetFrame.setVolume(frame.getVolume()); - targetFrame.setDataReference(frameBuffer, frameOffset, frameLength); - - frame.getData(frameBuffer, frameOffset); - - frameCount++; - } - - private MutableAudioFrame getBridgeFrame() { - if (bridgeFrame == null) { - bridgeFrame = new MutableAudioFrame(); - bridgeFrame.setBuffer(ByteBuffer.allocate(format.maximumChunkSize())); - } - - return bridgeFrame; - } - - private AudioFrame unwrapBridgeFrame() { - if (bridgeFrame.isTerminator()) { - return TerminatorAudioFrame.INSTANCE; - } else { - return new ImmutableAudioFrame(bridgeFrame.getTimecode(), bridgeFrame.getData(), bridgeFrame.getVolume(), - bridgeFrame.getFormat()); - } - } - - private static ReferenceMutableAudioFrame[] createFrames(int frameCount, AudioDataFormat format) { - ReferenceMutableAudioFrame[] frames = new ReferenceMutableAudioFrame[frameCount]; - - for (int i = 0; i < frames.length; i++) { - frames[i] = new ReferenceMutableAudioFrame(); - frames[i].setFormat(format); - } - - return frames; - } - - private static ReferenceMutableAudioFrame createSilentFrame(AudioDataFormat format) { - ReferenceMutableAudioFrame frame = new ReferenceMutableAudioFrame(); - frame.setFormat(format); - frame.setDataReference(format.silenceBytes(), 0, format.silenceBytes().length); - frame.setVolume(0); - return frame; - } - - @Override - protected void signalWaiters() { - synchronized (synchronizer) { - synchronizer.notifyAll(); - } - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/PrimordialAudioTrackExecutor.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/PrimordialAudioTrackExecutor.java deleted file mode 100644 index d77d258..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/PrimordialAudioTrackExecutor.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.track.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * Executor implementation which is used before a track has actually been executed. Saves the position and loop - * information, which is applied to the actual executor when one is attached. - */ -public class PrimordialAudioTrackExecutor implements AudioTrackExecutor { - private static final Logger log = LoggerFactory.getLogger(LocalAudioTrackExecutor.class); - - private final AudioTrackInfo trackInfo; - private final TrackMarkerTracker markerTracker; - - private volatile long position; - - /** - * @param trackInfo Information of the track this executor is used with - */ - public PrimordialAudioTrackExecutor(AudioTrackInfo trackInfo) { - this.trackInfo = trackInfo; - this.markerTracker = new TrackMarkerTracker(); - } - - @Override - public AudioFrameBuffer getAudioBuffer() { - return null; - } - - @Override - public void execute(TrackStateListener listener) { - throw new UnsupportedOperationException(); - } - - @Override - public void stop() { - log.info("Tried to stop track {} which is not playing.", trackInfo.identifier); - } - - @Override - public long getPosition() { - return position; - } - - @Override - public void setPosition(long timecode) { - position = timecode; - markerTracker.checkSeekTimecode(timecode); - } - - @Override - public AudioTrackState getState() { - return AudioTrackState.INACTIVE; - } - - @Override - public void setMarker(TrackMarker marker) { - markerTracker.set(marker, position); - } - - @Override - public boolean failedBeforeLoad() { - return false; - } - - @Override - public AudioFrame provide() { - return provide(0, TimeUnit.MILLISECONDS); - } - - @Override - public AudioFrame provide(long timeout, TimeUnit unit) { - return null; - } - - @Override - public boolean provide(MutableAudioFrame targetFrame) { - return false; - } - - @Override - public boolean provide(MutableAudioFrame targetFrame, long timeout, TimeUnit unit) - throws TimeoutException, InterruptedException { - - return false; - } - - /** - * Apply the position and loop state that had been set on this executor to an actual executor. - * - * @param executor The executor to apply the state to - */ - public void applyStateToExecutor(AudioTrackExecutor executor) { - if (position != 0) { - executor.setPosition(position); - } - - executor.setMarker(markerTracker.remove()); - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/ReferenceMutableAudioFrame.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/ReferenceMutableAudioFrame.java deleted file mode 100644 index f28cd7a..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/ReferenceMutableAudioFrame.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -/** - * Mutable audio frame which contains no dedicated buffer, but refers to a segment in a specified byte buffer. - */ -public class ReferenceMutableAudioFrame extends AbstractMutableAudioFrame { - private byte[] frameBuffer; - private int frameOffset; - private int frameLength; - - /** - * @return The underlying byte buffer. - */ - public byte[] getFrameBuffer() { - return frameBuffer; - } - - /** - * @return Offset of the frame data in the underlying byte buffer. - */ - public int getFrameOffset() { - return frameOffset; - } - - /** - * @return Offset of the end of frame data in the underlying byte buffer. - */ - public int getFrameEndOffset() { - return frameOffset + frameLength; - } - - @Override - public int getDataLength() { - return frameLength; - } - - @Override - public byte[] getData() { - byte[] data = new byte[frameLength]; - getData(data, 0); - return data; - } - - @Override - public void getData(byte[] buffer, int offset) { - System.arraycopy(frameBuffer, frameOffset, buffer, offset, frameLength); - } - - /** - * @param frameBuffer See {@link #getFrameBuffer()}. - * @param frameOffset See {@link #getFrameOffset()}. - * @param frameLength See {@link #getDataLength()}. - */ - public void setDataReference(byte[] frameBuffer, int frameOffset, int frameLength) { - this.frameBuffer = frameBuffer; - this.frameOffset = frameOffset; - this.frameLength = frameLength; - } -} diff --git a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/TerminatorAudioFrame.java b/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/TerminatorAudioFrame.java deleted file mode 100644 index 816d7b2..0000000 --- a/src/main/java/com/sedmelluq/discord/lavaplayer/track/playback/TerminatorAudioFrame.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.sedmelluq.discord.lavaplayer.track.playback; - -import com.sedmelluq.discord.lavaplayer.format.AudioDataFormat; - -/** - * Audio frame where {@link #isTerminator()} is true. - */ -public class TerminatorAudioFrame implements AudioFrame { - public static final TerminatorAudioFrame INSTANCE = new TerminatorAudioFrame(); - - @Override - public long getTimecode() { - throw new UnsupportedOperationException(); - } - - @Override - public int getVolume() { - throw new UnsupportedOperationException(); - } - - @Override - public int getDataLength() { - throw new UnsupportedOperationException(); - } - - @Override - public byte[] getData() { - throw new UnsupportedOperationException(); - } - - @Override - public void getData(byte[] buffer, int offset) { - throw new UnsupportedOperationException(); - } - - @Override - public AudioDataFormat getFormat() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isTerminator() { - return true; - } -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryBinaryProvider.java b/src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryBinaryProvider.java deleted file mode 100644 index ffc4eb0..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryBinaryProvider.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.sedmelluq.lava.common.natives; - -import com.sedmelluq.lava.common.natives.architecture.SystemType; - -import java.io.InputStream; - -public interface NativeLibraryBinaryProvider { - /** - * @param systemType Detected system type. - * @param libraryName Name of the library to load. - * @return Stream to the library binary. null causes failure. - */ - InputStream getLibraryStream(SystemType systemType, String libraryName); -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryLoader.java b/src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryLoader.java deleted file mode 100644 index 42a1684..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryLoader.java +++ /dev/null @@ -1,210 +0,0 @@ -package com.sedmelluq.lava.common.natives; - -import com.sedmelluq.lava.common.natives.architecture.SystemType; -import org.apache.commons.io.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.*; -import java.util.function.Predicate; - -import static java.nio.file.attribute.PosixFilePermissions.asFileAttribute; -import static java.nio.file.attribute.PosixFilePermissions.fromString; - -/** - * Loads native libraries by name. Libraries are expected to be in classpath /natives/[arch]/[prefix]name[suffix] - */ -public class NativeLibraryLoader { - private static final Logger log = LoggerFactory.getLogger(NativeLibraryLoader.class); - - private static final String DEFAULT_PROPERTY_PREFIX = "lava.native."; - private static final String DEFAULT_RESOURCE_ROOT = "/natives/"; - - private final String libraryName; - private final Predicate systemFilter; - private final NativeLibraryProperties properties; - private final NativeLibraryBinaryProvider binaryProvider; - private final Object lock; - private volatile RuntimeException previousFailure; - private volatile Boolean previousResult; - - public NativeLibraryLoader(String libraryName, Predicate systemFilter, NativeLibraryProperties properties, - NativeLibraryBinaryProvider binaryProvider) { - - this.libraryName = libraryName; - this.systemFilter = systemFilter; - this.binaryProvider = binaryProvider; - this.properties = properties; - this.lock = new Object(); - } - - public static NativeLibraryLoader create(Class classLoaderSample, String libraryName) { - return createFiltered(classLoaderSample, libraryName, null); - } - - public static NativeLibraryLoader createFiltered(Class classLoaderSample, String libraryName, - Predicate systemFilter) { - - return new NativeLibraryLoader( - libraryName, - systemFilter, - new SystemNativeLibraryProperties(libraryName, DEFAULT_PROPERTY_PREFIX), - new ResourceNativeLibraryBinaryProvider(classLoaderSample, DEFAULT_RESOURCE_ROOT) - ); - } - - public void load() { - Boolean result = previousResult; - - if (result == null) { - synchronized (lock) { - result = previousResult; - - if (result == null) { - loadAndRemember(); - return; - } - } - } - - if (!result) { - throw previousFailure; - } - } - - private void loadAndRemember() { - log.info("Native library {}: loading with filter {}", libraryName, systemFilter); - - try { - loadInternal(); - previousResult = true; - } catch (Throwable e) { - log.error("Native library {}: loading failed.", e); - - previousFailure = new RuntimeException(e); - previousResult = false; - } - } - - private void loadInternal() { - String explicitPath = properties.getLibraryPath(); - - if (explicitPath != null) { - log.debug("Native library {}: explicit path provided {}", libraryName, explicitPath); - - loadFromFile(Paths.get(explicitPath).toAbsolutePath()); - } else { - SystemType systemType = detectMatchingSystemType(); - - if (systemType != null) { - String explicitDirectory = properties.getLibraryDirectory(); - - if (explicitDirectory != null) { - log.debug("Native library {}: explicit directory provided {}", libraryName, explicitDirectory); - - loadFromFile(Paths.get(explicitDirectory, systemType.formatLibraryName(libraryName)).toAbsolutePath()); - } else { - loadFromFile(extractLibraryFromResources(systemType)); - } - } - } - } - - private void loadFromFile(Path libraryFilePath) { - log.debug("Native library {}: attempting to load library at {}", libraryName, libraryFilePath); - System.load(libraryFilePath.toAbsolutePath().toString()); - log.info("Native library {}: successfully loaded.", libraryName); - } - - private Path extractLibraryFromResources(SystemType systemType) { - try (InputStream libraryStream = binaryProvider.getLibraryStream(systemType, libraryName)) { - if (libraryStream == null) { - throw new UnsatisfiedLinkError("Required library was not found"); - } - - Path extractedLibraryPath = prepareExtractionDirectory().resolve(systemType.formatLibraryName(libraryName)); - - try (FileOutputStream fileStream = new FileOutputStream(extractedLibraryPath.toFile())) { - IOUtils.copy(libraryStream, fileStream); - } - - return extractedLibraryPath; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private Path prepareExtractionDirectory() throws IOException { - Path extractionDirectory = detectExtractionBaseDirectory().resolve(String.valueOf(System.currentTimeMillis())); - - if (!Files.isDirectory(extractionDirectory)) { - log.debug("Native library {}: extraction directory {} does not exist, creating.", libraryName, - extractionDirectory); - - try { - createDirectoriesWithFullPermissions(extractionDirectory); - } catch (FileAlreadyExistsException ignored) { - // All is well - } catch (IOException e) { - throw new IOException("Failed to create directory for unpacked native library.", e); - } - } else { - log.debug("Native library {}: extraction directory {} already exists, using.", libraryName, extractionDirectory); - } - - return extractionDirectory; - } - - private Path detectExtractionBaseDirectory() { - String explicitExtractionBase = properties.getExtractionPath(); - - if (explicitExtractionBase != null) { - log.debug("Native library {}: explicit extraction path provided - {}", libraryName, explicitExtractionBase); - return Paths.get(explicitExtractionBase).toAbsolutePath(); - } - - Path path = Paths.get(System.getProperty("java.io.tmpdir", "/tmp"), "lava-jni-natives") - .toAbsolutePath(); - - log.debug("Native library {}: detected {} as base directory for extraction.", libraryName, path); - return path; - } - - private SystemType detectMatchingSystemType() { - SystemType systemType; - - try { - systemType = SystemType.detect(properties); - } catch (IllegalArgumentException e) { - if (systemFilter != null) { - log.info("Native library {}: could not detect sytem type, but system filter is {} - assuming it does " + - "not match and skipping library.", libraryName, systemFilter); - - return null; - } else { - throw e; - } - } - - if (systemFilter != null && !systemFilter.test(systemType)) { - log.debug("Native library {}: system filter does not match detected system {], skipping", libraryName, - systemType.formatSystemName()); - return null; - } - - return systemType; - } - - private static void createDirectoriesWithFullPermissions(Path path) throws IOException { - boolean isPosix = FileSystems.getDefault().supportedFileAttributeViews().contains("posix"); - - if (!isPosix) { - Files.createDirectories(path); - } else { - Files.createDirectories(path, asFileAttribute(fromString("rwxrwxrwx"))); - } - } -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryProperties.java b/src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryProperties.java deleted file mode 100644 index 930202f..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/NativeLibraryProperties.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.sedmelluq.lava.common.natives; - -import com.sedmelluq.lava.common.natives.architecture.SystemType; - -public interface NativeLibraryProperties { - /** - * @return Explicit filesystem path for the library. If this is set, this is loaded directly and no resource - * extraction and/or system name detection is performed. If this returns null, library directory - * is checked next. - */ - String getLibraryPath(); - - /** - * @return Explicit directory containing the native library. The specified directory must contain the system name - * directories, thus the library to be loaded is actually located at - * directory/{systemName}/{libPrefix}{libName}{libSuffix}. If this returns null, - * then {@link NativeLibraryBinaryProvider#getLibraryStream(SystemType, String)} is called to obtain the - * stream to the library file, which is then written to disk for loading. - */ - String getLibraryDirectory(); - - /** - * @return Base directory where to write the library if it is obtained through - * {@link NativeLibraryBinaryProvider#getLibraryStream(SystemType, String)}. The library file itself will - * actually be written to a subdirectory with a randomly generated name. The specified directory does not - * have to exist, but in that case the current process must have privileges to create it. If this returns - * null, then {tmpDir}/lava-jni-natives is used. - */ - String getExtractionPath(); - - /** - * @return System name. If this is set, no operating system or architecture detection is performed. - */ - String getSystemName(); - - /** - * @return Library file name prefix to use. Only used when {@link #getSystemName()} is provided. - */ - String getLibraryFileNamePrefix(); - - /** - * @return Library file name suffix to use. Only used when {@link #getSystemName()} is provided. - */ - String getLibraryFileNameSuffix(); - - /** - * @return Architecture name to use. If this is set, operating system detection is still performed. - */ - String getArchitectureName(); -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/NativeResourceHolder.java b/src/main/java/com/sedmelluq/lava/common/natives/NativeResourceHolder.java deleted file mode 100644 index a213750..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/NativeResourceHolder.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.sedmelluq.lava.common.natives; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Abstract instance of a class which holds native resources that must be freed. - */ -public abstract class NativeResourceHolder { - private static final Logger log = LoggerFactory.getLogger(NativeResourceHolder.class); - - private final AtomicBoolean released = new AtomicBoolean(); - - /** - * Assert that the native resources have not been freed. - */ - protected void checkNotReleased() { - if (released.get()) { - throw new IllegalStateException("Cannot use the decoder after closing it."); - } - } - - /** - * Free up native resources of the decoder. Using other methods after this will throw IllegalStateException. - */ - public void close() { - closeInternal(false); - } - - /** - * Free the native resources. - */ - protected abstract void freeResources(); - - private synchronized void closeInternal(boolean inFinalizer) { - if (released.compareAndSet(false, true)) { - if (inFinalizer) { - log.warn("Should have been closed before finalization ({}).", this.getClass().getName()); - } - - freeResources(); - } - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - closeInternal(true); - } -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/ResourceNativeLibraryBinaryProvider.java b/src/main/java/com/sedmelluq/lava/common/natives/ResourceNativeLibraryBinaryProvider.java deleted file mode 100644 index d357123..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/ResourceNativeLibraryBinaryProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.sedmelluq.lava.common.natives; - -import com.sedmelluq.lava.common.natives.architecture.SystemType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.InputStream; - -public class ResourceNativeLibraryBinaryProvider implements NativeLibraryBinaryProvider { - private static final Logger log = LoggerFactory.getLogger(ResourceNativeLibraryBinaryProvider.class); - - private final Class classLoaderSample; - private final String nativesRoot; - - public ResourceNativeLibraryBinaryProvider(Class classLoaderSample, String nativesRoot) { - this.classLoaderSample = classLoaderSample != null ? classLoaderSample : ResourceNativeLibraryBinaryProvider.class; - this.nativesRoot = nativesRoot; - } - - @Override - public InputStream getLibraryStream(SystemType systemType, String libraryName) { - String resourcePath = nativesRoot + systemType.formatSystemName() + "/" + systemType.formatLibraryName(libraryName); - - log.debug("Native library {}: trying to find from resources at {} with {} as classloader reference", libraryName, - resourcePath, classLoaderSample.getName()); - - return classLoaderSample.getResourceAsStream(resourcePath); - } -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/SystemNativeLibraryProperties.java b/src/main/java/com/sedmelluq/lava/common/natives/SystemNativeLibraryProperties.java deleted file mode 100644 index 5c05990..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/SystemNativeLibraryProperties.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.sedmelluq.lava.common.natives; - -public class SystemNativeLibraryProperties implements NativeLibraryProperties { - private final String libraryName; - private final String propertyPrefix; - - public SystemNativeLibraryProperties(String libraryName, String propertyPrefix) { - this.libraryName = libraryName; - this.propertyPrefix = propertyPrefix; - } - - @Override - public String getLibraryPath() { - return get("path"); - } - - @Override - public String getLibraryDirectory() { - return get("dir"); - } - - @Override - public String getExtractionPath() { - return get("extractPath"); - } - - @Override - public String getSystemName() { - return get("system"); - } - - @Override - public String getArchitectureName() { - return get("arch"); - } - - @Override - public String getLibraryFileNamePrefix() { - return get("libPrefix"); - } - - @Override - public String getLibraryFileNameSuffix() { - return get("libSuffix"); - } - - private String get(String property) { - return System.getProperty( - propertyPrefix + libraryName + "." + property, - System.getProperty(propertyPrefix + property) - ); - } -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/architecture/ArchitectureType.java b/src/main/java/com/sedmelluq/lava/common/natives/architecture/ArchitectureType.java deleted file mode 100644 index 022d6fa..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/architecture/ArchitectureType.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sedmelluq.lava.common.natives.architecture; - -public interface ArchitectureType { - /** - * @return Identifier used in directory names (combined with OS identifier) for this ABI - */ - String identifier(); -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/architecture/DefaultArchitectureTypes.java b/src/main/java/com/sedmelluq/lava/common/natives/architecture/DefaultArchitectureTypes.java deleted file mode 100644 index 75af876..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/architecture/DefaultArchitectureTypes.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.sedmelluq.lava.common.natives.architecture; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public enum DefaultArchitectureTypes implements ArchitectureType { - ARM("arm", Arrays.asList("arm", "armeabi", "armv7b", "armv7l")), - ARM_HF("armhf", Arrays.asList("armeabihf", "armeabi-v7a")), - ARMv8_32("aarch32", Arrays.asList("armv8b", "armv8l")), - ARMv8_64("aarch64", Arrays.asList("arm64", "aarch64", "aarch64_be", "arm64-v8a")), - - MIPS_32("mips", Arrays.asList("mips")), - MIPS_32_LE("mipsel", Arrays.asList("mipsel", "mipsle")), - MIPS_64("mips64", Arrays.asList("mips64")), - MIPS_64_LE("mips64el", Arrays.asList("mips64el", "mips64le")), - - PPC_32("powerpc", Arrays.asList("ppc", "powerpc")), - PPC_32_LE("powerpcle", Arrays.asList("ppcel", "ppcle")), - PPC_64("ppc64", Arrays.asList("ppc64")), - PPC_64_LE("ppc64le", Arrays.asList("ppc64el", "ppc64le")), - - X86_32("x86", Arrays.asList("x86", "i386", "i486", "i586", "i686")), - X86_64("x86-64", Arrays.asList("x86_64", "amd64")); - - public final String identifier; - public final List aliases; - - DefaultArchitectureTypes(String identifier, List aliases) { - this.identifier = identifier; - this.aliases = aliases; - } - - @Override - public String identifier() { - return identifier; - } - - public static ArchitectureType detect() { - String architectureName = System.getProperty("os.arch"); - ArchitectureType type = aliasMap.get(architectureName); - - if (type == null) { - throw new IllegalArgumentException("Unknown architecture: " + architectureName); - } - - return type; - } - - private static Map aliasMap = createAliasMap(); - - private static Map createAliasMap() { - Map aliases = new HashMap<>(); - - for (DefaultArchitectureTypes value : values()) { - for (String alias : value.aliases) { - aliases.put(alias, value); - } - } - - return aliases; - } -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/architecture/DefaultOperatingSystemTypes.java b/src/main/java/com/sedmelluq/lava/common/natives/architecture/DefaultOperatingSystemTypes.java deleted file mode 100644 index 2a23997..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/architecture/DefaultOperatingSystemTypes.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.sedmelluq.lava.common.natives.architecture; - -public enum DefaultOperatingSystemTypes implements OperatingSystemType { - LINUX("linux", "lib", ".so"), - WINDOWS("win", "", ".dll"), - DARWIN("darwin", "lib", ".dylib"), - SOLARIS("solaris", "lib", ".so"); - - private final String identifier; - private final String libraryFilePrefix; - private final String libraryFileSuffix; - - DefaultOperatingSystemTypes(String identifier, String libraryFilePrefix, String libraryFileSuffix) { - this.identifier = identifier; - this.libraryFilePrefix = libraryFilePrefix; - this.libraryFileSuffix = libraryFileSuffix; - } - - @Override - public String identifier() { - return identifier; - } - - @Override - public String libraryFilePrefix() { - return libraryFilePrefix; - } - - @Override - public String libraryFileSuffix() { - return libraryFileSuffix; - } - - public static OperatingSystemType detect() { - String osFullName = System.getProperty("os.name"); - - if (osFullName.startsWith("Windows")) { - return WINDOWS; - } else if (osFullName.startsWith("Mac OS X")) { - return DARWIN; - } else if (osFullName.startsWith("Solaris")) { - return SOLARIS; - } else if (osFullName.toLowerCase().startsWith("linux")) { - return LINUX; - } else { - throw new IllegalArgumentException("Unknown operating system: " + osFullName); - } - } -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/architecture/OperatingSystemType.java b/src/main/java/com/sedmelluq/lava/common/natives/architecture/OperatingSystemType.java deleted file mode 100644 index dfbb296..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/architecture/OperatingSystemType.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.sedmelluq.lava.common.natives.architecture; - -public interface OperatingSystemType { - /** - * @return Identifier used in directory names (combined with architecture) for this OS - */ - String identifier(); - - /** - * @return Prefix used for library file names. lib on most Unix flavors. - */ - String libraryFilePrefix(); - - /** - * @return Suffix (extension) used for library file names. - */ - String libraryFileSuffix(); -} diff --git a/src/main/java/com/sedmelluq/lava/common/natives/architecture/SystemType.java b/src/main/java/com/sedmelluq/lava/common/natives/architecture/SystemType.java deleted file mode 100644 index d4da83a..0000000 --- a/src/main/java/com/sedmelluq/lava/common/natives/architecture/SystemType.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.sedmelluq.lava.common.natives.architecture; - -import com.sedmelluq.lava.common.natives.NativeLibraryProperties; - -import java.util.Optional; - -public class SystemType { - public final ArchitectureType architectureType; - public final OperatingSystemType osType; - - public SystemType(ArchitectureType architectureType, OperatingSystemType osType) { - this.architectureType = architectureType; - this.osType = osType; - } - - public String formatSystemName() { - if (osType.identifier() != null) { - if (osType == DefaultOperatingSystemTypes.DARWIN) { - return osType.identifier(); - } else { - return osType.identifier() + "-" + architectureType.identifier(); - } - } else { - return architectureType.identifier(); - } - } - - public String formatLibraryName(String libraryName) { - return osType.libraryFilePrefix() + libraryName + osType.libraryFileSuffix(); - } - - public static SystemType detect(NativeLibraryProperties properties) { - String systemName = properties.getSystemName(); - - if (systemName != null) { - return new SystemType( - () -> systemName, - new UnknownOperatingSystem( - Optional.ofNullable(properties.getLibraryFileNamePrefix()).orElse("lib"), - Optional.ofNullable(properties.getLibraryFileNameSuffix()).orElse(".so") - ) - ); - } - - OperatingSystemType osType = DefaultOperatingSystemTypes.detect(); - - String explicitArchitecture = properties.getArchitectureName(); - ArchitectureType architectureType = explicitArchitecture != null ? () -> explicitArchitecture : - DefaultArchitectureTypes.detect(); - - return new SystemType(architectureType, osType); - } - - private static class UnknownOperatingSystem implements OperatingSystemType { - private final String libraryFilePrefix; - private final String libraryFileSuffix; - - private UnknownOperatingSystem(String libraryFilePrefix, String libraryFileSuffix) { - this.libraryFilePrefix = libraryFilePrefix; - this.libraryFileSuffix = libraryFileSuffix; - } - - @Override - public String identifier() { - return null; - } - - @Override - public String libraryFilePrefix() { - return libraryFilePrefix; - } - - @Override - public String libraryFileSuffix() { - return libraryFileSuffix; - } - } -} diff --git a/src/main/java/com/sedmelluq/lava/common/tools/DaemonThreadFactory.java b/src/main/java/com/sedmelluq/lava/common/tools/DaemonThreadFactory.java deleted file mode 100644 index 289c573..0000000 --- a/src/main/java/com/sedmelluq/lava/common/tools/DaemonThreadFactory.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.sedmelluq.lava.common.tools; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Thread factory for daemon threads. - */ -public class DaemonThreadFactory implements ThreadFactory { - private static final Logger log = LoggerFactory.getLogger(DaemonThreadFactory.class); - - private static final AtomicInteger poolNumber = new AtomicInteger(1); - private final ThreadGroup group; - private final AtomicInteger threadNumber = new AtomicInteger(1); - private final String namePrefix; - private final Runnable exitCallback; - - /** - * @param name Name that will be included in thread names. - */ - public DaemonThreadFactory(String name) { - this(name, null); - } - - /** - * @param name Name that will be included in thread names. - * @param exitCallback Runnable to be executed when the thread exits. - */ - public DaemonThreadFactory(String name, Runnable exitCallback) { - SecurityManager securityManager = System.getSecurityManager(); - - group = (securityManager != null) ? securityManager.getThreadGroup() : Thread.currentThread().getThreadGroup(); - namePrefix = "lava-daemon-pool-" + name + "-" + poolNumber.getAndIncrement() + "-thread-"; - this.exitCallback = exitCallback; - } - - @Override - public Thread newThread(Runnable runnable) { - Thread thread = new Thread(group, getThreadRunnable(runnable), namePrefix + threadNumber.getAndIncrement(), 0); - thread.setDaemon(true); - thread.setPriority(Thread.NORM_PRIORITY); - return thread; - } - - private Runnable getThreadRunnable(Runnable target) { - if (exitCallback == null) { - return target; - } else { - return new ExitCallbackRunnable(target); - } - } - - private class ExitCallbackRunnable implements Runnable { - private final Runnable original; - - private ExitCallbackRunnable(Runnable original) { - this.original = original; - } - - @Override - public void run() { - try { - if (original != null) { - original.run(); - } - } finally { - wrapExitCallback(); - } - } - - private void wrapExitCallback() { - boolean wasInterrupted = Thread.interrupted(); - - try { - exitCallback.run(); - } catch (Throwable throwable) { - log.error("Thread exit notification threw an exception.", throwable); - } finally { - if (wasInterrupted) { - Thread.currentThread().interrupt(); - } - } - } - } -} diff --git a/src/main/java/com/sedmelluq/lava/common/tools/ExecutorTools.java b/src/main/java/com/sedmelluq/lava/common/tools/ExecutorTools.java deleted file mode 100644 index 0967044..0000000 --- a/src/main/java/com/sedmelluq/lava/common/tools/ExecutorTools.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.sedmelluq.lava.common.tools; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.*; - -/** - * Utility methods for working with executors. - */ -public class ExecutorTools { - private static final Logger log = LoggerFactory.getLogger(ExecutorTools.class); - - private static final long WAIT_TIME = 1000L; - - /** - * A completed Future instance. - */ - public static final CompletedVoidFuture COMPLETED_VOID = new CompletedVoidFuture(); - - /** - * Shut down an executor and log the shutdown result. The executor is given a fixed amount of time to shut down, if it - * does not manage to do it in that time, then this method just returns. - * - * @param executorService Executor service to shut down - * @param description Description of the service to use for logging - */ - public static void shutdownExecutor(ExecutorService executorService, String description) { - if (executorService == null) { - return; - } - - log.debug("Shutting down executor {}", description); - - executorService.shutdownNow(); - - try { - if (!executorService.awaitTermination(WAIT_TIME, TimeUnit.MILLISECONDS)) { - log.debug("Executor {} did not shut down in {}", description, WAIT_TIME); - } else { - log.debug("Executor {} successfully shut down", description); - } - } catch (InterruptedException e) { - log.debug("Received an interruption while shutting down executor {}", description); - Thread.currentThread().interrupt(); - } - } - - /** - * Creates an executor which will use the queue only when maximum number of threads has been reached. The core pool - * size here only means the number of threads that are always alive, it is no longer used to check whether a new - * thread should start or not. The maximum size is otherwise pointless unless you have a bounded queue, which in turn - * would cause tasks to be rejected if it is too small. - * - * @param coreSize Number of threads that are always alive - * @param maximumSize The maximum number of threads in the pool - * @param timeout Non-core thread timeout in milliseconds - * @param threadFactory Thread factory to create pool threads with - * @return An eagerly scaling thread pool executor - */ - public static ThreadPoolExecutor createEagerlyScalingExecutor(int coreSize, int maximumSize, long timeout, - int queueCapacity, ThreadFactory threadFactory) { - - ThreadPoolExecutor executor = new ThreadPoolExecutor(coreSize, maximumSize, timeout, TimeUnit.MILLISECONDS, - new EagerlyScalingTaskQueue(queueCapacity), threadFactory); - - executor.setRejectedExecutionHandler(new EagerlyScalingRejectionHandler()); - return executor; - } - - private static class EagerlyScalingTaskQueue extends LinkedBlockingQueue { - public EagerlyScalingTaskQueue(int capacity) { - super(capacity); - } - - @Override - public boolean offer(Runnable runnable) { - return isEmpty() && super.offer(runnable); - } - - public boolean offerDirectly(Runnable runnable) { - return super.offer(runnable); - } - } - - private static class EagerlyScalingRejectionHandler implements RejectedExecutionHandler { - @Override - public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) { - if (!((EagerlyScalingTaskQueue) executor.getQueue()).offerDirectly(runnable)) { - throw new RejectedExecutionException("Task " + runnable.toString() + " rejected from " + runnable.toString()); - } - } - } - - private static class CompletedVoidFuture implements Future { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return false; - } - - @Override - public boolean isCancelled() { - return false; - } - - @Override - public boolean isDone() { - return true; - } - - @Override - public Void get() throws InterruptedException, ExecutionException { - return null; - } - - @Override - public Void get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return null; - } - } -} diff --git a/src/main/java/command/pattern/ControlCommand.java b/src/main/java/command/pattern/ControlCommand.java deleted file mode 100644 index 559b5ad..0000000 --- a/src/main/java/command/pattern/ControlCommand.java +++ /dev/null @@ -1,74 +0,0 @@ -package command.pattern; - -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.entities.ChannelType; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import org.jetbrains.annotations.NotNull; - -/** - * Classe per gestire i controlli tra i simbolo di comanndo e il comando stesso - */ -public class ControlCommand { - /** - * Metodo per eseguire il controllo se il comando inserito è quello di controllo - * - * @param event evento del messaggio - * @param commandName nome del comando - * @return boolean il comando corrisponde a quello ricevuto con quello controllato - */ - - @Deprecated - public static boolean controlCommand(MessageReceivedEvent event, String commandName) { - -// System.out.println("Comando inviato da server: " + event.getGuild().getName()); -// System.out.println("Inviato da: " + event.getAuthor().getName() + "#" + event.getAuthor().getDiscriminator()); - -// LOGGER.log(Level.ALL,"Comando inviato da server: " + event.getGuild().getName()); -// LOGGER.debug("Inviato da: " + event.getAuthor().getName() + "#" + event.getAuthor().getDiscriminator()); - - if (!event.isFromType(ChannelType.PRIVATE)) { - if (event.getMessage().getContentRaw().startsWith(PostgreSQLInterface.getSimbol(event.getGuild().getId()) + commandName) - || (event.getMessage().isMentioned(event.getJDA().getSelfUser()) && event.getMessage().getContentRaw().contains(commandName))) { - return true; - } else { - return false; - } - } else { - return false; - } - } - - /** - * Metodo per ottere il simbolo di comando del server - * - * @param serverId ID del server - * @return String simbolo di comando - */ - public static String getSimbolCommand(String serverId) { - return PostgreSQLInterface.getSimbol(serverId); - } - - /** - * Controllo del comando lanciato dalla chat se sia corretto con quelli attivi sul bot. - * Combaciando il simbolo di comando con il nome del comando oppure con la menzione del bot, seguito dal nome del comando. - * - * @param event Evento del messaggio - * @param simbolCommand Simbolo di comando - * @param commandName Nome del comando - * @return boolean Validità del comando - */ - public static boolean checkCommand(@NotNull MessageReceivedEvent event, @NotNull String simbolCommand, @NotNull String commandName) { - String completeCommand = simbolCommand + commandName.toLowerCase(); - - if (!event.isFromType(ChannelType.PRIVATE)) { - if (event.getMessage().getContentRaw().equals(completeCommand) || - (event.getMessage().isMentioned(event.getJDA().getSelfUser()) && event.getMessage().getContentRaw().contains(commandName))) { - return true; - } else { - return false; - } - } else { - return false; - } - } -} diff --git a/src/main/java/command/real/BDO/BDOReceiver.java b/src/main/java/command/real/BDO/BDOReceiver.java deleted file mode 100644 index 6ba9314..0000000 --- a/src/main/java/command/real/BDO/BDOReceiver.java +++ /dev/null @@ -1,157 +0,0 @@ -package command.real.BDO; - -import beans.ServerToChannel; -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.util.ArrayList; - -public class BDOReceiver extends ListenerAdapter { - - //BDO BOSS START - public static String getBDOBossStartCommand() { - return "BDOBossStart"; - } - - public static String getBDOBossStartCommandDescription() { - return "Questo comando permette di iscriversi agli allarmi dei boss di BDO. \n" + - "Il comando deve essere lanciato sul canale su cui si desidera ricevere i boss"; - } - - //BDO BOSS STOP - - public static String getBDOBossStopCommand() { - return "BDOBossStop"; - } - - public static String getBDOBossStopCommandDescription() { - return "Questo comando permette disiscriversi agli allarmi dei boss di BDO. \n" + - "Il comando può essere lanciato su qualunque canale"; - } - - //BDO NEWS START - - public static String getBDONewsStartCommand() { - return "BDONewsStart"; - } - - public static String getBDONewsStartCommandDecription() { - return "Questo comando permette di iscriversi al feed delle news di BDO. \n" + - "Il comando deve essere lanciato sul canale su cui si desidera ricevere le news"; - } - - //BDO NEWS STOP - - public static String getBDONewsStopCommand() { - return "BDONewsStop"; - } - - public static String getBDONewsStopCommandDecription() { - return "Questo comando permette disiscriversi al feed delle news di BDO. \n" + - "Il comando può essere lanciato su qualunque canale"; - } - - //BDO PATCH START - - public static String getBDOPatchStartCommand() { - return "BDOPatchStart"; - } - - public static String getBDOPatchStartCommandDecription() { - return "Questo comando permette di iscriversi al feed delle patch di BDO. \n" + - "Il comando deve essere lanciato sul canale su cui si desidera ricevere le patch"; - } - - //BDO PATCH STOP - - public static String getBDOPatchStopCommand() { - return "BDOPatchStop"; - } - - public static String getBDOPatchStopCommandDecription() { - return "Comando per disiscriversi al feed delle patch di BDO. \n" + - "Il comando può essere lanciato su qualunque canale"; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - - if (event.getAuthor().isBot()) return; - - String simbolCommand = ControlCommand.getSimbolCommand(event.getGuild().getId()); - - if (ControlCommand.checkCommand(event, simbolCommand, getBDOBossStartCommand())) { - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - PostgreSQLInterface.setBDOBossChannel(event.getGuild().getId(), event.getChannel().getId()); - new MessageBuilder().append("Invio degli allarmi dei boss di BDO configurato sul canale: ") - .appendCodeBlock(event.getChannel().getName(), "").sendTo(event.getChannel()).queue(); - } - } else if (ControlCommand.checkCommand(event, simbolCommand, getBDOBossStopCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - ArrayList listChannel = PostgreSQLInterface.getBDOBossChannel(); - ServerToChannel removedChannelId = listChannel.get(listChannel.indexOf(new ServerToChannel(event.getGuild().getId(), null))); - - PostgreSQLInterface.removeBDOBossChannel(event.getGuild().getId()); - - new MessageBuilder().append("Invio degli allarmi dei boss di BDO rimosso dal canale: ") - .appendCodeBlock(event.getJDA().getTextChannelById(removedChannelId.getChannelID()).getName(), "") - .sendTo(event.getChannel()).queue(); - } - } else if (ControlCommand.checkCommand(event, simbolCommand, getBDONewsStartCommand())) { - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - PostgreSQLInterface.setBDONewsChannel(event.getGuild().getId(), event.getChannel().getId()); - new MessageBuilder().append("Invio delle news di BDO configurato sul canale: ") - .appendCodeBlock(event.getChannel().getName(), "").sendTo(event.getChannel()).queue(); - - } - } else if (ControlCommand.checkCommand(event, simbolCommand, getBDONewsStopCommand())) { - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - - ArrayList listChannel = PostgreSQLInterface.getBDONewsChannel(); - ServerToChannel removedChannelId = listChannel.get(listChannel.indexOf(new ServerToChannel(event.getGuild().getId(), null))); - - PostgreSQLInterface.removeBDONewsChannel(event.getGuild().getId()); - - new MessageBuilder().append("Invio delle news di BDO rimosso dal canale: ") - .appendCodeBlock(event.getJDA().getTextChannelById(removedChannelId.getChannelID()).getName(), "") - .sendTo(event.getChannel()).queue(); - } - } else if (ControlCommand.checkCommand(event, simbolCommand, getBDOPatchStartCommand())) { - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - - PostgreSQLInterface.setBDOPatchChannel(event.getGuild().getId(), event.getChannel().getId()); - new MessageBuilder().append("Invio delle patch di BDO configurato sul canale: ") - .appendCodeBlock(event.getChannel().getName(), "").sendTo(event.getChannel()).queue(); - } - } else if (ControlCommand.checkCommand(event, simbolCommand, getBDOPatchStopCommand())) { - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - - ArrayList listChannel = PostgreSQLInterface.getBDOPatchChannel(); - ServerToChannel removedChannelId = listChannel.get(listChannel.indexOf(new ServerToChannel(event.getGuild().getId(), null))); - - PostgreSQLInterface.removeBDOPatchChannel(event.getGuild().getId()); - - new MessageBuilder().append("Invio delle patch di BDO rimosso dal canale: ") - .appendCodeBlock(event.getJDA().getTextChannelById(removedChannelId.getChannelID()).getName(), "") - .sendTo(event.getChannel()).queue(); - } - } - } -} diff --git a/src/main/java/command/real/BDO/RSS/BDONewsStartCommand.java b/src/main/java/command/real/BDO/RSS/BDONewsStartCommand.java deleted file mode 100644 index 637c382..0000000 --- a/src/main/java/command/real/BDO/RSS/BDONewsStartCommand.java +++ /dev/null @@ -1,43 +0,0 @@ -package command.real.BDO.RSS; - -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -@Deprecated -public class BDONewsStartCommand extends ListenerAdapter { - - public static String getCommand() { - return "BDONewsStart"; - } - - public static String getCommandDescription() { - return "Questo comando permette di iscriversi al feed delle news di BDO. \n" + - "Il comando deve essere lanciato sul canale su cui si desidera ricevere le news"; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - event.getAuthor().getId(); - - - if (ControlCommand.controlCommand(event, getCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - PostgreSQLInterface.setBDONewsChannel(event.getGuild().getId(), event.getChannel().getId()); - new MessageBuilder().append("Invio delle news di BDO configurato sul canale: ") - .appendCodeBlock(event.getChannel().getName(), "").sendTo(event.getChannel()).queue(); - - } - } - } - - -} diff --git a/src/main/java/command/real/BDO/RSS/BDONewsStopCommand.java b/src/main/java/command/real/BDO/RSS/BDONewsStopCommand.java deleted file mode 100644 index 8acb8be..0000000 --- a/src/main/java/command/real/BDO/RSS/BDONewsStopCommand.java +++ /dev/null @@ -1,47 +0,0 @@ -package command.real.BDO.RSS; - -import beans.ServerToChannel; -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.util.ArrayList; - -@Deprecated -public class BDONewsStopCommand extends ListenerAdapter { - - public static String getCommand() { - return "BDONewsStop"; - } - - public static String getCommandDescription() { - return "Questo comando permette disiscriversi al feed delle news di BDO. \n" + - "Il comando può essere lanciato su qualunque canale"; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - if (ControlCommand.controlCommand(event, getCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - - ArrayList listChannel = PostgreSQLInterface.getBDONewsChannel(); - ServerToChannel removedChannelId = listChannel.get(listChannel.indexOf(new ServerToChannel(event.getGuild().getId(), null))); - - PostgreSQLInterface.removeBDONewsChannel(event.getGuild().getId()); - - new MessageBuilder().append("Invio delle news di BDO rimosso dal canale: ") - .appendCodeBlock(event.getJDA().getTextChannelById(removedChannelId.getChannelID()).getName(), "") - .sendTo(event.getChannel()).queue(); - } - } - } - - -} diff --git a/src/main/java/command/real/BDO/RSS/BDOPatchStartCommand.java b/src/main/java/command/real/BDO/RSS/BDOPatchStartCommand.java deleted file mode 100644 index b314100..0000000 --- a/src/main/java/command/real/BDO/RSS/BDOPatchStartCommand.java +++ /dev/null @@ -1,40 +0,0 @@ -package command.real.BDO.RSS; - -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -@Deprecated -public class BDOPatchStartCommand extends ListenerAdapter { - - public static String getCommand() { - return "BDOPatchStart"; - } - - public static String getCommandDescription() { - return "Questo comando permette di iscriversi al feed delle patch di BDO. \n" + - "Il comando deve essere lanciato sul canale su cui si desidera ricevere le patch"; - } - - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - if (ControlCommand.controlCommand(event, getCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - - PostgreSQLInterface.setBDOPatchChannel(event.getGuild().getId(), event.getChannel().getId()); - new MessageBuilder().append("Invio delle patch di BDO configurato sul canale: ") - .appendCodeBlock(event.getChannel().getName(), "").sendTo(event.getChannel()).queue(); - } - - } - } -} diff --git a/src/main/java/command/real/BDO/RSS/BDOPatchStopCommand.java b/src/main/java/command/real/BDO/RSS/BDOPatchStopCommand.java deleted file mode 100644 index b3913d1..0000000 --- a/src/main/java/command/real/BDO/RSS/BDOPatchStopCommand.java +++ /dev/null @@ -1,47 +0,0 @@ -package command.real.BDO.RSS; - -import beans.ServerToChannel; -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.util.ArrayList; - -@Deprecated -public class BDOPatchStopCommand extends ListenerAdapter { - - public static String getCommand() { - return "BDOPatchStop"; - } - - public static String getCommandDescription() { - return "Comando per disiscriversi al feed delle patch di BDO. \n" + - "Il comando può essere lanciato su qualunque canale"; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - if (ControlCommand.controlCommand(event, getCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - - ArrayList listChannel = PostgreSQLInterface.getBDOPatchChannel(); - ServerToChannel removedChannelId = listChannel.get(listChannel.indexOf(new ServerToChannel(event.getGuild().getId(), null))); - - PostgreSQLInterface.removeBDOPatchChannel(event.getGuild().getId()); - - new MessageBuilder().append("Invio delle patch di BDO rimosso dal canale: ") - .appendCodeBlock(event.getJDA().getTextChannelById(removedChannelId.getChannelID()).getName(), "") - .sendTo(event.getChannel()).queue(); - } - } - } - - -} diff --git a/src/main/java/command/real/BDO/RSS/BDORSSReader.java b/src/main/java/command/real/BDO/RSS/BDORSSReader.java deleted file mode 100644 index 9da0082..0000000 --- a/src/main/java/command/real/BDO/RSS/BDORSSReader.java +++ /dev/null @@ -1,72 +0,0 @@ -package command.real.BDO.RSS; - -import beans.RSSMessage; -import com.rometools.rome.feed.synd.SyndEntry; -import com.rometools.rome.feed.synd.SyndFeed; -import com.rometools.rome.io.FeedException; -import com.rometools.rome.io.SyndFeedInput; -import com.rometools.rome.io.XmlReader; -import net.dv8tion.jda.core.EmbedBuilder; -import net.dv8tion.jda.core.entities.MessageEmbed; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; - -import java.awt.*; -import java.io.IOException; -import java.net.URL; - -public class BDORSSReader { - - /** - * Metodo per leggere un feed RSS - * @param URL Url da cui bisogna leggere il feed - * @return Ultimo feed registrato - */ - public static RSSMessage readRSS(String URL){ - SyndFeedInput input = new SyndFeedInput(); - - String title = null; - String link = null; - Document doc = null; - - try { - URL url = new URL(URL); - SyndFeed feed = input.build(new XmlReader(url)); - SyndEntry entry = feed.getEntries().get(0); - - title = entry.getTitle(); - link = entry.getLink(); - doc = Jsoup.parse(entry.getContents().get(0).getValue()); - - } catch (FeedException | IOException e) { - e.printStackTrace(); - } - - return new RSSMessage(title,link,doc); - } - - /** - * Metodo per preparare il messaggio per discord in modalità da embedded - * @param message Ultimo feed prelevato dal metodo di lettura - * @return Messaggio pronto per l'invio a discord - * - * @see BDORSSReader#readRSS(String) readRSS - * @see net.dv8tion.jda.core.entities.MessageEmbed MessageEmbedded - */ - - public static MessageEmbed prepareRSStoEmbeddedMessage(RSSMessage message){ - EmbedBuilder builder = new EmbedBuilder(); - - String body = Jsoup.parse(message.getDoc().toString().replaceAll("(?i)]*>", "br2n")).text().replaceAll("br2n", "\n"); - if (!message.getDoc().select("img").isEmpty()) { - //esite 1 immagine - String imageUrl = message.getDoc().select("img").get(0).attr("src"); - return builder.setTitle(message.getTitle(), message.getLink()) - .setDescription(body).setColor(new Color(131, 196, 250)).setImage(imageUrl).build(); - } else { - return builder.setTitle(message.getTitle(), message.getLink()).setDescription(body).setColor(new Color(131, 196, 250)).build(); - } - - } - -} diff --git a/src/main/java/command/real/BDO/RSS/BDORSScheduler.java b/src/main/java/command/real/BDO/RSS/BDORSScheduler.java deleted file mode 100644 index 6775729..0000000 --- a/src/main/java/command/real/BDO/RSS/BDORSScheduler.java +++ /dev/null @@ -1,68 +0,0 @@ -package command.real.BDO.RSS; - -import beans.RSSMessage; -import beans.ServerToChannel; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.JDA; -import net.dv8tion.jda.core.entities.MessageEmbed; - -import java.util.ArrayList; -import java.util.TimerTask; - -public class BDORSScheduler { - - - public static TimerTask taskFeedRSSBDO(JDA jda) { - return new TimerTask() { - @Override - public void run() { - - - RSSMessage rssNewsMessage = BDORSSReader.readRSS("https://community.blackdesertonline.com/index.php?forums/news-announcements.181/index.rss"); - RSSMessage rssPatchMessage = BDORSSReader.readRSS("https://community.blackdesertonline.com/index.php?forums/patch-notes.5/index.rss"); - - ArrayList newsBDOList = PostgreSQLInterface.getListNewsBDO(); - //publishRSSNews - if (newsBDOList != null) { - if (newsBDOList.indexOf(rssNewsMessage.getLink()) == -1) { - procedurePublish(rssNewsMessage, newsBDOList, jda); - } - } else { - newsBDOList = new ArrayList<>(); - procedurePublish(rssNewsMessage, newsBDOList, jda); - } - - //publishRSSPatch - if (PostgreSQLInterface.getLastPatchBDO() != null) { - if (!PostgreSQLInterface.getLastPatchBDO().equals(rssPatchMessage.getLink())) { - MessageEmbed patchMessage = BDORSSReader.prepareRSStoEmbeddedMessage(rssPatchMessage); - ArrayList patchhNews = PostgreSQLInterface.getBDOPatchChannel(); - publishMessage(patchMessage, patchhNews, jda); - PostgreSQLInterface.setLastPatchBDO(rssPatchMessage.getLink()); - } - } else { - MessageEmbed patchMessage = BDORSSReader.prepareRSStoEmbeddedMessage(rssPatchMessage); - ArrayList patchhNews = PostgreSQLInterface.getBDOPatchChannel(); - publishMessage(patchMessage, patchhNews, jda); - PostgreSQLInterface.setLastPatchBDO(rssPatchMessage.getLink()); - } - } - }; - } - - private static void procedurePublish(RSSMessage rssNewsMessage, ArrayList newsBDOList, JDA jda) { - MessageEmbed newsMessage = BDORSSReader.prepareRSStoEmbeddedMessage(rssNewsMessage); //ottieni il messaggio embedded - ArrayList listNews = PostgreSQLInterface.getBDONewsChannel(); //ottieni la delle ultime news già pubblicate - publishMessage(newsMessage, listNews, jda); //publish del messaggio - newsBDOList.add(rssNewsMessage.getLink()); //aggiunta dell'ultima news alla lista - PostgreSQLInterface.setNewsBDO(newsBDOList); //salvataggio su db - } - - private static void publishMessage(MessageEmbed newsMessage, ArrayList servers, JDA jda) { - for (ServerToChannel obj : servers) { - String channelID = obj.getChannelID(); - String serverID = obj.getServerID(); - jda.getGuildById(serverID).getTextChannelById(channelID).sendMessage(newsMessage).queue(); - } - } -} diff --git a/src/main/java/command/real/BDO/boss/BDOBossStartCommand.java b/src/main/java/command/real/BDO/boss/BDOBossStartCommand.java deleted file mode 100644 index af89f14..0000000 --- a/src/main/java/command/real/BDO/boss/BDOBossStartCommand.java +++ /dev/null @@ -1,37 +0,0 @@ -package command.real.BDO.boss; - -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -@Deprecated -public class BDOBossStartCommand extends ListenerAdapter { - - public static String getCommand() { - return "BDOBossStart"; - } - - public static String getCommandDescription() { - return "Questo comando permette di iscriversi agli allarmi dei boss di BDO. \n" + - "Il comando deve essere lanciato sul canale su cui si desidera ricevere i boss"; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - if (ControlCommand.controlCommand(event, getCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - PostgreSQLInterface.setBDOBossChannel(event.getGuild().getId(), event.getChannel().getId()); - new MessageBuilder().append("Invio degli allarmi dei boss di BDO configurato sul canale: ") - .appendCodeBlock(event.getChannel().getName(), "").sendTo(event.getChannel()).queue(); - } - } - } -} diff --git a/src/main/java/command/real/BDO/boss/BDOBossStopCommand.java b/src/main/java/command/real/BDO/boss/BDOBossStopCommand.java deleted file mode 100644 index 4ae5e16..0000000 --- a/src/main/java/command/real/BDO/boss/BDOBossStopCommand.java +++ /dev/null @@ -1,45 +0,0 @@ -package command.real.BDO.boss; - -import beans.ServerToChannel; -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.util.ArrayList; - -@Deprecated -public class BDOBossStopCommand extends ListenerAdapter { - - public static String getCommand() { - return "BDOBossStop"; - } - - public static String getCommandDescription() { - return "Questo comando permette disiscriversi agli allarmi dei boss di BDO. \n" + - "Il comando può essere lanciato su qualunque canale"; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - if (ControlCommand.controlCommand(event, getCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - ArrayList listChannel = PostgreSQLInterface.getBDOBossChannel(); - ServerToChannel removedChannelId = listChannel.get(listChannel.indexOf(new ServerToChannel(event.getGuild().getId(), null))); - - PostgreSQLInterface.removeBDOBossChannel(event.getGuild().getId()); - - new MessageBuilder().append("Invio degli allarmi dei boss di BDO rimosso dal canale: ") - .appendCodeBlock(event.getJDA().getTextChannelById(removedChannelId.getChannelID()).getName(), "") - .sendTo(event.getChannel()).queue(); - } - } - } -} diff --git a/src/main/java/command/real/BDO/boss/BossJob.java b/src/main/java/command/real/BDO/boss/BossJob.java deleted file mode 100644 index 7b9f73c..0000000 --- a/src/main/java/command/real/BDO/boss/BossJob.java +++ /dev/null @@ -1,29 +0,0 @@ -package command.real.BDO.boss; - -import beans.BDOBossBean.Giorno; -import interfaces.TakaoLog; -import org.quartz.Job; -import org.quartz.JobExecutionContext; - -import java.time.LocalDateTime; -import java.time.format.TextStyle; -import java.util.ArrayList; -import java.util.Locale; - -/** - * Job per l'ottenimento dei boss - */ -public class BossJob implements Job { - - - @Override - public void execute(JobExecutionContext context) { - LocalDateTime time = LocalDateTime.now(); - TakaoLog.logInfo(time.getHour() + ":" + time.getMinute()); - ArrayList list = BossRetriver.getBossList(); - Giorno booDay = Giorno.getDayBosses(time.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH), list); - BossRetriver.processHour(time.getHour(), time.getMinute(), booDay); - - } - -} \ No newline at end of file diff --git a/src/main/java/command/real/BDO/boss/BossRetriver.java b/src/main/java/command/real/BDO/boss/BossRetriver.java deleted file mode 100644 index 53ac1b1..0000000 --- a/src/main/java/command/real/BDO/boss/BossRetriver.java +++ /dev/null @@ -1,214 +0,0 @@ -package command.real.BDO.boss; - -import beans.BDOBossBean.Boss; -import beans.BDOBossBean.Giorno; -import beans.ServerToChannel; -import com.google.gson.reflect.TypeToken; -import interfaces.PostgreSQLInterface; -import interfaces.TakaoLog; -import net.dv8tion.jda.core.MessageBuilder; -import starter.Start; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.time.DayOfWeek; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; - -import static starter.Start.jda; - -/** - * Classe per leggere il json dei boss - */ -public class BossRetriver { - /** - * Ottieni la lista dei boss da file - * - * @return ArrayList lista Boss - */ - public static ArrayList getBossList() { - - String fileName = "jsonboss.json"; - ClassLoader classLoader = BossRetriver.class.getClassLoader(); - - File file = new File("resources/" + fileName); - - if (!file.exists()) { - //risorsa su IDE - file = new File(classLoader.getResource(fileName).getFile()); - } - - ArrayList boss = null; - try { - BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath())); - - boss = Start.gson.fromJson(reader, new TypeToken>() { - }.getType()); - - reader.close(); - - } catch (IOException e) { - e.printStackTrace(); - } - - return boss; - } - - /** - * Processa l'ora per ottenere il boss - * - * @param ora ora attuale - * @param minuto minuti attuali - * @param giorno giorno attuale - */ - public static void processHour(int ora, int minuto, Giorno giorno) { - TakaoLog.logInfo("Giorno" + giorno.getGiorno() + " " + ora + ":" + minuto); - - if (ora == 0) { - //00:00-00:15 - processMinute0015(ora, minuto, giorno); - } else if (ora == 1) { - //1:45-1:55 - processMinute4500(ora, minuto, giorno); - } else if (ora == 2) { - //h2:00 - processMinute4500(ora, minuto, giorno); - } else if (ora == 4) { - //4:45-4:55 - processMinute4500(ora, minuto, giorno); - } else if (ora == 5) { - //5:00 - processMinute4500(ora, minuto, giorno); - } else if (ora == 8) { - //8:45-8:55 - processMinute4500(ora, minuto, giorno); - } else if (ora == 9) { - //9:00 - processMinute4500(ora, minuto, giorno); - } else if (ora == 11) { - //11:45-11:55 - processMinute4500(ora, minuto, giorno); - } else if (ora == 12) { - //12:00 - processMinute4500(ora, minuto, giorno); - } else if (ora == 15) { - //15:45.15:55 - processMinute4500(ora, minuto, giorno); - } else if (ora == 16) { - //16:00 - processMinute4500(ora, minuto, giorno); - } else if (ora == 18) { - //18:45-18:55 - processMinute4500(ora, minuto, giorno); - } else if (ora == 19) { - //19:00 - processMinute4500(ora, minuto, giorno); - } else if (ora == 23) { - processMinute0015(ora, minuto, giorno); - } else if (ora == 22) { - //22:00-22:15 - processMinute0015(ora, minuto, giorno); - } - - } - - /** - * Metodo per ottenere il boss che spawna alle 00 - * - * @param ora ora attuale - * @param minuto minuto attuale - * @param giorno giorno attuale - */ - private static void processMinute4500(int ora, int minuto, Giorno giorno) { - - if (giorno.getGiorno().equals(DayOfWeek.WEDNESDAY.name())) { - if (ora == 11 || ora == 12) { - return; - } - } - - if (minuto == 45) { - String[] listBoss = Boss.getHourBoss(ora + 1, 0, giorno.getBosses()); - publish(listBoss, "15"); - } else if (minuto == 50) { - String[] listBoss = Boss.getHourBoss(ora + 1, 0, giorno.getBosses()); - publish(listBoss, "10"); - } else if (minuto == 55) { - String[] listBoss = Boss.getHourBoss(ora + 1, 0, giorno.getBosses()); - publish(listBoss, "5"); - } else if (minuto == 0) { - String[] listBoss = Boss.getHourBoss(ora, 0, giorno.getBosses()); - publish(listBoss, "0"); - } - } - - /** - * Metodo per ottenere il boss che spawna alle 15 - * - * @param ora ora attuale - * @param minuto minuto attuale - * @param giorno giorno attuale - */ - private static void processMinute0015(int ora, int minuto, Giorno giorno) { - - if (giorno.getGiorno().equals(DayOfWeek.SATURDAY.name())) { - if (ora == 22) { - return; - } - } - - if (minuto == 0) { - String[] listBoss; - - listBoss = Boss.getHourBoss(ora, 15, giorno.getBosses()); - - publish(listBoss, "15"); - - } else if (minuto == 5) { - String[] listBoss = Boss.getHourBoss(ora, 15, giorno.getBosses()); - publish(listBoss, "10"); - - } else if (minuto == 10) { - String[] listBoss = Boss.getHourBoss(ora, 15, giorno.getBosses()); - publish(listBoss, "5"); - - } else if (minuto == 15) { - String[] listBoss = Boss.getHourBoss(ora, 15, giorno.getBosses()); - publish(listBoss, "0"); - } - } - - /** - * Metoto per eseguire la pubblicazione dei messaggi - * - * @param bosses lista boss trovati - * @param orarioMancante minuti mancanti allo spawn dei boss - */ - private static void publish(String[] bosses, String orarioMancante) { - if (bosses != null) { - ArrayList listServerChannel = PostgreSQLInterface.getBDOBossChannel(); - - String oraAttuale = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm")); - - MessageBuilder builder = new MessageBuilder(); - builder.append(oraAttuale).append(" -> "); - - for (String boss : bosses) { - builder.append(boss).append(" "); - } - - if (orarioMancante.equals("0")) { - builder.append("sta spawnando"); - } else { - builder.append("in arrivo tra: ").append(orarioMancante).append(" minuti"); - } - for (ServerToChannel channel : listServerChannel) { - jda.getGuildById(channel.getServerID()).getTextChannelById(channel.getChannelID()).sendMessage(builder.build()).queue(); - } - } - } - -} diff --git a/src/main/java/command/real/JoinListener.java b/src/main/java/command/real/JoinListener.java deleted file mode 100644 index d3bc66f..0000000 --- a/src/main/java/command/real/JoinListener.java +++ /dev/null @@ -1,27 +0,0 @@ -package command.real; - -import interfaces.PostgreSQLInterface; -import interfaces.TakaoLog; -import net.dv8tion.jda.core.events.guild.GuildJoinEvent; -import net.dv8tion.jda.core.events.guild.GuildLeaveEvent; -import net.dv8tion.jda.core.events.guild.update.GuildUpdateNameEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -public class JoinListener extends ListenerAdapter { - @Override - public void onGuildJoin(GuildJoinEvent event) { - TakaoLog.logInfo("REGISTRAZIONE GILDA " + event.getGuild().getName() + "\nID " + event.getGuild().getId()); - PostgreSQLInterface.newServer(event.getGuild().getName(), event.getGuild().getId()); - } - - @Override - public void onGuildLeave(GuildLeaveEvent event) { - PostgreSQLInterface.deleteServer(event.getGuild().getId()); - } - - @Override - public void onGuildUpdateName(GuildUpdateNameEvent event) { - event.getNewName(); - } - -} diff --git a/src/main/java/command/real/configuration/ConfigurationCommand.java b/src/main/java/command/real/configuration/ConfigurationCommand.java deleted file mode 100644 index 4f63b0b..0000000 --- a/src/main/java/command/real/configuration/ConfigurationCommand.java +++ /dev/null @@ -1,77 +0,0 @@ -package command.real.configuration; - -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.entities.ChannelType; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.util.Arrays; -import java.util.List; -import java.util.StringTokenizer; - -@Deprecated -public class ConfigurationCommand extends ListenerAdapter { - - public static String getCommand() { - return "configurationCommand"; - } - - public static String getCommandDescription() { - return "Questo comando permette la configurazione del prefisso per i comandi \n" + - "Questo comando è riservato al solo utilizzo da parte del proprietario del server."; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - if (event.isFromType(ChannelType.PRIVATE)) { - return; - } - - if (ControlCommand.controlCommand(event, getCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - if (event.getMessage().isMentioned(event.getJDA().getSelfUser())) { - - if ((new StringTokenizer(event.getMessage().getContentRaw())).countTokens() == 3) { - //menzionato e parametri a 3 - configuration(event); - } else { - event.getChannel().sendMessage("Quantità di parametri non conformi").queue(); - } - } else { - if ((new StringTokenizer(event.getMessage().getContentRaw())).countTokens() == 2) { - configuration(event); - - } else { - event.getChannel().sendMessage("Quantità di parametri non conformi").queue(); - } - } - } - - - } - } - - private void configuration(MessageReceivedEvent event) { - if (!(event.getMessage().getContentRaw().contains("\"") | event.getMessage().getContentRaw().contains("\\") | - event.getMessage().getContentRaw().contains("'"))) { - - List listMessage = Arrays.asList(event.getMessage().getContentRaw().split(" ")); - String newCommand = listMessage.get(listMessage.size() - 1); - PostgreSQLInterface.setSimbol(newCommand, event.getGuild().getId()); - - new MessageBuilder().append("Simbolo di comando configurato. Nuovo simbolo di comando: ") - .appendCodeBlock(PostgreSQLInterface.getSimbol(event.getGuild().getId()), "").sendTo(event.getChannel()).queue(); - } else { - new MessageBuilder().append("Simbolo di comando non conforme").sendTo(event.getChannel()).queue(); - } - } - -} diff --git a/src/main/java/command/real/configuration/ConfigurationReceiver.java b/src/main/java/command/real/configuration/ConfigurationReceiver.java deleted file mode 100644 index f25777a..0000000 --- a/src/main/java/command/real/configuration/ConfigurationReceiver.java +++ /dev/null @@ -1,154 +0,0 @@ -package command.real.configuration; - -import command.pattern.ControlCommand; -import command.real.BDO.BDOReceiver; -import command.real.tpl.atmAlert.ATMAlertReceiver; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.EmbedBuilder; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.entities.ChannelType; -import net.dv8tion.jda.core.entities.MessageEmbed; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.awt.*; -import java.util.Arrays; -import java.util.List; -import java.util.StringTokenizer; - -import static starter.Start.jda; - -public class ConfigurationReceiver extends ListenerAdapter { - - public static String getConfigurationCommandCommand() { - return "configurationCommand"; - } - - public static String getConfigurationCommandCommandDescription() { - return "Questo comando permette la configurazione del prefisso per i comandi \n" + - "Questo comando è riservato al solo utilizzo da parte del proprietario del server."; - } - - public static String getInfoCommand() { - return "info"; - } - - public static String getInfoCommandDescription() { - return "Info del bot."; - } - - public String getHelpCommand() { - return "help"; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - - if (event.getAuthor().isBot()) return; - if (event.isFromType(ChannelType.PRIVATE)) { - return; - } - - String simbolCommand = ControlCommand.getSimbolCommand(event.getGuild().getId()); - - if (ControlCommand.checkCommand(event, simbolCommand, getConfigurationCommandCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - if (event.getMessage().isMentioned(event.getJDA().getSelfUser())) { - - if ((new StringTokenizer(event.getMessage().getContentRaw())).countTokens() == 3) { - //menzionato e parametri a 3 - configuration(event); - } else { - event.getChannel().sendMessage("Quantità di parametri non conformi").queue(); - } - } else { - if ((new StringTokenizer(event.getMessage().getContentRaw())).countTokens() == 2) { - configuration(event); - - } else { - event.getChannel().sendMessage("Quantità di parametri non conformi").queue(); - } - } - } - - - } - - if (ControlCommand.checkCommand(event, simbolCommand, getHelpCommand())) { - - EmbedBuilder builder = new EmbedBuilder(); - - builder.setTitle("Lista Comandi").setColor(new Color(132, 197, 251)) - .setDescription("Questi comandi possono essere usati menzionando il bot e scrivendo il comando senza simbolo," + - "oppure usando i comandi direttamente come segue:") - - .addField(simbolCommand + ConfigurationReceiver.getInfoCommand(), ConfigurationReceiver.getInfoCommandDescription(), false) - .addField(simbolCommand + ConfigurationReceiver.getConfigurationCommandCommand(), ConfigurationReceiver.getConfigurationCommandCommandDescription(), false) - .addField(simbolCommand + BDOReceiver.getBDONewsStartCommand(), BDOReceiver.getBDONewsStartCommandDecription(), false) - .addField(simbolCommand + BDOReceiver.getBDONewsStopCommand(), BDOReceiver.getBDONewsStopCommandDecription(), false) - .addField(simbolCommand + BDOReceiver.getBDOPatchStartCommand(), BDOReceiver.getBDOPatchStartCommandDecription(), false) - .addField(simbolCommand + BDOReceiver.getBDOPatchStopCommand(), BDOReceiver.getBDOPatchStopCommandDecription(), false) - .addField(simbolCommand + BDOReceiver.getBDOBossStartCommand(), BDOReceiver.getBDOBossStartCommandDescription(), false) - .addField(simbolCommand + BDOReceiver.getBDOBossStopCommand(), BDOReceiver.getBDOBossStopCommandDescription(), false) - .addField(simbolCommand + ATMAlertReceiver.getATMStartCommand(), ATMAlertReceiver.getATMStartCommandDescription(), false) - .addField(simbolCommand + ATMAlertReceiver.getATMStopCommand(), ATMAlertReceiver.getATMStopCommandDescription(), false); - - event.getAuthor().openPrivateChannel().queue(privateChannel -> { - privateChannel.sendMessage(builder.build()).queue(); - }); - - } - - if (ControlCommand.checkCommand(event, simbolCommand, getInfoCommand())) { - - EmbedBuilder builder = new EmbedBuilder(); - - String info = "Ciao, sono samuele794#8585 lo sviluppatore di questo bot, scritto Java 8 con l'utilizzo " + - "della libreria di base JDA (Java Discord Api). \n\n" + - "Il personaggio Takao di Arpeggio Of Blue Steel (\u84bc\u304d\u92fc\u306e\u30a2\u30eb\u30da\u30b8\u30aa, Aoki Hagane no Arpeggio) " + - "è stato creato da Ark Performance. \nNon sono il possessore di nessuna immagine " + - "utilizzata all'interno del bot. \n\n" + - "Se sei uno sviluppatore Java e vuoi contribuire al bot sei ben accetto. \n" + - "Link GitHub: https://github.com/samuele794/TakaoBot \n\n" + - "Usando questo bot accetti il fatto che conserverò l'uso dei comandi per fini della manutenzione del bot \n\n" + - "Link utili: \n" + - "- Sito web: https://samuele794.github.io/TakaoBot/"; - - String avatarUrl = jda.getUserById("186582756841488385").getAvatarUrl(); - - MessageEmbed message = builder - .setImage("https://samuele794.github.io/TakaoBot/images/Copertina.png") - .setThumbnail(avatarUrl) - .setDescription(info) - .setColor(new Color(131, 196, 250)) - .build(); - - event.getAuthor().openPrivateChannel().queue(privateChannel -> { - privateChannel.sendMessage(message).queue(); - }); - - - } - - - } - - private void configuration(MessageReceivedEvent event) { - if (!(event.getMessage().getContentRaw().contains("\"") | event.getMessage().getContentRaw().contains("\\") | - event.getMessage().getContentRaw().contains("'"))) { - - List listMessage = Arrays.asList(event.getMessage().getContentRaw().split(" ")); - String newCommand = listMessage.get(listMessage.size() - 1); - PostgreSQLInterface.setSimbol(newCommand, event.getGuild().getId()); - - new MessageBuilder().append("Simbolo di comando configurato. Nuovo simbolo di comando: ") - .appendCodeBlock(PostgreSQLInterface.getSimbol(event.getGuild().getId()), "").sendTo(event.getChannel()).queue(); - } else { - new MessageBuilder().append("Simbolo di comando non conforme").sendTo(event.getChannel()).queue(); - } - } -} diff --git a/src/main/java/command/real/configuration/HelpCommand.java b/src/main/java/command/real/configuration/HelpCommand.java deleted file mode 100644 index 19fd90d..0000000 --- a/src/main/java/command/real/configuration/HelpCommand.java +++ /dev/null @@ -1,58 +0,0 @@ -package command.real.configuration; - -import command.pattern.ControlCommand; -import command.real.BDO.BDOReceiver; -import command.real.tpl.atmAlert.ATMAlertReceiver; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.EmbedBuilder; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.awt.*; - -@Deprecated -public class HelpCommand extends ListenerAdapter { - - public String getCommand() { - return "help"; - } - - public String getCommandDescription() { - return null; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - - if (ControlCommand.controlCommand(event, getCommand())) { - - String simbol = PostgreSQLInterface.getSimbol(event.getGuild().getId()); - EmbedBuilder builder = new EmbedBuilder(); - - builder.setTitle("Lista Comandi").setColor(new Color(132, 197, 251)) - .setDescription("Questi comandi possono essere usati menzionando il bot e scrivendo il comando senza simbolo," + - "oppure usando i comandi direttamente come segue:") - - .addField(simbol + InfoCommand.getCommand(), InfoCommand.getCommandDescription(), false) - .addField(simbol + ConfigurationCommand.getCommand(), ConfigurationCommand.getCommandDescription(), false) - .addField(simbol + BDOReceiver.getBDONewsStartCommand(), BDOReceiver.getBDONewsStartCommandDecription(), false) - .addField(simbol + BDOReceiver.getBDONewsStopCommand(), BDOReceiver.getBDONewsStopCommandDecription(), false) - .addField(simbol + BDOReceiver.getBDOPatchStartCommand(), BDOReceiver.getBDOPatchStartCommandDecription(), false) - .addField(simbol + BDOReceiver.getBDOPatchStopCommand(), BDOReceiver.getBDOPatchStopCommandDecription(), false) - .addField(simbol + BDOReceiver.getBDOBossStartCommand(), BDOReceiver.getBDOBossStartCommandDescription(), false) - .addField(simbol + BDOReceiver.getBDOBossStopCommand(), BDOReceiver.getBDOBossStopCommandDescription(), false) - .addField(simbol + ATMAlertReceiver.getATMStartCommand(), ATMAlertReceiver.getATMStartCommandDescription(), false) - .addField(simbol + ATMAlertReceiver.getATMStopCommand(), ATMAlertReceiver.getATMStopCommandDescription(), false); - - event.getAuthor().openPrivateChannel().queue(privateChannel -> { - privateChannel.sendMessage(builder.build()).queue(); - }); - - } - - } - - -} diff --git a/src/main/java/command/real/configuration/InfoCommand.java b/src/main/java/command/real/configuration/InfoCommand.java deleted file mode 100644 index 39d8318..0000000 --- a/src/main/java/command/real/configuration/InfoCommand.java +++ /dev/null @@ -1,62 +0,0 @@ -package command.real.configuration; - -import command.pattern.ControlCommand; -import net.dv8tion.jda.core.EmbedBuilder; -import net.dv8tion.jda.core.entities.MessageEmbed; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.awt.*; - -import static starter.Start.jda; - -@Deprecated -public class InfoCommand extends ListenerAdapter { - - public static String getCommand() { - return "info"; - } - - public static String getCommandDescription() { - return "Info del bot."; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - if (ControlCommand.controlCommand(event, getCommand())) { - - EmbedBuilder builder = new EmbedBuilder(); - - String info = "Ciao, sono samuele794#8585 lo sviluppatore di questo bot, scritto Java 8 con l'utilizzo " + - "della libreria di base JDA (Java Discord Api). \n\n" + - "Il personaggio Takao di Arpeggio Of Blue Steel (\u84bc\u304d\u92fc\u306e\u30a2\u30eb\u30da\u30b8\u30aa, Aoki Hagane no Arpeggio) " + - "è stato creato da Ark Performance. \nNon sono il possessore di nessuna immagine " + - "utilizzata all'interno del bot. \n\n" + - "Se sei uno sviluppatore Java e vuoi contribuire al bot sei ben accetto. \n" + - "Link GitHub: https://github.com/samuele794/TakaoBot \n\n" + - "Usando questo bot accetti il fatto che conserverò l'uso dei comandi per fini della manutenzione del bot \n\n" + - "Link utili: \n" + - "- Sito web: https://samuele794.github.io/TakaoBot/"; - - String avatarUrl = jda.getUserById("186582756841488385").getAvatarUrl(); - - MessageEmbed message = builder - .setImage("https://samuele794.github.io/TakaoBot/images/Copertina.png") - .setThumbnail(avatarUrl) - .setDescription(info) - .setColor(new Color(131, 196, 250)) - .build(); - - event.getAuthor().openPrivateChannel().queue(privateChannel -> { - privateChannel.sendMessage(message).queue(); - }); - - - } - - } - - -} diff --git a/src/main/java/command/real/sound/AudioPlayerSendHandler.java b/src/main/java/command/real/sound/AudioPlayerSendHandler.java deleted file mode 100644 index ee876f0..0000000 --- a/src/main/java/command/real/sound/AudioPlayerSendHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -package command.real.sound; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; -import net.dv8tion.jda.core.audio.AudioSendHandler; - -/** - * This is a wrapper around AudioPlayer which makes it behave as an AudioSendHandler for JDA. As JDA calls canProvide - * before every call to provide20MsAudio(), we pull the frame in canProvide() and use the frame we already pulled in - * provide20MsAudio(). - */ -public class AudioPlayerSendHandler implements AudioSendHandler { - private final AudioPlayer audioPlayer; - private AudioFrame lastFrame; - - /** - * @param audioPlayer Audio player to wrap. - */ - public AudioPlayerSendHandler(AudioPlayer audioPlayer) { - this.audioPlayer = audioPlayer; - } - - @Override - public boolean canProvide() { - if (lastFrame == null) { - lastFrame = audioPlayer.provide(); - } - - return lastFrame != null; - } - - @Override - public byte[] provide20MsAudio() { - if (lastFrame == null) { - lastFrame = audioPlayer.provide(); - } - - byte[] data = lastFrame != null ? lastFrame.getData() : null; - lastFrame = null; - - return data; - } - - @Override - public boolean isOpus() { - return true; - } -} - diff --git a/src/main/java/command/real/sound/GuildMusicManager.java b/src/main/java/command/real/sound/GuildMusicManager.java deleted file mode 100644 index b6719e6..0000000 --- a/src/main/java/command/real/sound/GuildMusicManager.java +++ /dev/null @@ -1,34 +0,0 @@ -package command.real.sound; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; - -/** - * Holder for both the player and a track scheduler for one guild. - */ -public class GuildMusicManager { - /** - * Audio player for the guild. - */ - public final AudioPlayer player; - /** - * Track scheduler for the player. - */ - public final TrackScheduler scheduler; - /** - * Wrapper around AudioPlayer to use it as an AudioSendHandler. - */ - public final AudioPlayerSendHandler sendHandler; - - /** - * Creates a player and a track scheduler. - * - * @param manager Audio player manager to use for creating the player. - */ - public GuildMusicManager(AudioPlayerManager manager) { - player = manager.createPlayer(); - scheduler = new TrackScheduler(player); - sendHandler = new AudioPlayerSendHandler(player); - player.addListener(scheduler); - } -} diff --git a/src/main/java/command/real/sound/MusicManager.java b/src/main/java/command/real/sound/MusicManager.java deleted file mode 100644 index 7403e5d..0000000 --- a/src/main/java/command/real/sound/MusicManager.java +++ /dev/null @@ -1,445 +0,0 @@ -package command.real.sound; - -import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; -import com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.local.LocalAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.soundcloud.SoundCloudAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager; -import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; -import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import interfaces.TakaoLog; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.entities.Guild; -import net.dv8tion.jda.core.entities.MessageChannel; -import net.dv8tion.jda.core.entities.VoiceChannel; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.exceptions.PermissionException; - -import java.util.*; - -/** - * Classe per gestire il musicBot - */ - -public class MusicManager { - - private static final int DEFAULT_VOLUME = 25; //(0 - 150, where 100 is default max volume) - private final Map musicManagers; - private AudioPlayerManager playerManager; - - public MusicManager() { - - this.playerManager = new DefaultAudioPlayerManager(); - playerManager.registerSourceManager(new YoutubeAudioSourceManager()); - playerManager.registerSourceManager(new SoundCloudAudioSourceManager()); -// playerManager.registerSourceManager(new BandcampAudioSourceManager()); -// playerManager.registerSourceManager(new VimeoAudioSourceManager()); - playerManager.registerSourceManager(new TwitchStreamAudioSourceManager()); - playerManager.registerSourceManager(new HttpAudioSourceManager()); - playerManager.registerSourceManager(new LocalAudioSourceManager()); - - musicManagers = new HashMap<>(); - } - - /** - * Parsing del messaggio per ottenere l'url - * - * @param event - * @return String url della canzone - */ - private static String getUrl(MessageReceivedEvent event) { - List listMessage = Arrays.asList(event.getMessage().getContentRaw().split(" ")); - return listMessage.get(listMessage.size() - 1); - } - - private static String getTimestamp(long milliseconds) { - int seconds = (int) (milliseconds / 1000) % 60; - int minutes = (int) ((milliseconds / (1000 * 60)) % 60); - int hours = (int) ((milliseconds / (1000 * 60 * 60)) % 24); - - if (hours > 0) - return String.format("%02d:%02d:%02d", hours, minutes, seconds); - else - return String.format("%02d:%02d", minutes, seconds); - } - - /** - * Metodo per eseguire il join nel canale - * - * @param event - */ - private void join(MessageReceivedEvent event) { - - Guild guild = event.getGuild(); - GuildMusicManager guildMusicManager = getMusicManager(guild.getId()); - - VoiceChannel voiceChannel; - if (event.getMember().getVoiceState().inVoiceChannel()) { - voiceChannel = event.getMember().getVoiceState().getChannel(); - guild.getAudioManager().setSendingHandler(guildMusicManager.sendHandler); - - try { - guild.getAudioManager().openAudioConnection(voiceChannel); - } catch (PermissionException e) { - if (e.getPermission() == Permission.VOICE_CONNECT) { - event.getChannel().sendMessage("Accesso al canale negato").queue(); - } - - TakaoLog.logError("Problemi accesso al canale " + event.getChannel().getName() + "del server" + - event.getGuild().getName()); - } - } else { - event.getChannel().sendMessage("Entra in un canale vocale, per favore").queue(); - } - - } - - /** - * Metodo per far uscire il bot dalla lobby, bloccherà la queue - * e la svuoterà - * - * @param event - */ - void leave(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - if (!guildMusicManager.scheduler.getQueue().isEmpty()) { - guildMusicManager.scheduler.getQueue().clear(); - } - - guildMusicManager.player.stopTrack(); - guildMusicManager.player.setPaused(false); - guildMusicManager.player.destroy(); - event.getGuild().getAudioManager().setSendingHandler(null); - event.getGuild().getAudioManager().closeAudioConnection(); - } - - /** - * Metodo per riprodurre l'url audio passato come parametro - * @param event - */ - void play(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - Guild guild = event.getGuild(); - if (guild.getAudioManager().getSendingHandler() == null) { - this.join(event); - } - - if (event.getMessage().isMentioned(event.getJDA().getSelfUser())) { - - if ((new StringTokenizer(event.getMessage().getContentRaw())).countTokens() == 3) { - //menzionato e parametri a 3 - - loadAndPlay(guildMusicManager, event.getChannel(), getUrl(event), false); - } else { - event.getChannel().sendMessage("Quantità di parametri non conformi").queue(); - } - } else { - if ((new StringTokenizer(event.getMessage().getContentRaw())).countTokens() == 2) { - - loadAndPlay(guildMusicManager, event.getChannel(), getUrl(event), false); - } else { - event.getChannel().sendMessage("Quantità di parametri non conformi").queue(); - } - } - } - - /** - * Metodo per riprodurre una playlist dall'url passato come parametro - * @param event - */ - void playPlaylist(MessageReceivedEvent event) { - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - Guild guild = event.getGuild(); - if (guild.getAudioManager().getSendingHandler() == null) { - this.join(event); - } - - loadAndPlay(guildMusicManager, event.getChannel(), getUrl(event), true); - } - - /** - * Metodo per saltare la traccia attualmente in riproduzione - * @param event - */ - void skip(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - guildMusicManager.scheduler.nextTrack(); - event.getChannel().sendMessage("Canzone saltata").queue(); - } - - /** - * Metodo per mettere in pausa o riprendere la traccia attualmente - * in riproduzione - * @param event - */ - void pauseResume(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - AudioPlayer player = guildMusicManager.player; - - if (player.getPlayingTrack() == null) { - event.getChannel().sendMessage("Non è possibile mettere in pausa o riprendere il nulla, coglione.").queue(); - return; - } - - player.setPaused(!player.isPaused()); - if (player.isPaused()) - event.getChannel().sendMessage("Riproduzione in pausa").queue(); - else - event.getChannel().sendMessage("Ripresa riproduzione").queue(); - } - - /** - * Metodo per stoppare la riproduzione e pulire la coda - * @param event - */ - void stop(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - - guildMusicManager.scheduler.getQueue().clear(); - guildMusicManager.player.stopTrack(); - guildMusicManager.player.setPaused(false); - event.getChannel().sendMessage("Riproduzione stoppata e playlist svuotata").queue(); - - } - - /** - * Metodo per cambiare il volume, attualmente non in uso. - * Bisogno di calcolo computazionale extra per il cambio del volume. - * @param event - */ - private void changeVolume(MessageReceivedEvent event) { -/* if (command.length == 1) { - event.getChannel().sendMessage("Current player volume: **" + player.getVolume() + "**").queue(); - } else { - try { - int newVolume = Math.max(10, Math.min(100, Integer.parseInt(command[1]))); - int oldVolume = player.getVolume(); - player.setVolume(newVolume); - event.getChannel().sendMessage("Player volume changed from `" + oldVolume + "` to `" + newVolume + "`").queue(); - } catch (NumberFormatException e) { - event.getChannel().sendMessage("`" + command[1] + "` is not a valid integer. (10 - 100)").queue(); - } - }*/ - } - - /** - * Metodo per riavviare la traccia attualmente in riproduzione - * @param event - */ - void restart(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - - AudioTrack track = guildMusicManager.player.getPlayingTrack(); - if (track == null) - track = guildMusicManager.scheduler.lastTrack; - - if (track != null) { - event.getChannel().sendMessage("Riavvio traccia: " + track.getInfo().title).queue(); - guildMusicManager.player.playTrack(track.makeClone()); - } -// else { -// //Nessuna traccia è stata pre -// event.getChannel().sendMessage("No track has been previously started, so the player cannot replay a track!").queue(); -// } - } - - /** - * Metodo per ripetere la traccia attualmente in riproduzione - * @param event - */ - void repeat(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - guildMusicManager.scheduler.setRepeating(!guildMusicManager.scheduler.isRepeating()); - event.getChannel().sendMessage("Riproduzione impostata su: **" + (guildMusicManager.scheduler.isRepeating() ? "ripeti" : "non ripetere") + "**").queue(); - - } - - /** - * Metodo per resettare il bot in caso di problemi. - * Pulisce la coda, e resetta i canali audio - * @param event - */ - void reset(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - - synchronized (musicManagers) { - guildMusicManager.scheduler.getQueue().clear(); - guildMusicManager.player.destroy(); - event.getGuild().getAudioManager().setSendingHandler(null); - musicManagers.remove(event.getGuild().getId()); - } - - event.getGuild().getAudioManager().setSendingHandler(guildMusicManager.sendHandler); - event.getChannel().sendMessage("Riproduttore resettato").queue(); - } - - /** - * Metodo per ottenere la traccia attualmente in riproduzione - * @param event - */ - void nowPlay(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - - AudioTrack currentTrack = guildMusicManager.player.getPlayingTrack(); - if (currentTrack != null) { - String title = currentTrack.getInfo().title; - String position = getTimestamp(currentTrack.getPosition()); - String duration = getTimestamp(currentTrack.getDuration()); - - String nowplaying = String.format("**In Riprodzione:** %s\n**Time:** [%s / %s]", - title, position, duration); - - event.getChannel().sendMessage(nowplaying).queue(); - } else - event.getChannel().sendMessage("Non sto riproducendo nulla!").queue(); - } - - /** - * Metodo per ottenere la lista della coda - * @param event - */ - void getListQueue(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - Queue queue = guildMusicManager.scheduler.getQueue(); - - synchronized (queue) { - if (queue.isEmpty()) { - event.getChannel().sendMessage("La coda è vuota").queue(); - } else { - int trackCount = 0; - long queueLength = 0; - StringBuilder sb = new StringBuilder(); - sb.append("Coda attuale: ").append(queue.size()).append("\n"); - for (AudioTrack track : queue) { - queueLength += track.getDuration(); - if (trackCount < 10) { - sb.append("`[").append(getTimestamp(track.getDuration())).append("]` "); - sb.append(track.getInfo().title).append("\n"); - trackCount++; - } - } - sb.append("\n").append("Tempo totale di coda: ").append(getTimestamp(queueLength)); - - event.getChannel().sendMessage(sb.toString()).queue(); - } - } - } - - /** - * Metodo per randomizzare la coda - * @param event - */ - void shuffleQueue(MessageReceivedEvent event) { - - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - - if (guildMusicManager.scheduler.getQueue().isEmpty()) { - event.getChannel().sendMessage("La coda è attualmente vuota!").queue(); - return; - } - - guildMusicManager.scheduler.shuffle(); - event.getChannel().sendMessage("Coda mischiata").queue(); - } - - - void clearQueue(MessageReceivedEvent event) { - GuildMusicManager guildMusicManager = getMusicManager(event.getGuild().getId()); - - if (!guildMusicManager.scheduler.getQueue().isEmpty()) { - guildMusicManager.scheduler.getQueue().clear(); - event.getChannel().sendMessage("Coda Pulita").queue(); - } else { - event.getChannel().sendMessage("La coda è già vuota").queue(); - } - - } - - /** - * Metodo per caricare una traccia o una playlist nella coda - * @param mng - * @param channel - * @param url - * @param addPlaylist - */ - private void loadAndPlay(GuildMusicManager mng, final MessageChannel channel, String url, final boolean addPlaylist) { - final String trackUrl; - - //Strip <>'s that prevent discord from embedding link resources - if (url.startsWith("<") && url.endsWith(">")) - trackUrl = url.substring(1, url.length() - 1); - else - trackUrl = url; - - playerManager.loadItemOrdered(mng, trackUrl, new AudioLoadResultHandler() { - @Override - public void trackLoaded(AudioTrack track) { - String msg = "Aggiunta alla coda: " + track.getInfo().title; - if (mng.player.getPlayingTrack() == null) - msg += "\ne inizio riproduzione"; - - mng.scheduler.queue(track); - channel.sendMessage(msg).queue(); - } - - @Override - public void playlistLoaded(AudioPlaylist playlist) { - AudioTrack firstTrack = playlist.getSelectedTrack(); - List tracks = playlist.getTracks(); - - - if (firstTrack == null) { - firstTrack = playlist.getTracks().get(0); - } - - if (addPlaylist) { - channel.sendMessage("Aggiunte **" + playlist.getTracks().size() + "** tracce alla coda").queue(); - tracks.forEach(mng.scheduler::queue); - } else { - channel.sendMessage("Aggiunto alla coda " + firstTrack.getInfo().title).queue(); - mng.scheduler.queue(firstTrack); - } - } - - @Override - public void noMatches() { - channel.sendMessage("Non ho abbastanza forza di vedere dentro a " + trackUrl).queue(); - } - - @Override - public void loadFailed(FriendlyException exception) { - channel.sendMessage("Non è nel mio potere: " + exception.getMessage()).queue(); - } - }); - } - - private GuildMusicManager getMusicManager(String guildId) { - GuildMusicManager mng = musicManagers.get(guildId); - if (mng == null) { - synchronized (musicManagers) { - mng = musicManagers.get(guildId); - if (mng == null) { - mng = new GuildMusicManager(playerManager); - mng.player.setVolume(DEFAULT_VOLUME); - musicManagers.put(guildId, mng); - } - } - } - return mng; - } -} diff --git a/src/main/java/command/real/sound/PlayerControlCommand.java b/src/main/java/command/real/sound/PlayerControlCommand.java deleted file mode 100644 index 6823d63..0000000 --- a/src/main/java/command/real/sound/PlayerControlCommand.java +++ /dev/null @@ -1,86 +0,0 @@ -package command.real.sound; - -import command.pattern.ControlCommand; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -public class PlayerControlCommand extends ListenerAdapter { - - private MusicManager musicManager; - - public PlayerControlCommand() { - this.musicManager = new MusicManager(); - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - String simbolCommand = ControlCommand.getSimbolCommand(event.getGuild().getId()); - - - if (ControlCommand.checkCommand(event, simbolCommand, "leave")) { - - musicManager.leave(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "play")) { - - musicManager.play(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "playPlaylist") | - ControlCommand.checkCommand(event, simbolCommand, "pp")) { - - musicManager.playPlaylist(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "skip") | - ControlCommand.checkCommand(event, simbolCommand, "salta")) { - - musicManager.skip(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "pausa") | - ControlCommand.checkCommand(event, simbolCommand, "pause") | - ControlCommand.checkCommand(event, simbolCommand, "resume") | - ControlCommand.checkCommand(event, simbolCommand, "riprendi")) { - - musicManager.pauseResume(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "stop")) { - - musicManager.stop(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "restart")) { - - musicManager.restart(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "repeat") | - ControlCommand.checkCommand(event, simbolCommand, "ripeti")) { - - musicManager.repeat(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "reset")) { - - musicManager.reset(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "nowplaying") | - ControlCommand.checkCommand(event, simbolCommand, "np")) { - - musicManager.nowPlay(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "queue") | - ControlCommand.checkCommand(event, simbolCommand, "lista")) { - - musicManager.getListQueue(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "shuffle")) { - - musicManager.shuffleQueue(event); - - } else if (ControlCommand.checkCommand(event, simbolCommand, "clear") | - ControlCommand.checkCommand(event, simbolCommand, "pulisci")) { - - musicManager.clearQueue(event); - } - } - - -} \ No newline at end of file diff --git a/src/main/java/command/real/sound/TrackScheduler.java b/src/main/java/command/real/sound/TrackScheduler.java deleted file mode 100644 index 4fca8d3..0000000 --- a/src/main/java/command/real/sound/TrackScheduler.java +++ /dev/null @@ -1,82 +0,0 @@ -package command.real.sound; - -import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; -import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter; -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; - -/** - * This class schedules tracks for the audio player. It contains the queue of tracks. - */ -public class TrackScheduler extends AudioEventAdapter { - private boolean repeating = false; - final AudioPlayer player; - private final Queue queue; - public AudioTrack lastTrack; - - /** - * @param player The audio player this scheduler uses - */ - public TrackScheduler(AudioPlayer player) { - this.player = player; - this.queue = new LinkedList<>(); - } - - /** - * Add the next track to queue or play right away if nothing is in the queue. - * - * @param track The track to play or add to queue. - */ - public void queue(AudioTrack track) { - - // Calling startTrack with the noInterrupt set to true will start the track only if nothing is currently playing. If - // something is playing, it returns false and does nothing. In that case the player was already playing so this - // track goes to the queue instead. - if (!player.startTrack(track, true)) { - queue.offer(track); - } - } - - /** - * Start the next track, stopping the current one if it is playing. - */ - public void nextTrack() { - // Start the next track, regardless of if something is already playing or not. In case queue was empty, we are - // giving null to startTrack, which is a valid argument and will simply stop the player. - player.startTrack(queue.poll(), false); - } - - @Override - public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { - this.lastTrack = track; - // Only start the next track if the end reason is suitable for it (FINISHED or LOAD_FAILED) - if (endReason.mayStartNext) { - if (repeating) - player.startTrack(lastTrack.makeClone(), false); - else - nextTrack(); - } - - } - - public Queue getQueue() { - return queue; - } - - public boolean isRepeating() { - return repeating; - } - - public void setRepeating(boolean repeating) { - this.repeating = repeating; - } - - public void shuffle() { - Collections.shuffle((List) queue); - } -} diff --git a/src/main/java/command/real/tpl/atmAlert/ATMAlertReceiver.java b/src/main/java/command/real/tpl/atmAlert/ATMAlertReceiver.java deleted file mode 100644 index 0ddfd74..0000000 --- a/src/main/java/command/real/tpl/atmAlert/ATMAlertReceiver.java +++ /dev/null @@ -1,64 +0,0 @@ -package command.real.tpl.atmAlert; - -import beans.ServerToChannel; -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.util.ArrayList; - -public class ATMAlertReceiver extends ListenerAdapter { - - public static String getATMStartCommand() { - return "ATMAlertStart"; - } - - public static String getATMStartCommandDescription() { - return "Questo comando permette di iscriversi agli avvisi dell'ATM Milano. \n" + - "Il comando deve essere lanciato sul canale su cui si desidera ricevere gli avvisi"; - } - - public static String getATMStopCommand() { - return "ATMAlertStop"; - } - - public static String getATMStopCommandDescription() { - return "Questo comando permette disiscriversi agli avvisi dell'ATM Milano. \n" + - "Il comando può essere lanciato su qualunque canale"; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - String simbol = ControlCommand.getSimbolCommand(event.getGuild().getId()); - - if (ControlCommand.checkCommand(event, simbol, getATMStartCommand())) { - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - PostgreSQLInterface.setATMAlertChannel(event.getGuild().getId(), event.getChannel().getId()); - new MessageBuilder().append("Invio degli avvisi dell'ATM configurato sul canale: ") - .appendCodeBlock(event.getChannel().getName(), "").sendTo(event.getChannel()).queue(); - } - } else if (ControlCommand.checkCommand(event, simbol, getATMStopCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - ArrayList listChannel = PostgreSQLInterface.getATMAlertChannel(); - ServerToChannel removedChannelId = listChannel.get(listChannel.indexOf(new ServerToChannel(event.getGuild().getId(), null))); - - PostgreSQLInterface.removeATMAlertChannel(event.getGuild().getId()); - - new MessageBuilder().append("Invio degli avvisi dell'ATM rimosso dal canale: ") - .appendCodeBlock(event.getJDA().getTextChannelById(removedChannelId.getChannelID()).getName(), "") - .sendTo(event.getChannel()).queue(); - } - } - - } -} diff --git a/src/main/java/command/real/tpl/atmAlert/ATMAlertStartCommand.java b/src/main/java/command/real/tpl/atmAlert/ATMAlertStartCommand.java deleted file mode 100644 index 14ae657..0000000 --- a/src/main/java/command/real/tpl/atmAlert/ATMAlertStartCommand.java +++ /dev/null @@ -1,37 +0,0 @@ -package command.real.tpl.atmAlert; - -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -@Deprecated -public class ATMAlertStartCommand extends ListenerAdapter { - - public static String getCommand() { - return "ATMAlertStart"; - } - - public static String getCommandDescription() { - return "Questo comando permette di iscriversi agli avvisi dell'ATM Milano \n" + - "Il comando deve essere lanciato sul canale su cui si desidera ricevere gli avvisi"; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - if (ControlCommand.controlCommand(event, getCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - PostgreSQLInterface.setATMAlertChannel(event.getGuild().getId(), event.getChannel().getId()); - new MessageBuilder().append("Invio degli avvisi dell'ATM configurato sul canale: ") - .appendCodeBlock(event.getChannel().getName(), "").sendTo(event.getChannel()).queue(); - } - } - } -} diff --git a/src/main/java/command/real/tpl/atmAlert/ATMAlertStopCommand.java b/src/main/java/command/real/tpl/atmAlert/ATMAlertStopCommand.java deleted file mode 100644 index 2f4c89b..0000000 --- a/src/main/java/command/real/tpl/atmAlert/ATMAlertStopCommand.java +++ /dev/null @@ -1,45 +0,0 @@ -package command.real.tpl.atmAlert; - -import beans.ServerToChannel; -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.util.ArrayList; - -@Deprecated -public class ATMAlertStopCommand extends ListenerAdapter { - - public static String getCommand() { - return "ATMAlertStop"; - } - - public static String getCommandDescription() { - return "Questo comando permette disiscriversi agli avvisi dell'ATM Milano. \n" + - "Il comando può essere lanciato su qualunque canale"; - } - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - - if (ControlCommand.controlCommand(event, getCommand())) { - - if (!event.getGuild().getMember(event.getAuthor()).hasPermission(Permission.ADMINISTRATOR)) { - event.getChannel().sendMessage(event.getAuthor().getName() + " non sei autorizzato all'uso di questo comando").queue(); - } else { - ArrayList listChannel = PostgreSQLInterface.getATMAlertChannel(); - ServerToChannel removedChannelId = listChannel.get(listChannel.indexOf(new ServerToChannel(event.getGuild().getId(), null))); - - PostgreSQLInterface.removeATMAlertChannel(event.getGuild().getId()); - - new MessageBuilder().append("Invio degli avvisi dell'ATM rimosso dal canale: ") - .appendCodeBlock(event.getJDA().getTextChannelById(removedChannelId.getChannelID()).getName(), "") - .sendTo(event.getChannel()).queue(); - } - } - } -} diff --git a/src/main/java/command/real/tpl/atmAlert/ATMRSSReader.java b/src/main/java/command/real/tpl/atmAlert/ATMRSSReader.java deleted file mode 100644 index 0939df9..0000000 --- a/src/main/java/command/real/tpl/atmAlert/ATMRSSReader.java +++ /dev/null @@ -1,83 +0,0 @@ -package command.real.tpl.atmAlert; - -import beans.RSSMessage; -import com.rometools.rome.feed.synd.SyndEntry; -import com.rometools.rome.feed.synd.SyndFeed; -import com.rometools.rome.io.FeedException; -import com.rometools.rome.io.SyndFeedInput; -import com.rometools.rome.io.XmlReader; -import net.dv8tion.jda.core.EmbedBuilder; -import net.dv8tion.jda.core.entities.MessageEmbed; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; - -import java.awt.*; -import java.io.IOException; -import java.net.URL; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class ATMRSSReader { - - public static RSSMessage readRSS(String URL) { - SyndFeedInput input = new SyndFeedInput(); - - String title = null; - String link = null; - Document doc = null; - - try { - URL url = new URL(URL); - SyndFeed feed = input.build(new XmlReader(url)); - List entryList = feed.getEntries(); - - SyndEntry entry = entryList.get(entryList.size() - 1); - - - title = entry.getTitle(); - link = entry.getLink(); - doc = Jsoup.parse(entry.getDescription().getValue()); - - } catch (FeedException | IOException e) { - e.printStackTrace(); - } - - return new RSSMessage(title, link, doc); - } - - public static MessageEmbed prepareRSStoEmbeddedMessage(RSSMessage message) { - EmbedBuilder builder = new EmbedBuilder(); - - Pattern regex = Pattern.compile( - "

|

|
", - Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.COMMENTS); - Matcher regexMatcher = regex.matcher(message.getDoc().toString()); - String mess = regexMatcher.replaceAll("br2n"); - - regex = Pattern.compile( - "

|

", - Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.COMMENTS); - regexMatcher = regex.matcher(mess); - mess = regexMatcher.replaceAll(""); - - - regex = Pattern.compile( - "|", - Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.COMMENTS); - regexMatcher = regex.matcher(mess); - mess = regexMatcher.replaceAll("**"); - - mess = Jsoup.parse(mess).text().replaceAll("br2n", "\n"); - - if (mess.length() >= 2048){ - mess = new StringBuilder().append( mess.subSequence(0, 2000).toString()).append("\n\n Continua nel link...").toString(); - } - - return builder.setTitle(message.getTitle(), message.getLink()) - .setThumbnail("https://i.imgur.com/2cMpNuI.png") - .setDescription(mess).setColor(new Color(244, 131, 37)).build(); - - - } -} diff --git a/src/main/java/command/real/tpl/atmAlert/AtmScheduler.java b/src/main/java/command/real/tpl/atmAlert/AtmScheduler.java deleted file mode 100644 index 97b883b..0000000 --- a/src/main/java/command/real/tpl/atmAlert/AtmScheduler.java +++ /dev/null @@ -1,148 +0,0 @@ -package command.real.tpl.atmAlert; - -import beans.RSSMessage; -import beans.ServerToChannel; -import interfaces.PostgreSQLInterface; -import interfaces.TakaoLog; -import interfaces.TwitterManager; -import net.dv8tion.jda.core.EmbedBuilder; -import net.dv8tion.jda.core.entities.MessageEmbed; -import twitter4j.*; - -import java.awt.*; -import java.util.ArrayList; -import java.util.TimerTask; - -import static starter.Start.jda; - -public class AtmScheduler { - - private static TwitterManager manager = new TwitterManager().getTwitterManagerWithStream(); - private static String twitterUrl = "https://twitter.com/atm_informa/status/"; -// https://twitter.com/atm_informa/status/[id of status] - - public static void startAtmTweetScheduler() { - String QUERY_PARAM = "exclude:retweets exclude:replies"; - StatusListener listener = new StatusListener() { - @Override - public void onStatus(Status status) { - - TakaoLog.logInfo("ATMUSERID " + status.getUser().getScreenName() + " " + status.getUser().getId()); - - if (status.getUser().getId() == 988355810) { - if (!status.isRetweet()) { - ((Runnable) () -> { - Status statusCopy = status; - long id = statusCopy.getId(); - String text = statusCopy.getText(); - String mediaUrl = null; - if (statusCopy.getMediaEntities().length != 0) { - mediaUrl = statusCopy.getMediaEntities()[0].getMediaURL(); - } - String profileImageUrl = statusCopy.getUser().getProfileImageURL(); - TakaoLog.logInfo("ATM Message" + id + " " + text); - System.out.println("ATM Message" + id + " " + text); - getMessage(id, text, mediaUrl, profileImageUrl); - }).run(); - } - } - - } - - @Override - public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) { - - } - - @Override - public void onTrackLimitationNotice(int numberOfLimitedStatuses) { - - } - - @Override - public void onScrubGeo(long userId, long upToStatusId) { - - } - - @Override - public void onStallWarning(StallWarning warning) { - - } - - @Override - public void onException(Exception ex) { - - } - }; - FilterQuery query = new FilterQuery().track(QUERY_PARAM); - - query.follow(988355810); - manager.setTwitterStreamListener(listener); - manager.setTwitterStreamFilter(query); - - } - - public static TimerTask taskFeedRSSATM() { - return new TimerTask() { - @Override - public void run() { - RSSMessage message = ATMRSSReader.readRSS("https://www.atm.it/_layouts/atm/apps/PublishingRSS.aspx?web=388a6572-890f-4e0f-a3c7-a3dd463f7252&c=News%20Infomobilita"); - - String lastATMAlert = PostgreSQLInterface.getLastATMAlert(); - - if (lastATMAlert != null) { - if (!lastATMAlert.equals(message.getLink())) { - publish(message); - PostgreSQLInterface.setLastATMAlert(message.getLink()); - } - } else { - publish(message); - PostgreSQLInterface.setLastATMAlert(message.getLink()); - } - - - } - }; - - } - - private static void publish(RSSMessage message) { - ArrayList serverList = PostgreSQLInterface.getATMAlertChannel(); - MessageEmbed messageEmbed = ATMRSSReader.prepareRSStoEmbeddedMessage(message); - for (ServerToChannel item : serverList) { - jda.getGuildById(item.getServerID()). - getTextChannelById(item.getChannelID()).sendMessage(messageEmbed).queue(); - - } - } - - private static void getMessage(long tweetId, String twitterMessage, String mediaUrl, String profileImageUrl) { - TakaoLog.logInfo("PROCESSAZIONE MESSAGE"); - String tweetUrl = twitterUrl + tweetId; - - //cambiare in contains - if (twitterMessage.contains("#tram") || - twitterMessage.contains("#bus") || - twitterMessage.contains("#M1") || - twitterMessage.contains("#M2") || - twitterMessage.contains("#M3") || - twitterMessage.contains("#M5") || - twitterMessage.contains("\ud83d\udea6")) { - EmbedBuilder messageEmbed = new EmbedBuilder(); - - messageEmbed.setAuthor("ATM (@atm_informa)", tweetUrl, profileImageUrl) - .setDescription(twitterMessage) - .setColor(new Color(244, 131, 37)) - .setFooter("Ricevuto da Twitter", "https://i.imgur.com/vkm6lHX.png"); - - if (mediaUrl != null) { - messageEmbed.setImage(mediaUrl); - } - - ArrayList channelList = PostgreSQLInterface.getATMAlertChannel(); - for (ServerToChannel item : channelList) { - jda.getGuildById(item.getServerID()).getTextChannelById(item.getChannelID()).sendMessage(messageEmbed.build()).queue(); - } - } - } -} diff --git a/src/main/java/interfaces/DiscordScheduler.java b/src/main/java/interfaces/DiscordScheduler.java deleted file mode 100644 index 11365af..0000000 --- a/src/main/java/interfaces/DiscordScheduler.java +++ /dev/null @@ -1,50 +0,0 @@ -package interfaces; - -import command.real.BDO.RSS.BDORSScheduler; -import command.real.BDO.boss.BossJob; -import command.real.tpl.atmAlert.AtmScheduler; -import net.dv8tion.jda.core.JDA; -import org.quartz.*; -import org.quartz.impl.StdSchedulerFactory; - -import java.util.Timer; - -import static org.quartz.CronScheduleBuilder.cronSchedule; -import static org.quartz.JobBuilder.newJob; -import static org.quartz.TriggerBuilder.newTrigger; - -public class DiscordScheduler { - - public static void startScheduling(JDA jda) { - -// TASK BDO PATCH AND NEWS - Timer timerTaskBDO = new Timer(); - timerTaskBDO.scheduleAtFixedRate(BDORSScheduler.taskFeedRSSBDO(jda), 1800000, 1800000); - -// TASK BOSS BDO - try { - SchedulerFactory sf = new StdSchedulerFactory(); - Scheduler scheduler = sf.getScheduler(); - JobDetail job = newJob(BossJob - .class) - .withIdentity("bossJob", "group1") - .build(); - - CronTrigger trigger = newTrigger() - .withIdentity("BossCronTrigger", "group1") - .withSchedule(cronSchedule("0 0/5 * 1/1 * ? *")) - .build(); - - scheduler.scheduleJob(job, trigger); - scheduler.start(); - } catch (SchedulerException ex) { - ex.printStackTrace(); - } - -// TASK ATM - AtmScheduler.startAtmTweetScheduler(); - Timer timerTaskAtm = new Timer(); - timerTaskAtm.scheduleAtFixedRate(AtmScheduler.taskFeedRSSATM(), 1800000, 1800000); - - } -} diff --git a/src/main/java/interfaces/DiscordTokenInterfaces.java b/src/main/java/interfaces/DiscordTokenInterfaces.java deleted file mode 100644 index 4298a60..0000000 --- a/src/main/java/interfaces/DiscordTokenInterfaces.java +++ /dev/null @@ -1,42 +0,0 @@ -package interfaces; - -import java.io.*; - - -/** - * Classe per caricare il token di discord da file - */ -public class DiscordTokenInterfaces { - - public static String getToken() { - - if (new File("tokenDiscord.txt").exists()) { - File file = new File("tokenDiscord.txt"); - - try { - BufferedReader reader = new BufferedReader(new FileReader(file)); - String token = reader.readLine(); - reader.close(); - - return token; - - } catch (IOException e) { - e.printStackTrace(); - } - }else { - - File file= new File("tokenDiscord.txt"); - try { - System.out.println("SuccessCreate: "+ file.createNewFile()); - FileWriter stream = new FileWriter(file); - stream.write(""); - stream.close(); - System.out.println("Inserire il token di discord nel file che trovi nella seguente cartella: \n" + file.getAbsolutePath()); - - } catch (IOException e) { - - } - } - return null; - } -} diff --git a/src/main/java/interfaces/PostgreSQLInterface.java b/src/main/java/interfaces/PostgreSQLInterface.java deleted file mode 100644 index a0c609e..0000000 --- a/src/main/java/interfaces/PostgreSQLInterface.java +++ /dev/null @@ -1,474 +0,0 @@ -package interfaces; - -import beans.ServerToChannel; -import beans.ServersDiscord; -import org.apache.commons.text.StringEscapeUtils; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.hibernate.cfg.Configuration; -import org.hibernate.query.Query; -import starter.Start; - -import javax.persistence.TypedQuery; -import java.io.File; -import java.util.ArrayList; -import java.util.Iterator; - -public class PostgreSQLInterface { - - private static SessionFactory sessionFactory; - - /** - * Metodo per inizializzare la connessione - */ - public static void initializeDB() { - String fileName = "hibernate.cfg.xml"; - - File file = new File("resources/" + fileName); - - if (!file.exists()) { - //risorsa su IDE - file = new File(PostgreSQLInterface.class.getClassLoader().getResource(fileName).getFile()); - } - - sessionFactory = new Configuration().configure(file).buildSessionFactory(); - - - } - - /** - * Metodo che aggiunge nome e l'id del server che ha aggiunto il bot sul database. - * - * @param nameServer Nome del server - * @param serverID ID del server Discord - */ - public static void newServer(String nameServer, String serverID) { - - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - ServersDiscord serversDiscord = new ServersDiscord(); - serversDiscord.setServerId(serverID); - serversDiscord.setNameServer(nameServer); - serversDiscord.setSimbolCommand("%"); - - - session.save(serversDiscord); - transaction.commit(); - session.close(); - - } - - /** - * Metodo che rimuove la riga del server che ha espulso il bot - * - * @param serverID id del server - */ - public static void deleteServer(String serverID) { - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - ServersDiscord serverDiscord = new ServersDiscord(); - serverDiscord.setServerId(serverID); - - session.delete(serverDiscord); - - transaction.commit(); - session.close(); - } - - public static void updateNameServer(String serverID, String name) { - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - Query query = session.createQuery("UPDATE ServersDiscord set nameServer = :nameServer where serverId = :serverID"); - query.setParameter("serverID", serverID); - query.setParameter("nameServer", name); - - query.executeUpdate(); - - transaction.commit(); - session.close(); - } - - /** - * Metodo che per ottenre il simbolo del server - * - * @param serverID id del server - * @return prefisso per comandi - */ - public static String getSimbol(String serverID) { - - Session session = sessionFactory.openSession(); - Query query = session.createQuery("select simbolCommand from ServersDiscord where serverId = :serverId"); - query.setParameter("serverId", serverID); - String simbol = (String) query.uniqueResult(); - session.close(); - - return simbol; - } - - /** - * Metodo per configurare il simbolo di comando per il server - * - * @param command Simbolo del comando nuovo - * @param serverID ID del server - */ - public static void setSimbol(String command, String serverID) { - - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - Query query = session.createQuery("UPDATE ServersDiscord SET simbolCommand = :simbol WHERE serverId = :serverId"); - - query.setParameter("simbol", StringEscapeUtils.escapeJava(command)); - query.setParameter("serverId", serverID); - query.executeUpdate(); - - transaction.commit(); - session.close(); - } - - /** - * Metodo per settare il canale per le news su BDO - * - * @param serverID id del server - * @param channelID id del canale testuale - */ - public static void setBDONewsChannel(String serverID, String channelID) { - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - Query query = session.createQuery("UPDATE ServersDiscord set bdoNewsIDChannel = :channelId where serverId = :serverId"); - - query.setParameter("channelId", channelID); - query.setParameter("serverId", serverID); - query.executeUpdate(); - - transaction.commit(); - session.close(); - } - - /** - * Metodo per rimuovere il canale per le news su BDO - * - * @param serverID id del server - */ - public static void removeBDONewsChannel(String serverID) { - - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - Query query = session.createQuery("UPDATE ServersDiscord SET bdoNewsIDChannel = NULL WHERE serverId = :serverId"); - - query.setParameter("serverId", serverID); - query.executeUpdate(); - - transaction.commit(); - session.close(); - } - - /** - * Metodo per ottenere tutti i canali registrati alle news di BDO - * - * @return Lista di coppie di serverID e channelID - * @see ServerToChannel ServerToChannel - */ - - public static ArrayList getBDONewsChannel() { - - Session session = sessionFactory.openSession(); - - TypedQuery q = session.createQuery("SELECT new beans.ServerToChannel(serverId, bdoNewsIDChannel) from ServersDiscord where bdoNewsIDChannel is not null ", ServerToChannel.class); - ArrayList serverToChannels = (ArrayList) q.getResultList(); - session.close(); - - return serverToChannels; - } - - /** - * Metodo per settare il canale per le patch di BDO - * - * @param serverID id del server - * @param channelID id del canale testuale - */ - public static void setBDOPatchChannel(String serverID, String channelID) { - - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - Query query = session.createQuery("UPDATE ServersDiscord SET bdoPatchIDChannel = :channelId WHERE serverId = :serverId"); - query.setParameter("serverId", serverID); - query.setParameter("channelId", channelID); - - query.executeUpdate(); - - transaction.commit(); - session.close(); - } - - /** - * Metodo per rimuovere il canale per le patch di BDO - * - * @param serverID id del server - */ - public static void removeBDOPatchChannel(String serverID) { - - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - Query query = session.createQuery("UPDATE ServersDiscord SET bdoPatchIDChannel = NULL WHERE serverId = :serverId"); - query.setParameter("serverId", serverID); - - query.executeUpdate(); - transaction.commit(); - session.close(); - } - - /** - * Metodo per settare il canale per i boss alert di BDO - * - * @param serverID id del server - * @param channelID id del canale testuale - */ - - public static void setBDOBossChannel(String serverID, String channelID) { - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - - Query query = session.createQuery("UPDATE ServersDiscord set bdoBossIDChannel = :channelID WHERE serverId = :serverId"); - query.setParameter("serverId", serverID); - query.setParameter("channelID", channelID); - - query.executeUpdate(); - transaction.commit(); - session.close(); - } - - /** - * Metodo per rimuovere il canale per i boss alert di BDO - * - * @param serverID id del server - */ - public static void removeBDOBossChannel(String serverID) { - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - Query query = session.createQuery("UPDATE ServersDiscord SET bdoBossIDChannel = NULL where serverId = :serverId"); - query.setParameter("serverId", serverID); - - query.executeUpdate(); - - transaction.commit(); - session.close(); - } - - - /** - * Metodo per ottenere tutti i canali registrati agli alert dei boss di BDO - * - * @return Lista di coppie di serverID e channelID - * @see ServerToChannel ServerToChannel - */ - - public static ArrayList getBDOBossChannel() { - - Session session = sessionFactory.openSession(); - - TypedQuery query = session.createQuery("SELECT new beans.ServerToChannel(serverId, bdoBossIDChannel) from ServersDiscord where bdoBossIDChannel is not null ", ServerToChannel.class); - - ArrayList list = (ArrayList) query.getResultList(); - - session.close(); - return list; - } - - /** - * Metodo per ottenere tutti i canali registrati alle patch di BDO - * - * @return lista dei server e dei relativi canali che si sono registrati - * @see ServerToChannel ServerToChannel - */ - public static ArrayList getBDOPatchChannel() { - - Session session = sessionFactory.openSession(); - - TypedQuery query = session.createQuery("SELECT new beans.ServerToChannel(serverId, bdoPatchIDChannel) from ServersDiscord where bdoPatchIDChannel is not null ", ServerToChannel.class); - ArrayList list = (ArrayList) query.getResultList(); - - return list; - } - - /** - * Ottiene la lista delle ultime notizie di BDO - * - * @return ArrayList lista delle ultime notizie - */ - public static ArrayList getListNewsBDO() { - - Session session = sessionFactory.openSession(); - Query query = session.createQuery("select lastNewsBDO from Rsslink where id = 1"); - - ArrayList list = Start.gson.fromJson((String) query.uniqueResult(), ArrayList.class); - session.close(); - - return list; - } - - /** - * Imposta la lista delle ultime notizie di bdo - * - * @param newsBDOList Lista delle ultime notizie di BDO - */ - public static void setNewsBDO(ArrayList newsBDOList) { - - if (newsBDOList.size() > 15) { - Iterator iteratorList = newsBDOList.iterator(); - int cont = 0; - while (iteratorList.hasNext()) { - iteratorList.next(); - iteratorList.remove(); - if (cont == 7) { - break; - } - cont++; - } - } - String json = Start.gson.toJson(newsBDOList); - - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - Query query = session.createQuery("UPDATE Rsslink set lastNewsBDO = :json where id = 1"); - query.setParameter("json", json); - - query.executeUpdate(); - transaction.commit(); - session.close(); - } - - /** - * Ottiene il link dell'ultima patch di BDO - * - * @return String link url dell'ultima patch - */ - public static String getLastPatchBDO() { - Session session = sessionFactory.openSession(); - Query query = session.createQuery("SELECT lastPatchBDO from Rsslink WHERE id = 1"); - - String lastPatch = (String) query.uniqueResult(); - session.close(); - - return lastPatch; - } - - /** - * Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga. - * - * @param url url dell'ultimo feed rss aggiornato - */ - public static void setLastPatchBDO(String url) { - - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - Query query = session.createQuery("UPDATE Rsslink set lastPatchBDO = :url where id = 1"); - - query.setParameter("url", url); - query.executeUpdate(); - - transaction.commit(); - session.close(); - } - - /** - * Metodo per settare il canale per gli alert dell'ATM - * - * @param serverID id del server - * @param channelID id del canale testuale - */ - public static void setATMAlertChannel(String serverID, String channelID) { - - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - Query query = session.createQuery("UPDATE ServersDiscord set atmAlertIDChannel = :channelID where serverId = :serverID"); - query.setParameter("channelID", channelID); - query.setParameter("serverID", serverID); - - query.executeUpdate(); - - transaction.commit(); - session.close(); - } - - /** - * Metodo per ottenere tutti i canali registrati agli alert di ATM - * - * @return lista dei server e dei relativi canali che si sono registrati - * @see ServerToChannel ServerToChannel - */ - public static ArrayList getATMAlertChannel() { - - Session session = sessionFactory.openSession(); - - TypedQuery query = session.createQuery("SELECT new beans.ServerToChannel(serverId, atmAlertIDChannel) from ServersDiscord where atmAlertIDChannel is not null ", ServerToChannel.class); - ArrayList list = (ArrayList) query.getResultList(); - - session.close(); - return list; - } - - /** - * Metodo per rimuovere il canale per gli alert di ATM - * - * @param serverID id del server - */ - public static void removeATMAlertChannel(String serverID) { - - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - Query query = session.createQuery("UPDATE ServersDiscord set atmAlertIDChannel = null where serverId = :serverID"); - query.setParameter("serverID", serverID); - - query.executeUpdate(); - transaction.commit(); - session.close(); - } - - /** - * Ottiene il link dell'ultimo alert di atm - * - * @return String link url dell'ultimo alert di atm - */ - public static String getLastATMAlert() { - - Session session = sessionFactory.openSession(); - - Query query = session.createQuery("SELECT lastAtmAlert from Rsslink where id= 1"); - String url = (String) query.uniqueResult(); - - session.close(); - return url; - } - - /** - * Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga. - * - * @param url url dell'ultimo feed rss aggiornato - */ - public static void setLastATMAlert(String url) { - - Session session = sessionFactory.openSession(); - Transaction transaction = session.beginTransaction(); - - Query query = session.createQuery("UPDATE Rsslink set lastAtmAlert = :url where id = 1"); - query.setParameter("url", url); - query.executeUpdate(); - - transaction.commit(); - session.close(); - } - - -} diff --git a/src/main/java/interfaces/PropertyInterfaces.java b/src/main/java/interfaces/PropertyInterfaces.java deleted file mode 100644 index 78a4ce4..0000000 --- a/src/main/java/interfaces/PropertyInterfaces.java +++ /dev/null @@ -1,37 +0,0 @@ -package interfaces; - - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -public class PropertyInterfaces { - - public static void getProp() { - Properties prop = new Properties(); - InputStream input = null; - - try { - - input = new FileInputStream("config.properties"); - - // load a properties file - prop.load(input); - - // get the property value and print it out - System.out.println(prop.getProperty("database")); - - } catch (IOException ex) { - ex.printStackTrace(); - } finally { - if (input != null) { - try { - input.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } -} diff --git a/src/main/java/interfaces/SQLiteInterfaces.java b/src/main/java/interfaces/SQLiteInterfaces.java deleted file mode 100644 index 48d8026..0000000 --- a/src/main/java/interfaces/SQLiteInterfaces.java +++ /dev/null @@ -1,563 +0,0 @@ -package interfaces; - -import beans.ServerToChannel; -import org.apache.commons.text.StringEscapeUtils; -import starter.Start; - -import java.sql.*; -import java.util.ArrayList; -import java.util.Iterator; - -@Deprecated -public class SQLiteInterfaces { - - private static final String SERVERS_DISCORD = "ServersDiscord"; - private static final String RSS_LINK = "RSSLink"; - private static Connection connection; - - /** - * Metodo per inizializzare la connessione e/o il DB + la tabella - *

- * PS: In caso sia il primo avvio del bot, accendere, spegnere e successivamente riaccendere il bot - */ - public static void initializeDB() { - try { - Class.forName("org.sqlite.JDBC"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - - try { - connection = DriverManager.getConnection("jdbc:sqlite:databaseDiscord.db"); - if (connection != null) { - connection.getMetaData(); - connection.close(); - connection = DriverManager.getConnection("jdbc:sqlite:databaseDiscord.db"); - } - - String sql = "SELECT name FROM sqlite_master WHERE type='table' AND name='" + SERVERS_DISCORD + "';"; - Statement statement = connection.createStatement(); - ResultSet resultSet = statement.executeQuery(sql); - if (!resultSet.next()) { - sql = "CREATE TABLE " + SERVERS_DISCORD + - "(" + SD_DB_COLUMN.SERVER_ID.name() + " VARCHAR(255) NOT NULL PRIMARY KEY, " + - SD_DB_COLUMN.NAME_SERVER.name() + " TEXT NOT NULL, " + - SD_DB_COLUMN.SIMBOL_COMMAND.name() + " VARCHAR(5) DEFAULT \"%\" NOT NULL," + - SD_DB_COLUMN.BDONewsIDChannel + " VARCHAR(255)," + - SD_DB_COLUMN.BDOPatchIDChannel + " VARCHAR(255)," + - SD_DB_COLUMN.BDOBossIDChannel + " VARCHAR(255))"; - statement.execute(sql); - - sql = "CREATE TABLE " + RSS_LINK + - "(" + RSS_DB_COLUMN.ID.name() + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " + - RSS_DB_COLUMN.LastNewsBDO.name() + " TEXT default NULL, " + - RSS_DB_COLUMN.LastPatchBDO.name() + " TEXT default NULL )"; -// CREATE TABLE RSSLink ( LastNewsBDO TEXT default NULL, LastPatchBDO TEXT default null, ID INTEGER constraint RSSLink_pk primary key autoincrement ) - - statement.execute(sql); - - sql = "INSERT INTO RSSLink DEFAULT VALUES"; - statement.execute(sql); - statement.close(); - } - - } catch (SQLException e) { - e.printStackTrace(); - } - - } - - /** - * Metodo che aggiunge nome e l'id del server che ha aggiunto il bot sul database. - * - * @param nameServe Nome del server - * @param serverID ID del server Discord - */ - public static void newServer(String nameServe, String serverID) { - - String sql = "INSERT INTO " + SERVERS_DISCORD + "(" + - SD_DB_COLUMN.NAME_SERVER.name() + "," + SD_DB_COLUMN.SERVER_ID.name() + ")" + - "VALUES(\"" + nameServe + "\", \"" + serverID + "\");"; - - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - /** - * Metodo che rimuove la riga del server che ha espulso il bot - * - * @param serverID id del server - */ - public static void deleteServer(String serverID) { - String sql = "DELETE FROM " + SERVERS_DISCORD + " WHERE " + SD_DB_COLUMN.SERVER_ID.name() + "='" + serverID + "';"; - - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - statement.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - } - - /** - * Metodo che per ottenre il simbolo del server - * - * @param serverID id del server - * @return prefisso per comandi - */ - public static String getSimbol(String serverID) { - String sql = "SELECT " + SD_DB_COLUMN.SIMBOL_COMMAND.name() + " FROM " + SERVERS_DISCORD + " WHERE " + SD_DB_COLUMN.SERVER_ID.name() + " = '" + serverID + "';"; - try { - Statement statement = connection.createStatement(); - ResultSet resultSet = statement.executeQuery(sql); - - if (resultSet.next()) { - return StringEscapeUtils.unescapeJava(resultSet.getString("SIMBOL_COMMAND")); - } - } catch (SQLException e) { - e.printStackTrace(); - } - return ""; - } - - /** - * Metodo per configurare il simbolo di comando per il server - * - * @param command Simbolo del comando nuovo - * @param serverID ID del server - */ - public static void setSimbol(String command, String serverID) { - String sql = "UPDATE " + SERVERS_DISCORD + " SET " + SD_DB_COLUMN.SIMBOL_COMMAND.name() + "= '" + command + "' " + - "WHERE " + SD_DB_COLUMN.SERVER_ID.name() + "='" + serverID + "';"; - sql = StringEscapeUtils.escapeJava(sql); - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - /** - * Metodo per settare il canale per le news su BDO - * - * @param serverID id del server - * @param channelID id del canale testuale - */ - public static void setBDONewsChannel(String serverID, String channelID) { - String sql = "UPDATE " + SERVERS_DISCORD + " SET " + SD_DB_COLUMN.BDONewsIDChannel.name() + "= '" + channelID + "' WHERE " + SD_DB_COLUMN.SERVER_ID.name() + "='" + serverID + "';"; - - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - /** - * Metodo per rimuovere il canale per le news su BDO - * - * @param serverID id del server - */ - public static void removeBDONewsChannel(String serverID) { - String sql = "UPDATE " + SERVERS_DISCORD + " SET " + SD_DB_COLUMN.BDONewsIDChannel.name() + "= NULL WHERE " + SD_DB_COLUMN.SERVER_ID.name() + "='" + serverID + "';"; - - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } - - } - - /** - * Metodo per ottenere tutti i canali registrati alle news di BDO - * - * @return Lista di coppie di serverID e channelID - * @see beans.ServerToChannel ServerToChannel - */ - public static ArrayList getBDONewsChannel() { - String sql = "SELECT " + SD_DB_COLUMN.SERVER_ID.name() + ", " + SD_DB_COLUMN.BDONewsIDChannel.name() + " FROM " + SERVERS_DISCORD + " WHERE " + SD_DB_COLUMN.BDONewsIDChannel.name() + " IS NOT NULL"; - ArrayList list = new ArrayList<>(); - - try { - Statement statement = connection.createStatement(); - ResultSet resutlt = statement.executeQuery(sql); - - while (resutlt.next()) { - list.add(new ServerToChannel(resutlt.getString(SD_DB_COLUMN.SERVER_ID.name()), resutlt.getString(SD_DB_COLUMN.BDONewsIDChannel.name()))); - } - } catch (SQLException e) { - e.printStackTrace(); - } - - return list; - - } - - /** - * Metodo per settare il canale per le patch di BDO - * - * @param serverID id del server - * @param channelID id del canale testuale - */ - public static void setBDOPatchChannel(String serverID, String channelID) { - String sql = "UPDATE " + SERVERS_DISCORD + " SET " + SD_DB_COLUMN.BDOPatchIDChannel.name() + "= '" + channelID + "' WHERE " + SD_DB_COLUMN.SERVER_ID.name() + "='" + serverID + "';"; - - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - /** - * Metodo per rimuovere il canale per le patch di BDO - * - * @param serverID id del server - */ - public static void removeBDOPatchChannel(String serverID) { - String sql = "UPDATE " + SERVERS_DISCORD + " SET " + SD_DB_COLUMN.BDOPatchIDChannel.name() + "= NULL WHERE " + SD_DB_COLUMN.SERVER_ID.name() + "='" + serverID + "';"; - - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - /** - * Metodo per settare il canale per i boss alert di BDO - * - * @param serverID id del server - * @param channelID id del canale testuale - */ - public static void setBDOBossChannel(String serverID, String channelID) { - String sql = "UPDATE " + SERVERS_DISCORD + " SET " + SD_DB_COLUMN.BDOBossIDChannel.name() + "= '" + channelID + "' WHERE " + SD_DB_COLUMN.SERVER_ID.name() + "='" + serverID + "';"; - - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - /** - * Metodo per rimuovere il canale per i boss alert di BDO - * - * @param serverID id del server - */ - public static void removeBDOBossChannel(String serverID) { - String sql = "UPDATE " + SERVERS_DISCORD + " SET " + SD_DB_COLUMN.BDOBossIDChannel.name() + "= NULL WHERE " + SD_DB_COLUMN.SERVER_ID.name() + "='" + serverID + "';"; - - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - public static ArrayList getBDOBossChannel() { - String sql = "SELECT " + SD_DB_COLUMN.SERVER_ID.name() + ", " + SD_DB_COLUMN.BDOBossIDChannel.name() + " FROM " + SERVERS_DISCORD + " WHERE " + SD_DB_COLUMN.BDOBossIDChannel.name() + " IS NOT NULL"; - ArrayList list = new ArrayList<>(); - - try { - Statement statement = connection.createStatement(); - ResultSet resutlt = statement.executeQuery(sql); - - while (resutlt.next()) { - list.add(new ServerToChannel(resutlt.getString(SD_DB_COLUMN.SERVER_ID.name()), resutlt.getString(SD_DB_COLUMN.BDOBossIDChannel.name()))); - } - } catch (SQLException e) { - e.printStackTrace(); - } - - return list; - - } - - /** - * Metodo per ottenere tutti i canali registrati alle patch di BDO - * - * @return lista dei server e dei relativi canali che si sono registrati - * @see ServerToChannel ServerToChannel - */ - public static ArrayList getBDOPatchChannel() { - String sql = "SELECT " + SD_DB_COLUMN.SERVER_ID.name() + ", " + SD_DB_COLUMN.BDOPatchIDChannel.name() + " FROM " + SERVERS_DISCORD + " WHERE " + SD_DB_COLUMN.BDOPatchIDChannel.name() + " IS NOT NULL"; - ArrayList list = new ArrayList<>(); - - try { - Statement statement = connection.createStatement(); - ResultSet resutlt = statement.executeQuery(sql); - - while (resutlt.next()) { - list.add(new ServerToChannel(resutlt.getString(SD_DB_COLUMN.SERVER_ID.name()), resutlt.getString(SD_DB_COLUMN.BDOPatchIDChannel.name()))); - } - } catch (SQLException e) { - e.printStackTrace(); - } - - return list; - - } - - /** - * Ottiene la lista delle ultime notizie di BDO - * - * @return ArrayList lista delle ultime notizie - */ - public static ArrayList getListNewsBDO() { - String sql = "SELECT " + RSS_DB_COLUMN.LastNewsBDO.name() + " FROM " + RSS_LINK + ";"; - - try { - Statement statement = connection.createStatement(); - ResultSet result = statement.executeQuery(sql); - - if (result.next()) { - return Start.gson.fromJson(result.getString(RSS_DB_COLUMN.LastNewsBDO.name()), ArrayList.class); - } else { - return null; - } - - } catch (SQLException e) { - e.printStackTrace(); - } - return null; - } - - /** - * Imposta la lista delle ultime notizie di bdo - * - * @param newsBDOList Lista delle ultime notizie di BDO - */ - public static void setNewsBDO(ArrayList newsBDOList) { - - if (newsBDOList.size() > 10) { - Iterator iteratorList = newsBDOList.iterator(); - int cont = 0; - while (iteratorList.hasNext()) { - iteratorList.next(); - iteratorList.remove(); - if (cont == 7) { - break; - } - cont++; - } - } - - String json = Start.gson.toJson(newsBDOList); - - PreparedStatement statement = null; - try { - statement = connection.prepareStatement("UPDATE " + RSS_LINK + " SET " + RSS_DB_COLUMN.LastNewsBDO.name() + " = ? WHERE " + RSS_DB_COLUMN.ID.name() + " = 1"); - statement.setString(1, json); - statement.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); - } finally { - try { - statement.close(); - } catch (SQLException e) { - TakaoLog.logError(e.getMessage()); - } - } - } - - /** - * Ottiene il link dell'ultima patch di BDO - * - * @return String link url dell'ultima patch - */ - public static String getLastPatchBDO() { - String sql = "SELECT " + RSS_DB_COLUMN.LastPatchBDO.name() + " FROM " + RSS_LINK + ";"; - - try { - Statement statement = connection.createStatement(); - ResultSet result = statement.executeQuery(sql); - - //false è vuoto - //true trovato - if (result.next()) { - return result.getString(RSS_DB_COLUMN.LastPatchBDO.name()); - } else { - return null; - } - - } catch (SQLException e) { - e.printStackTrace(); - } - return null; - } - - /** - * Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga. - * - * @param url url dell'ultimo feed rss aggiornato - */ - public static void setLastPatchBDO(String url) { - - String sql = "UPDATE " + RSS_LINK + " SET " + RSS_DB_COLUMN.LastPatchBDO.name() + " = '" + url + "' WHERE " + RSS_DB_COLUMN.ID.name() + " = 1;"; - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } - - } - - /** - * Metodo per settare il canale per gli alert dell'ATM - * - * @param serverID id del server - * @param channelID id del canale testuale - */ - public static void setATMAlertChannel(String serverID, String channelID) { - String sql = "UPDATE " + SERVERS_DISCORD + " SET " + SD_DB_COLUMN.ATMAlertIDChannel.name() + "= '" + channelID + "' WHERE " + SD_DB_COLUMN.SERVER_ID.name() + "='" + serverID + "';"; - - try { - Statement statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - /** - * Metodo per ottenere tutti i canali registrati agli alert di ATM - * - * @return lista dei server e dei relativi canali che si sono registrati - * @see ServerToChannel ServerToChannel - */ - public static ArrayList getATMAlertChannel() { - String sql = "SELECT " + SD_DB_COLUMN.SERVER_ID.name() + ", " + SD_DB_COLUMN.ATMAlertIDChannel.name() + " FROM " + SERVERS_DISCORD + " WHERE " + SD_DB_COLUMN.ATMAlertIDChannel.name() + " IS NOT NULL"; - ArrayList list = new ArrayList<>(); - - Statement statement = null; - ResultSet resutlt = null; - try { - statement = connection.createStatement(); - resutlt = statement.executeQuery(sql); - - while (resutlt.next()) { - list.add(new ServerToChannel(resutlt.getString(SD_DB_COLUMN.SERVER_ID.name()), resutlt.getString(SD_DB_COLUMN.ATMAlertIDChannel.name()))); - } - } catch (SQLException e) { - e.printStackTrace(); - } finally { - try { - statement.close(); - } catch (SQLException e) {} - - try { - resutlt.close(); - } catch (SQLException e) {} - } - - return list; - - } - - /** - * Metodo per rimuovere il canale per gli alert di ATM - * - * @param serverID id del server - */ - public static void removeATMAlertChannel(String serverID) { - String sql = "UPDATE " + SERVERS_DISCORD + " SET " + SD_DB_COLUMN.ATMAlertIDChannel.name() + "= NULL WHERE " + SD_DB_COLUMN.SERVER_ID.name() + "='" + serverID + "';"; - - Statement statement = null; - try { - statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } finally { - try { - statement.close(); - } catch (SQLException e) {} - } - } - - /** - * Ottiene il link dell'ultima patch di BDO - * - * @return String link url dell'ultima patch - */ - public static String getLastATMAlert() { - String sql = "SELECT " + RSS_DB_COLUMN.LastATMAlert.name() + " FROM " + RSS_LINK + ";"; - - try { - Statement statement = connection.createStatement(); - ResultSet result = statement.executeQuery(sql); - - //false è vuoto - //true trovato - if (result.next()) { - return result.getString(RSS_DB_COLUMN.LastATMAlert.name()); - } else { - return null; - } - - } catch (SQLException e) { - e.printStackTrace(); - } - return null; - } - - /** - * Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga. - * - * @param url url dell'ultimo feed rss aggiornato - */ - public static void setLastATMAlert(String url) { - - String sql = "UPDATE " + RSS_LINK + " SET " + RSS_DB_COLUMN.LastATMAlert.name() + " = '" + url + "' WHERE " + RSS_DB_COLUMN.ID.name() + " = 1;"; - Statement statement = null; - try { - statement = connection.createStatement(); - statement.executeUpdate(sql); - } catch (SQLException e) { - e.printStackTrace(); - } finally { - try { - statement.close(); - } catch (SQLException e) {} - } - - } - - /** - * Nomi delle colonne sul db - */ - public enum SD_DB_COLUMN { - NAME_SERVER, - SERVER_ID, - SIMBOL_COMMAND, - BDONewsIDChannel, - BDOPatchIDChannel, - BDOBossIDChannel, - ATMAlertIDChannel - } - - public enum RSS_DB_COLUMN { - ID, - LastNewsBDO, - LastPatchBDO, - LastATMAlert - } - - -} diff --git a/src/main/java/interfaces/TakaoLog.java b/src/main/java/interfaces/TakaoLog.java deleted file mode 100644 index f082684..0000000 --- a/src/main/java/interfaces/TakaoLog.java +++ /dev/null @@ -1,21 +0,0 @@ -package interfaces; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import starter.Start; - -public class TakaoLog { - private static Logger logger = LoggerFactory.getLogger(Start.class); - - public static void logInfo(String message) { - logger.info(message); - } - - public static void logDebug(String message) { - logger.debug(message); - } - - public static void logError(String message) { - logger.error(message); - } -} diff --git a/src/main/java/interfaces/TwitterManager.java b/src/main/java/interfaces/TwitterManager.java deleted file mode 100644 index 72d8d56..0000000 --- a/src/main/java/interfaces/TwitterManager.java +++ /dev/null @@ -1,74 +0,0 @@ -package interfaces; - -import command.real.tpl.atmAlert.AtmScheduler; -import twitter4j.FilterQuery; -import twitter4j.StatusListener; -import twitter4j.TwitterStream; -import twitter4j.TwitterStreamFactory; -import twitter4j.conf.ConfigurationBuilder; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.Properties; - -public class TwitterManager { - - private TwitterStreamFactory twitterStreamFactory = null; - private TwitterStream twitterStream = null; - - public TwitterManager getTwitterManagerWithStream() { - if (twitterStreamFactory == null) { - - String fileName = "twitter4j.properties"; - - File file = new File("resources/" + fileName); - - if (!file.exists()) { - //risorsa su IDE - file = new File(AtmScheduler.class.getClassLoader().getResource("twitter4j.properties").getFile()); - } - - - FileInputStream input = null; - try { - input = new FileInputStream(file); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - Properties prop = new Properties(); - try { - prop.load(input); - } catch (IOException e) { - e.printStackTrace(); - } - - ConfigurationBuilder cb = new ConfigurationBuilder(); - cb.setDebugEnabled(true) - .setOAuthConsumerKey(prop.getProperty("oauth.consumerKey")) - .setOAuthConsumerSecret(prop.getProperty("oauth.consumerSecret")) - .setOAuthAccessToken(prop.getProperty("oauth.accessToken")) - .setOAuthAccessTokenSecret(prop.getProperty("oauth.accessTokenSecret")); - this.twitterStreamFactory = new TwitterStreamFactory(cb.build()); - this.twitterStream = twitterStreamFactory.getInstance(); - } - return this; - } - - public TwitterManager setTwitterStreamListener(StatusListener listener) { - twitterStream.addListener(listener); - return this; - } - - public TwitterManager setTwitterStreamFilter(FilterQuery filterQuery) { - twitterStream.filter(filterQuery); - return this; - } - - public TwitterStream getTwitterStream() { - return twitterStream; - } -} diff --git a/src/main/java/starter/Start.java b/src/main/java/starter/Start.java deleted file mode 100644 index 0282c34..0000000 --- a/src/main/java/starter/Start.java +++ /dev/null @@ -1,59 +0,0 @@ -package starter; - -import com.google.gson.Gson; -import command.real.BDO.BDOReceiver; -import command.real.JoinListener; -import command.real.configuration.ConfigurationReceiver; -import command.real.sound.PlayerControlCommand; -import command.real.tpl.atmAlert.ATMAlertReceiver; -import interfaces.DiscordScheduler; -import interfaces.DiscordTokenInterfaces; -import interfaces.PostgreSQLInterface; -import interfaces.TakaoLog; -import net.dv8tion.jda.core.JDA; -import net.dv8tion.jda.core.JDABuilder; -import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import javax.security.auth.login.LoginException; - -public class Start { - - public static Gson gson = new Gson(); - public static JDA jda = null; - - public static void main(String[] args) { - - PostgreSQLInterface.initializeDB(); - - try { - jda = new JDABuilder(DiscordTokenInterfaces.getToken()).build(); - } catch (LoginException e) { - TakaoLog.logError(e.getMessage()); - return; - } - - DiscordScheduler.startScheduling(jda); - - jda.addEventListener(new JoinListener()); - jda.addEventListener(new ListenerAdapter() { - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (!event.getAuthor().isBot()) { - System.out.println("Comando inviato da server: " + event.getGuild().getName()); - System.out.println("Inviato da: " + event.getAuthor().getName() + "#" + event.getAuthor().getDiscriminator()); - } - } - }); - - //comandi reali - jda.addEventListener(new ConfigurationReceiver()); - jda.addEventListener(new BDOReceiver()); - jda.addEventListener(new PlayerControlCommand()); - jda.addEventListener(new ATMAlertReceiver()); - - System.out.println(jda.asBot().getInviteUrl(Permission.ADMINISTRATOR)); - - } -} diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/StartBot.kt b/src/main/kotlin/it/discordbot/StartBot.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/StartBot.kt rename to src/main/kotlin/it/discordbot/StartBot.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/TestCommand.kt b/src/main/kotlin/it/discordbot/TestCommand.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/TestCommand.kt rename to src/main/kotlin/it/discordbot/TestCommand.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSLink.kt b/src/main/kotlin/it/discordbot/beans/RSSLink.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSLink.kt rename to src/main/kotlin/it/discordbot/beans/RSSLink.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSMessage.kt b/src/main/kotlin/it/discordbot/beans/RSSMessage.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/RSSMessage.kt rename to src/main/kotlin/it/discordbot/beans/RSSMessage.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt b/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt rename to src/main/kotlin/it/discordbot/beans/ServerDiscord.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt b/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt rename to src/main/kotlin/it/discordbot/beans/ServerToChannel.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Boss.kt b/src/main/kotlin/it/discordbot/beans/boss/Boss.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Boss.kt rename to src/main/kotlin/it/discordbot/beans/boss/Boss.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt b/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt rename to src/main/kotlin/it/discordbot/beans/boss/Giorno.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt b/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt rename to src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt rename to src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt rename to src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt rename to src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt b/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt rename to src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt b/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt rename to src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/ControlCommand.kt b/src/main/kotlin/it/discordbot/command/ControlCommand.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/ControlCommand.kt rename to src/main/kotlin/it/discordbot/command/ControlCommand.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt rename to src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt b/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt rename to src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt b/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt similarity index 94% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt rename to src/main/kotlin/it/discordbot/command/music/MusicCommand.kt index 068f4c1..2de1292 100644 --- a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt +++ b/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt @@ -34,6 +34,10 @@ class MusicCommand : ListenerAdapter() { || checkCommand(event, symbolCommand, "pp")) { musicManager.playPlaylist(event) + } else if (checkCommand(event, symbolCommand, "skip") || + checkCommand(event, symbolCommand, "salta")) { + musicManager.skip(event) + } else if (checkCommand(event, symbolCommand, "pausa") || checkCommand(event, symbolCommand, "pause") || checkCommand(event, symbolCommand, "resume") || diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt b/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt rename to src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt b/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt rename to src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt b/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt rename to src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt b/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt rename to src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt rename to src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt rename to src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt rename to src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt rename to src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/JDAController.kt b/src/main/kotlin/it/discordbot/core/JDAController.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/JDAController.kt rename to src/main/kotlin/it/discordbot/core/JDAController.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TakaoLog.kt b/src/main/kotlin/it/discordbot/core/TakaoLog.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TakaoLog.kt rename to src/main/kotlin/it/discordbot/core/TakaoLog.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TwitterManager.kt b/src/main/kotlin/it/discordbot/core/TwitterManager.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/core/TwitterManager.kt rename to src/main/kotlin/it/discordbot/core/TwitterManager.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt b/src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt rename to src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt b/src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt rename to src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt b/src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt rename to src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt b/src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt rename to src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt b/src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt rename to src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt b/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt rename to src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt diff --git a/SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt b/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt similarity index 100% rename from SpringBootTakaoBot/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt rename to src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt diff --git a/src/main/main.iml b/src/main/main.iml deleted file mode 100644 index 4f2a68c..0000000 --- a/src/main/main.iml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SpringBootTakaoBot/src/main/resources/application.properties b/src/main/resources/application.properties similarity index 93% rename from SpringBootTakaoBot/src/main/resources/application.properties rename to src/main/resources/application.properties index 1075f20..b4ad69e 100644 --- a/SpringBootTakaoBot/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,7 +1,7 @@ ############################################## ###### SPRING BOOT CONFIGURATION PROPERTIES ############ ############################################## -spring.profiles.active=dev +spring.profiles.active=dev #prod logging.level.root=INFO logging.level.org.springframework.web=DEBUG diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml deleted file mode 100644 index b9cfd81..0000000 --- a/src/main/resources/logback.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - - 1000 - - - - takaoLog/${fileName}-${byDay}.log - - %d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - takaoLog/jcg.%i.log.zip - 1 - 10 - - - - 20MB - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/java/testing/PrivateMessage.java b/src/test/java/testing/PrivateMessage.java deleted file mode 100644 index 8d88869..0000000 --- a/src/test/java/testing/PrivateMessage.java +++ /dev/null @@ -1,38 +0,0 @@ -package testing; - -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.EmbedBuilder; -import net.dv8tion.jda.core.MessageBuilder; -import net.dv8tion.jda.core.entities.Message; -import net.dv8tion.jda.core.entities.User; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.awt.*; - -public class PrivateMessage extends ListenerAdapter { - - @Override - public void onMessageReceived(MessageReceivedEvent event) { - Message message = event.getMessage(); - String content = message.getContentRaw(); - if (event.getAuthor().isBot()) return; - - if (ControlCommand.controlCommand(event,"tt")){ - User user = event.getAuthor(); - user.openPrivateChannel().queue((privateChannel -> { - MessageBuilder builder = new MessageBuilder(); - EmbedBuilder embedBuilder = new EmbedBuilder(); - embedBuilder.setColor(Color.MAGENTA) - .setAuthor(user.getName(), null, user.getAvatarUrl()) - .setTitle("Ciao " + event.getAuthor().getName()) - .setDescription("Il tuo simbolo di comando è: " + PostgreSQLInterface.getSimbol(event.getGuild().getId())); - privateChannel.sendMessage(embedBuilder.build()).queue(); - - - })); - event.getMessage().getChannel().deleteMessageById(event.getMessageId()).queue(); - } - } -} diff --git a/src/test/java/testing/StartTest.java b/src/test/java/testing/StartTest.java deleted file mode 100644 index 87a25a0..0000000 --- a/src/test/java/testing/StartTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package testing; - -import com.google.gson.Gson; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.JDA; -import net.dv8tion.jda.core.JDABuilder; -import net.dv8tion.jda.core.Permission; - -import javax.security.auth.login.LoginException; -import java.io.IOException; - -public class StartTest { - - public static Gson gson = new Gson(); - public static JDA jda; - - public static void main(String[] args) throws IOException { - -// SQLiteInterfaces.initializeDB(); - PostgreSQLInterface.initializeDB(); - - try { - jda = new JDABuilder("NTMwMzA1MjEzNDkyNDk0MzM4.D3RW1A.IXqW6JxGvSrBHpstTXuZtVOyCO4").build(); - } catch (LoginException e) { - e.printStackTrace(); - return; - } - -// DiscordScheduler.startScheduling(jda); - - - jda.addEventListener(new TestCommand()); -// jda.addEventListener(new PrivateMessage()); - - System.out.println(jda.asBot().getInviteUrl(Permission.ADMINISTRATOR)); - - } - - public static JDA getJDA() { - return jda; - } - - -} diff --git a/src/test/java/testing/TestCommand.java b/src/test/java/testing/TestCommand.java deleted file mode 100644 index 888b431..0000000 --- a/src/test/java/testing/TestCommand.java +++ /dev/null @@ -1,45 +0,0 @@ -package testing; - -import command.pattern.ControlCommand; -import interfaces.PostgreSQLInterface; -import net.dv8tion.jda.core.EmbedBuilder; -import net.dv8tion.jda.core.events.message.MessageReceivedEvent; -import net.dv8tion.jda.core.hooks.ListenerAdapter; - -import java.awt.*; - -public class TestCommand extends ListenerAdapter { - @Override - public void onMessageReceived(MessageReceivedEvent event) { - if (event.getAuthor().isBot()) return; - // We don't want to respond to other bot accounts, including ourself -// Message message = event.getMessage(); -// String content = message.getContentRaw(); - // getContentRaw() is an atomic getter - // getContentDisplay() is a lazy getter which modifies the content for e.g. console view (strip discord formatting) - /*if (content.equals("!ping")) { - MessageChannel channel = event.getChannel(); - channel.sendMessage("Pong!").queue(); // Important to call .queue() on the RestAction returned by sendMessage(...) - }*/ - - - if (ControlCommand.controlCommand(event, "ping")) { - - EmbedBuilder messageEmbed = new EmbedBuilder(); - - messageEmbed - .setDescription("\n" + - "\n" + - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque hendrerit faucibus lorem, in faucibus elit tempor in. Vestibulum fringilla mi erat, eget fringilla massa mollis sit amet. Fusce aliquam dolor laoreet, congue turpis a, iaculis eros. Donec ullamcorper ultricies justo quis bibendum. Aenean porttitor vehicula nisi quis venenatis. Donec id felis mauris. Mauris rhoncus a mi eget ultrices.\n" + - "\nm eu nisi eu egestas. Nulla tincidunt enim ac eam. Curabitur suscipit magna id turpis porta. ").setColor(new Color(132, 197, 251)) - .setThumbnail(event.getJDA().getSelfUser().getAvatarUrl()); - event.getChannel().sendMessage(messageEmbed.build()).queue(); - - // event.getGuild().getRoles(); -// channel.sendMessage("Pong!").queue(); - - - } - } - -} diff --git a/SpringBootTakaoBot/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt b/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt similarity index 100% rename from SpringBootTakaoBot/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt rename to src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt From 75084e996f5377ddc25a982eaca0d56bc3a4627f Mon Sep 17 00:00:00 2001 From: samuele794 Date: Tue, 14 May 2019 23:23:55 +0200 Subject: [PATCH 03/12] Abbassato il rate di lettura del feedRSS di ATM a 15 minuti --- .../it/discordbot/command/generalCommand/GeneralCommand.kt | 4 ++-- .../it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt index 400e649..8745ff9 100644 --- a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt +++ b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt @@ -76,8 +76,8 @@ class GeneralCommand : ListenerAdapter() { setColor(Color(132, 197, 251)) setDescription("Questi comandi possono essere usati menzionando il bot e scrivendo il comando senza simbolo," + "oppure usando i comandi direttamente come segue:") - addField(symbolCommand + GeneralCommand.INFO_COMMAND, GeneralCommand.INFO_COMMAND_DESCRIPTION, false) - addField(symbolCommand + GeneralCommand.CONFIGURATION_COMMAND, GeneralCommand.CONFIGURATION_COMMAND_DESCRIPTION, false) + addField(symbolCommand + INFO_COMMAND, INFO_COMMAND_DESCRIPTION, false) + addField(symbolCommand + CONFIGURATION_COMMAND, CONFIGURATION_COMMAND_DESCRIPTION, false) addField(symbolCommand + BDOCommand.BDO_NEWS_START_COMMAND, BDOCommand.BDO_NEWS_START_COMMAND_DESCRIPTION, false) addField(symbolCommand + BDOCommand.BDO_NEWS_STOP_COMMAND, BDOCommand.BDO_NEWS_STOP_COMMAND_DESCRIPTION, false) addField(symbolCommand + BDOCommand.BDO_PATCH_START_COMMAND, BDOCommand.BDO_PATCH_START_COMMAND_DESCRIPTION, false) diff --git a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt index 18bac76..fdc009e 100644 --- a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt @@ -22,7 +22,7 @@ class ATMRSSScheduler { @Autowired lateinit var atmInterface: ATMInterface - @Scheduled(fixedRate = 1800000, initialDelay = 1800000) + @Scheduled(fixedRate = 900000, initialDelay = 900000) fun taskFeedRSSATM() { val message = atmrssReader.readRSS(ATM_RSS_LINK) From b1b06d189b95a8a5f6374e135225fb2d12e22f77 Mon Sep 17 00:00:00 2001 From: samuele794 Date: Wed, 15 May 2019 13:57:24 +0200 Subject: [PATCH 04/12] Code Refractor, Fix checkCommand --- .../kotlin/it/discordbot/beans/RSSMessage.kt | 2 +- .../kotlin/it/discordbot/beans/boss/Giorno.kt | 2 +- .../it/discordbot/command/BDO/BDOCommand.kt | 20 +++---- .../command/BDO/RSS/BDONewsRSSScheduler.kt | 33 ++++++----- .../command/BDO/RSS/BDOPatchRSSScheduler.kt | 46 +++++++-------- .../command/BDO/RSS/BDORSSReader.kt | 37 +++++++++++- .../command/BDO/boss/BDOBossScheduler.kt | 2 +- .../discordbot/command/BDO/boss/BossUtil.kt | 4 +- .../it/discordbot/command/ControlCommand.kt | 4 +- .../command/generalCommand/GeneralCommand.kt | 2 +- .../command/generalCommand/JoinListener.kt | 2 +- .../discordbot/command/music/MusicCommand.kt | 2 +- .../music/config/AudioPlayerSendHandler.kt | 2 - .../command/music/config/GuildMusicManager.kt | 3 +- .../command/music/config/MusicManager.kt | 2 +- .../command/music/config/TrackScheduler.kt | 5 +- .../discordbot/command/pattern/RSSReader.kt | 12 ++++ .../command/pattern/RSSScheduler.kt | 12 ++++ .../command/tpl/atmAlert/ATMCommand.kt | 4 +- .../command/tpl/atmAlert/ATMRSSReader.kt | 7 ++- .../command/tpl/atmAlert/ATMRSSScheduler.kt | 33 ++++++----- .../tpl/atmAlert/ATMTwitterScheduler.kt | 56 ++++++++++--------- .../kotlin/it/discordbot/core/TakaoLog.kt | 6 +- .../it/discordbot/core/TwitterManager.kt | 4 +- .../{interfaces => filter}/ATMInterface.kt | 2 +- .../BDOBossInterface.kt | 9 +-- .../BDONewsInterface.kt | 22 ++++---- .../BDOPatchInterface.kt | 25 +++++---- .../ServerManagementInterface.kt | 6 +- .../database/repository/RSSLinkRepository.kt | 2 +- .../repository/ServerDiscordRepository.kt | 3 - 31 files changed, 209 insertions(+), 162 deletions(-) create mode 100644 src/main/kotlin/it/discordbot/command/pattern/RSSReader.kt create mode 100644 src/main/kotlin/it/discordbot/command/pattern/RSSScheduler.kt rename src/main/kotlin/it/discordbot/database/{interfaces => filter}/ATMInterface.kt (97%) rename src/main/kotlin/it/discordbot/database/{interfaces => filter}/BDOBossInterface.kt (87%) rename src/main/kotlin/it/discordbot/database/{interfaces => filter}/BDONewsInterface.kt (69%) rename src/main/kotlin/it/discordbot/database/{interfaces => filter}/BDOPatchInterface.kt (67%) rename src/main/kotlin/it/discordbot/database/{interfaces => filter}/ServerManagementInterface.kt (88%) diff --git a/src/main/kotlin/it/discordbot/beans/RSSMessage.kt b/src/main/kotlin/it/discordbot/beans/RSSMessage.kt index e2e329b..c812fdc 100644 --- a/src/main/kotlin/it/discordbot/beans/RSSMessage.kt +++ b/src/main/kotlin/it/discordbot/beans/RSSMessage.kt @@ -2,4 +2,4 @@ package it.discordbot.beans import org.jsoup.nodes.Document -data class RSSMessage(val title:String,val link:String,val doc: Document) \ No newline at end of file +data class RSSMessage(val title: String, val link: String, val doc: Document) \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt b/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt index 95df846..5858073 100644 --- a/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt +++ b/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt @@ -1,3 +1,3 @@ package it.discordbot.beans.boss - data class Giorno(val giorno: String, val bosses: ArrayList) \ No newline at end of file +data class Giorno(val giorno: String, val bosses: ArrayList) \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt b/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt index 2af0487..5e7643c 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt @@ -3,10 +3,10 @@ package it.discordbot.command.BDO import it.discordbot.command.checkAdminPermission import it.discordbot.command.checkCommand import it.discordbot.command.rejectCommand -import it.discordbot.database.interfaces.BDOBossInterface -import it.discordbot.database.interfaces.BDONewsInterface -import it.discordbot.database.interfaces.BDOPatchInterface -import it.discordbot.database.interfaces.ServerManagementInterface +import it.discordbot.database.filter.BDOBossInterface +import it.discordbot.database.filter.BDONewsInterface +import it.discordbot.database.filter.BDOPatchInterface +import it.discordbot.database.filter.ServerManagementInterface import net.dv8tion.jda.core.MessageBuilder import net.dv8tion.jda.core.events.message.MessageReceivedEvent import net.dv8tion.jda.core.hooks.ListenerAdapter @@ -63,14 +63,14 @@ class BDOCommand : ListenerAdapter() { val symbolCommand = serverManagementInterface.getSimbolCommand(event.guild.id) - if (checkCommand(event, symbolCommand, BDOCommand.BDO_BOSS_START_COMMAND)) { + if (checkCommand(event, symbolCommand, BDO_BOSS_START_COMMAND)) { if (!checkAdminPermission(event)) { rejectCommand(event) } else { bdoBossInterface.setBDOBossChannel(event.guild.id, event.textChannel.id) sendMessageAddChannel(event, "Invio degli allarmi dei boss di BDO configurato sul canale: ") } - } else if (checkCommand(event, symbolCommand, BDOCommand.BDO_BOSS_STOP_COMMAND)) { + } else if (checkCommand(event, symbolCommand, BDO_BOSS_STOP_COMMAND)) { if (!checkAdminPermission(event)) { rejectCommand(event) } else { @@ -78,14 +78,14 @@ class BDOCommand : ListenerAdapter() { if (removedChannelId != null) sendMessageRemoveChannel(event, "Invio degli allarmi dei boss di BDO rimosso dal canale: ", removedChannelId) } - } else if (checkCommand(event, symbolCommand, BDOCommand.BDO_NEWS_START_COMMAND)) { + } else if (checkCommand(event, symbolCommand, BDO_NEWS_START_COMMAND)) { if (!checkAdminPermission(event)) { rejectCommand(event) } else { bdoNewsInterface.setBDONewsChannel(event.guild.id, event.textChannel.id) sendMessageAddChannel(event, "Invio delle news di BDO configurato sul canale: ") } - } else if (checkCommand(event, symbolCommand, BDOCommand.BDO_NEWS_STOP_COMMAND)) { + } else if (checkCommand(event, symbolCommand, BDO_NEWS_STOP_COMMAND)) { if (!checkAdminPermission(event)) { rejectCommand(event) } else { @@ -93,14 +93,14 @@ class BDOCommand : ListenerAdapter() { if (removedChannelId != null) sendMessageRemoveChannel(event, "Invio delle news di BDO rimosso dal canale: ", removedChannelId) } - } else if (checkCommand(event, symbolCommand, BDOCommand.BDO_PATCH_START_COMMAND)) { + } else if (checkCommand(event, symbolCommand, BDO_PATCH_START_COMMAND)) { if (!checkAdminPermission(event)) { rejectCommand(event) } else { bdoPatchInterface.setBDOPatchChannel(event.guild.id, event.textChannel.id) sendMessageAddChannel(event, "Invio delle patch di BDO configurato sul canale: ") } - } else if (checkCommand(event, symbolCommand, BDOCommand.BDO_PATCH_STOP_COMMAND)) { + } else if (checkCommand(event, symbolCommand, BDO_PATCH_STOP_COMMAND)) { if (!checkAdminPermission(event)) { rejectCommand(event) } else { diff --git a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt index d634d59..844744f 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt @@ -2,8 +2,9 @@ package it.discordbot.command.BDO.RSS import it.discordbot.beans.RSSMessage import it.discordbot.beans.ServerToChannel +import it.discordbot.command.pattern.RSSScheduler import it.discordbot.core.JDAController -import it.discordbot.database.interfaces.BDONewsInterface +import it.discordbot.database.filter.BDONewsInterface import net.dv8tion.jda.core.entities.MessageEmbed import org.springframework.beans.factory.annotation.Autowired import org.springframework.scheduling.annotation.Scheduled @@ -11,7 +12,7 @@ import org.springframework.stereotype.Service import java.util.* @Service -class BDONewsRSSScheduler { +class BDONewsRSSScheduler : RSSScheduler { @Autowired lateinit var bdorssReader: BDORSSReader @@ -24,30 +25,28 @@ class BDONewsRSSScheduler { fun taskFeedRSSBDONews() { val rssNewsMessage = bdorssReader.readRSS("https://community.blackdesertonline.com/index.php?forums/news-announcements.181/index.rss") - var newsBDOList = bdoNewsInterface.getBDONewsList() - if (newsBDOList.size != 0) { - if (newsBDOList.indexOf(rssNewsMessage.link) == -1) { - procedurePublish(rssNewsMessage, newsBDOList) + val newsBDO = bdoNewsInterface.getLastBDONews() + if (newsBDO != "") { + if (bdorssReader.isNew(rssNewsMessage.link, newsBDO)) { + procedurePublish(rssNewsMessage) } } else { - newsBDOList = ArrayList() - procedurePublish(rssNewsMessage, newsBDOList) + procedurePublish(rssNewsMessage) } } - private fun procedurePublish(rssNewsMessage: RSSMessage, newsBDOList: ArrayList) { - val newsMessage = bdorssReader.prepareRSStoEmbeddedMessage(rssNewsMessage) //ottieni il messaggio embedded - val listNewsChannel = bdoNewsInterface.getBDONewsChannels() //ottieni la delle ultime news già pubblicate - publishMessage(newsMessage, listNewsChannel) //publish del messaggio - newsBDOList.add(rssNewsMessage.link) //aggiunta dell'ultima news alla lista - bdoNewsInterface.setBDONewsList(newsBDOList) //salvataggio su db + override fun procedurePublish(rssMessage: RSSMessage) { + val newsMessage = bdorssReader.prepareRSStoMessageEmbed(rssMessage) //ottieni il messaggio embedded + val listNewsChannel = bdoNewsInterface.getBDONewsChannels() + publishMessage(newsMessage, listNewsChannel) + bdoNewsInterface.setBDONews(rssMessage.link) //salvataggio su db } - private fun publishMessage(newsMessage: MessageEmbed, servers: ArrayList) { - for (obj in servers) { + override fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList) { + for (obj in serversToChannel) { JDAController.jda.getGuildById(obj.serverID) .getTextChannelById(obj.channelID) - .sendMessage(newsMessage).queue() + .sendMessage(message).queue() } } diff --git a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt index 611c2ae..188ef8f 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt @@ -1,8 +1,10 @@ package it.discordbot.command.BDO.RSS +import it.discordbot.beans.RSSMessage import it.discordbot.beans.ServerToChannel +import it.discordbot.command.pattern.RSSScheduler import it.discordbot.core.JDAController -import it.discordbot.database.interfaces.BDOPatchInterface +import it.discordbot.database.filter.BDOPatchInterface import net.dv8tion.jda.core.entities.MessageEmbed import org.springframework.beans.factory.annotation.Autowired import org.springframework.scheduling.annotation.Scheduled @@ -10,7 +12,7 @@ import org.springframework.stereotype.Service import java.util.* @Service -class BDOPatchRSSScheduler { +class BDOPatchRSSScheduler : RSSScheduler { @Autowired lateinit var bdorssReader: BDORSSReader @@ -21,39 +23,29 @@ class BDOPatchRSSScheduler { @Scheduled(fixedRate = 1800000, initialDelay = 1800000) fun taskFeedRSSBDOPatch() { - /*val rssNewsMessage = bdorssReader.readRSS("https://community.blackdesertonline.com/index.php?forums/news-announcements.181/index.rss") - - var newsBDOList = bdoNewsInterface.getBDONewsList() - if (newsBDOList.indexOf(rssNewsMessage.link) == -1) { - procedurePublish(rssNewsMessage, newsBDOList) - }else{ - newsBDOList = ArrayList() - procedurePublish(rssNewsMessage, newsBDOList) - }*/ - val rssPatchMessage = bdorssReader.readRSS("https://community.blackdesertonline.com/index.php?forums/patch-notes.5/index.rss") - val lastPatch = bdoPatchInterface.getBDOPatchList() + val patchBDO = bdoPatchInterface.getLastBDOPatch() - val message = bdorssReader.prepareRSStoEmbeddedMessage(rssPatchMessage) - val listPatchChannel = bdoPatchInterface.getBDOPatchChannels() - if (rssPatchMessage.link != lastPatch) { - publishMessage(message, listPatchChannel) - bdoPatchInterface.setLastPatch(rssPatchMessage.link) - } + if (patchBDO != "") { + if (bdorssReader.isNew(rssPatchMessage.link, patchBDO)) { + procedurePublish(rssPatchMessage) + } + } else { + procedurePublish(rssPatchMessage) + } } - /*private fun procedurePublish(rssNewsMessage: RSSMessage, newsBDOList: ArrayList) { - val newsMessage = bdorssReader.prepareRSStoEmbeddedMessage(rssNewsMessage) //ottieni il messaggio embedded - val listNews = bdoNewsInterface.getBDONewsChannels() //ottieni la delle ultime news già pubblicate - publishMessage(newsMessage, listNews) //publish del messaggio - newsBDOList.add(rssNewsMessage.link) //aggiunta dell'ultima news alla lista - bdoNewsInterface.setBDONewsList(newsBDOList) //salvataggio su db - }*/ + override fun procedurePublish(rssPatchMessage: RSSMessage) { + val patchMessage = bdorssReader.prepareRSStoMessageEmbed(rssPatchMessage) //ottieni il messaggio embedded + val listNewsChannel = bdoPatchInterface.getBDOPatchChannels() + publishMessage(patchMessage, listNewsChannel) + bdoPatchInterface.setLastPatch(rssPatchMessage.link) //salvataggio su db + } - private fun publishMessage(patchMessage: MessageEmbed, servers: ArrayList) { + override fun publishMessage(patchMessage: MessageEmbed, servers: ArrayList) { for (obj in servers) { JDAController.jda.getGuildById(obj.serverID) .getTextChannelById(obj.channelID) diff --git a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt index 669fd45..551083a 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt @@ -3,6 +3,7 @@ package it.discordbot.command.BDO.RSS import com.rometools.rome.io.SyndFeedInput import com.rometools.rome.io.XmlReader import it.discordbot.beans.RSSMessage +import it.discordbot.command.pattern.RSSReader import net.dv8tion.jda.core.EmbedBuilder import net.dv8tion.jda.core.entities.MessageEmbed import org.jsoup.Jsoup @@ -11,17 +12,18 @@ import org.springframework.context.annotation.Scope import org.springframework.stereotype.Component import java.awt.Color import java.net.URL +import java.util.regex.Pattern @Scope("singleton") @Component -class BDORSSReader { +class BDORSSReader : RSSReader { /** * Metodo per leggere un feed RSS * @param url Url da cui bisogna leggere il feed * @return Ultimo feed registrato */ - fun readRSS(url: String): RSSMessage { + override fun readRSS(url: String): RSSMessage { var title: String var link: String @@ -39,7 +41,36 @@ class BDORSSReader { return RSSMessage(title, link, doc) } - fun prepareRSStoEmbeddedMessage(message: RSSMessage): MessageEmbed { + private fun linkNumberParser(link: String): Int { + return link.substring(1, link.length - 1).toInt() + } + + fun isNew(linkRSS: String, linkDB: String): Boolean { + val regex1 = Pattern.compile( + "\\.(\\d+)/?\$", + Pattern.CASE_INSENSITIVE or Pattern.UNICODE_CASE or Pattern.COMMENTS) + + val regex2 = Pattern.compile( + "\\.(\\d+)/?\$", + Pattern.CASE_INSENSITIVE or Pattern.UNICODE_CASE or Pattern.COMMENTS) + + val regexMatcher1 = regex1.matcher(linkRSS) + regexMatcher1.find() + + val numberRSS = linkNumberParser(regexMatcher1.group()) + + val regexMatcher2 = regex2.matcher(linkDB) + regexMatcher2.find() + + val numberDB = linkNumberParser(regexMatcher2.group()) + return if (numberRSS == numberDB) { + false + } else { + numberDB < numberRSS + } + } + + override fun prepareRSStoMessageEmbed(message: RSSMessage): MessageEmbed { val body = Jsoup.parse(message.doc.toString().replace("(?i)]*>", "br2n")) .text() .replace("br2n".toRegex(), "\n") diff --git a/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt b/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt index 5bb7a56..31e9be2 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt @@ -1,6 +1,6 @@ package it.discordbot.command.BDO.boss -import it.discordbot.database.interfaces.BDOBossInterface +import it.discordbot.database.filter.BDOBossInterface import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.scheduling.annotation.Scheduled diff --git a/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt b/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt index ca21b3c..9622e69 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt @@ -3,7 +3,7 @@ package it.discordbot.command.BDO.boss import it.discordbot.beans.boss.Boss import it.discordbot.beans.boss.Giorno import it.discordbot.core.JDAController -import it.discordbot.database.interfaces.BDOBossInterface +import it.discordbot.database.filter.BDOBossInterface import net.dv8tion.jda.core.MessageBuilder import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope @@ -124,7 +124,7 @@ class BossUtil { } }.build() - for (serverChannel in listServerChannel){ + for (serverChannel in listServerChannel) { JDAController.jda.getGuildById(serverChannel.serverID) .getTextChannelById(serverChannel.channelID) .sendMessage(message).queue() diff --git a/src/main/kotlin/it/discordbot/command/ControlCommand.kt b/src/main/kotlin/it/discordbot/command/ControlCommand.kt index d68dd6e..9dea433 100644 --- a/src/main/kotlin/it/discordbot/command/ControlCommand.kt +++ b/src/main/kotlin/it/discordbot/command/ControlCommand.kt @@ -1,6 +1,5 @@ package it.discordbot.command -import it.discordbot.database.interfaces.ServerManagementInterface import net.dv8tion.jda.core.Permission import net.dv8tion.jda.core.entities.ChannelType import net.dv8tion.jda.core.events.message.MessageReceivedEvent @@ -11,9 +10,10 @@ fun checkCommand(@NotNull event: MessageReceivedEvent, @NotNull commandName: String): Boolean { val completeCommand = simbolCommand + commandName.toLowerCase() + val commandEvent = event.message.contentRaw.split(" ")[0].toLowerCase() return if (!event.isFromType(ChannelType.PRIVATE)) { - if (event.message.contentRaw == completeCommand || + if (commandEvent == completeCommand || event.message.isMentioned(event.jda.selfUser) && event.message.contentRaw.contains(commandName)) { true diff --git a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt index 8745ff9..8b666ee 100644 --- a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt +++ b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt @@ -5,7 +5,7 @@ import it.discordbot.command.checkAdminPermission import it.discordbot.command.checkCommand import it.discordbot.command.rejectCommand import it.discordbot.core.JDAController -import it.discordbot.database.interfaces.ServerManagementInterface +import it.discordbot.database.filter.ServerManagementInterface import net.dv8tion.jda.core.EmbedBuilder import net.dv8tion.jda.core.MessageBuilder import net.dv8tion.jda.core.entities.ChannelType diff --git a/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt b/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt index 1ef686e..87927c0 100644 --- a/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt +++ b/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt @@ -1,7 +1,7 @@ package it.discordbot.command.generalCommand import it.discordbot.core.TakaoLog -import it.discordbot.database.interfaces.ServerManagementInterface +import it.discordbot.database.filter.ServerManagementInterface import net.dv8tion.jda.core.events.guild.GuildJoinEvent import net.dv8tion.jda.core.events.guild.GuildLeaveEvent import net.dv8tion.jda.core.events.guild.update.GuildUpdateNameEvent diff --git a/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt b/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt index 2de1292..cc555b8 100644 --- a/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt +++ b/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt @@ -2,7 +2,7 @@ package it.discordbot.command.music import it.discordbot.command.checkCommand import it.discordbot.command.music.config.MusicManager -import it.discordbot.database.interfaces.ServerManagementInterface +import it.discordbot.database.filter.ServerManagementInterface import net.dv8tion.jda.core.events.message.MessageReceivedEvent import net.dv8tion.jda.core.hooks.ListenerAdapter import org.springframework.beans.factory.annotation.Autowired diff --git a/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt b/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt index ece1df5..c009bf8 100644 --- a/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt +++ b/src/main/kotlin/it/discordbot/command/music/config/AudioPlayerSendHandler.kt @@ -3,8 +3,6 @@ package it.discordbot.command.music.config import com.sedmelluq.discord.lavaplayer.player.AudioPlayer import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame import net.dv8tion.jda.core.audio.AudioSendHandler -import org.springframework.context.annotation.Bean -import org.springframework.stereotype.Component class AudioPlayerSendHandler(val audioPlayer: AudioPlayer) : AudioSendHandler { diff --git a/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt b/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt index 6b80260..c1acedf 100644 --- a/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt +++ b/src/main/kotlin/it/discordbot/command/music/config/GuildMusicManager.kt @@ -1,8 +1,7 @@ package it.discordbot.command.music.config -import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager import com.sedmelluq.discord.lavaplayer.player.AudioPlayer -import org.springframework.stereotype.Component +import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager class GuildMusicManager(val manager: AudioPlayerManager) { diff --git a/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt b/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt index a3a6a1e..5a2dea7 100644 --- a/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt +++ b/src/main/kotlin/it/discordbot/command/music/config/MusicManager.kt @@ -406,7 +406,7 @@ class MusicManager { if (addPlaylist) { channel.sendMessage("Aggiunte **" + playlist.tracks.size + "** tracce alla coda").queue() // tracks.forEach(Consumer { mng.scheduler.queue() }) - tracks.forEach { _ -> Consumer {mng.scheduler.queue} } + tracks.forEach { _ -> Consumer { mng.scheduler.queue } } } else { channel.sendMessage("Aggiunto alla coda " + firstTrack!!.info.title).queue() mng.scheduler.queue(firstTrack) diff --git a/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt b/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt index 41b219a..370ef20 100644 --- a/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/music/config/TrackScheduler.kt @@ -4,7 +4,6 @@ import com.sedmelluq.discord.lavaplayer.player.AudioPlayer import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter import com.sedmelluq.discord.lavaplayer.track.AudioTrack import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason -import org.springframework.stereotype.Component import java.util.* class TrackScheduler(val player: AudioPlayer) : AudioEventAdapter() { @@ -17,11 +16,11 @@ class TrackScheduler(val player: AudioPlayer) : AudioEventAdapter() { * * @param track The track to play or add to queue. */ - fun queue(track:AudioTrack){ + fun queue(track: AudioTrack) { // Calling startTrack with the noInterrupt set to true will start the track only if nothing is currently playing. If // something is playing, it returns false and does nothing. In that case the player was already playing so this // track goes to the queue instead. - if (!player.startTrack(track, true)){ + if (!player.startTrack(track, true)) { queue.offer(track) } } diff --git a/src/main/kotlin/it/discordbot/command/pattern/RSSReader.kt b/src/main/kotlin/it/discordbot/command/pattern/RSSReader.kt new file mode 100644 index 0000000..9d2f23a --- /dev/null +++ b/src/main/kotlin/it/discordbot/command/pattern/RSSReader.kt @@ -0,0 +1,12 @@ +package it.discordbot.command.pattern + +import it.discordbot.beans.RSSMessage +import net.dv8tion.jda.core.entities.MessageEmbed + +interface RSSReader { + + fun readRSS(url: String): RSSMessage + + fun prepareRSStoMessageEmbed(message: RSSMessage): MessageEmbed + +} \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/command/pattern/RSSScheduler.kt b/src/main/kotlin/it/discordbot/command/pattern/RSSScheduler.kt new file mode 100644 index 0000000..0e21619 --- /dev/null +++ b/src/main/kotlin/it/discordbot/command/pattern/RSSScheduler.kt @@ -0,0 +1,12 @@ +package it.discordbot.command.pattern + +import it.discordbot.beans.RSSMessage +import it.discordbot.beans.ServerToChannel +import net.dv8tion.jda.core.entities.MessageEmbed + +interface RSSScheduler { + + fun procedurePublish(rssMessage: RSSMessage) + + fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList) +} \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt index 5795f15..4f48a73 100644 --- a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt +++ b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt @@ -3,8 +3,8 @@ package it.discordbot.command.tpl.atmAlert import it.discordbot.command.checkAdminPermission import it.discordbot.command.checkCommand import it.discordbot.command.rejectCommand -import it.discordbot.database.interfaces.ATMInterface -import it.discordbot.database.interfaces.ServerManagementInterface +import it.discordbot.database.filter.ATMInterface +import it.discordbot.database.filter.ServerManagementInterface import net.dv8tion.jda.core.MessageBuilder import net.dv8tion.jda.core.events.message.MessageReceivedEvent import net.dv8tion.jda.core.hooks.ListenerAdapter diff --git a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt index cfa93ea..2c557f7 100644 --- a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt +++ b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt @@ -3,6 +3,7 @@ package it.discordbot.command.tpl.atmAlert import com.rometools.rome.io.SyndFeedInput import com.rometools.rome.io.XmlReader import it.discordbot.beans.RSSMessage +import it.discordbot.command.pattern.RSSReader import net.dv8tion.jda.core.EmbedBuilder import net.dv8tion.jda.core.entities.MessageEmbed import org.jsoup.Jsoup @@ -15,9 +16,9 @@ import java.util.regex.Pattern @Scope("singleton") @Component -class ATMRSSReader { +class ATMRSSReader : RSSReader { - fun readRSS(url: String): RSSMessage { + override fun readRSS(url: String): RSSMessage { var title: String var link: String @@ -35,7 +36,7 @@ class ATMRSSReader { return RSSMessage(title, link, doc) } - fun prepareRSStoEmbeddedMessage(message: RSSMessage): MessageEmbed { + override fun prepareRSStoMessageEmbed(message: RSSMessage): MessageEmbed { var regex = Pattern.compile( "

|

|
", Pattern.CASE_INSENSITIVE or Pattern.UNICODE_CASE or Pattern.COMMENTS) diff --git a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt index fdc009e..0c78039 100644 --- a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt @@ -1,8 +1,11 @@ package it.discordbot.command.tpl.atmAlert import it.discordbot.beans.RSSMessage +import it.discordbot.beans.ServerToChannel +import it.discordbot.command.pattern.RSSScheduler import it.discordbot.core.JDAController -import it.discordbot.database.interfaces.ATMInterface +import it.discordbot.database.filter.ATMInterface +import net.dv8tion.jda.core.entities.MessageEmbed import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.scheduling.annotation.Scheduled @@ -10,7 +13,7 @@ import org.springframework.stereotype.Service @Scope("singleton") @Service -class ATMRSSScheduler { +class ATMRSSScheduler : RSSScheduler { companion object { const val ATM_RSS_LINK = "https://www.atm.it/_layouts/atm/apps/PublishingRSS.aspx?web=388a6572-890f-4e0f-a3c7-a3dd463f7252&c=News%20Infomobilita" @@ -30,26 +33,28 @@ class ATMRSSScheduler { if (lastATMAlert != null) { if (lastATMAlert != message.link) { - publish(message) - atmInterface.setLastATMAlert(message.link) + procedurePublish(message) } } else { - publish(message) - atmInterface.setLastATMAlert(message.link) + procedurePublish(message) } - } - private fun publish(message: RSSMessage) { + override fun procedurePublish(rssMessage: RSSMessage) { val serverList = atmInterface.getATMAlertChannels() - val messageEmbed = atmrssReader.prepareRSStoEmbeddedMessage(message) - for (server in serverList) { - JDAController.jda.getGuildById(server.serverID) - .getTextChannelById(server.channelID) - .sendMessage(messageEmbed) + val messageEmbed = atmrssReader.prepareRSStoMessageEmbed(rssMessage) + publishMessage(messageEmbed, serverList) + atmInterface.setLastATMAlert(rssMessage.link) + + } + + override fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList) { + for (obj in serversToChannel) { + JDAController.jda.getGuildById(obj.serverID) + .getTextChannelById(obj.channelID) + .sendMessage(message) .queue() } - } } \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt index 2e7dda2..ea0fecf 100644 --- a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt @@ -3,7 +3,7 @@ package it.discordbot.command.tpl.atmAlert import it.discordbot.core.JDAController import it.discordbot.core.TakaoLog import it.discordbot.core.TwitterManager -import it.discordbot.database.interfaces.ATMInterface +import it.discordbot.database.filter.ATMInterface import net.dv8tion.jda.core.EmbedBuilder import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope @@ -31,33 +31,31 @@ class ATMTwitterScheduler { } @PostConstruct - fun initATMTwitterScheduler(){ + fun initATMTwitterScheduler() { val listener = object : StatusListener { override fun onStatus(status: Status) { - if (status.user.id == ATM_TWITTER_ID) { - - if (!status.isRetweet) { - TakaoLog.logInfo("ATMUSERID = " + status.user.screenName + " " + status.user.id + "\nMESSAGE = " + status.text) - thread(start = true) { - val statusCopy = status - - val tweetID: Long - val tweetMessage: String - var mediaUrl: String? = null - val profileImageUrl: String - - statusCopy.apply { - tweetID = id - tweetMessage = text - profileImageUrl = user.profileImageURL - if (mediaEntities.isNotEmpty()) { - mediaUrl = mediaEntities[0].mediaURL + if (status.user.id == ATM_TWITTER_ID && status.isRetweet) { + TakaoLog.logInfo("ATMUSERID = " + status.user.screenName + " " + status.user.id + "\nMESSAGE = " + status.text) + thread(start = true) { + + val tweetID: Long + var tweetMessage: String + var mediaUrl: String? = null + val profileImageUrl: String + + status.apply { + tweetID = id + tweetMessage = text + profileImageUrl = user.profileImageURL + if (mediaEntities.isNotEmpty()) { + mediaUrl = mediaEntities[0].mediaURL + if (mediaEntities.size > 1) { + tweetMessage = "$tweetMessage\n\n Altre immagini le puoi trovare sul tweet." } - } - - publish(tweetID, tweetMessage, mediaUrl, profileImageUrl) + } } + publish(tweetID, tweetMessage, mediaUrl, profileImageUrl) } } @@ -83,9 +81,10 @@ class ATMTwitterScheduler { } } - var query = FilterQuery().track(QUERY_PARAM) - - query.follow(ATM_TWITTER_ID) + val query = FilterQuery().apply { + track(QUERY_PARAM) + follow(ATM_TWITTER_ID) + } twitterManager.apply { setTwitterStreamListener(listener) @@ -102,7 +101,10 @@ class ATMTwitterScheduler { twitterMessage.contains("#M2") || twitterMessage.contains("#M3") || twitterMessage.contains("#M5") || - twitterMessage.contains("\ud83d\udea6")) { + twitterMessage.contains("\ud83d\udea6") || + twitterMessage.contains("sciopero", ignoreCase = true) || + twitterMessage.contains("manifestazione", ignoreCase = true) || + twitterMessage.contains("aggiornamento", ignoreCase = true)) { val message = EmbedBuilder().apply { setAuthor("ATM (@atm_informa)", tweetUrl, profileImageUrl) setDescription(twitterMessage) diff --git a/src/main/kotlin/it/discordbot/core/TakaoLog.kt b/src/main/kotlin/it/discordbot/core/TakaoLog.kt index 7903ae6..3170a32 100644 --- a/src/main/kotlin/it/discordbot/core/TakaoLog.kt +++ b/src/main/kotlin/it/discordbot/core/TakaoLog.kt @@ -8,15 +8,15 @@ class TakaoLog { companion object { private var logger = LoggerFactory.getLogger(TakaoLog::class.java) - fun logDebug(message:String){ + fun logDebug(message: String) { logger.debug(message) } - fun logInfo(message: String){ + fun logInfo(message: String) { logger.info(message) } - fun logError(message: String){ + fun logError(message: String) { logger.error(message) } } diff --git a/src/main/kotlin/it/discordbot/core/TwitterManager.kt b/src/main/kotlin/it/discordbot/core/TwitterManager.kt index c8226f3..9e05795 100644 --- a/src/main/kotlin/it/discordbot/core/TwitterManager.kt +++ b/src/main/kotlin/it/discordbot/core/TwitterManager.kt @@ -30,7 +30,7 @@ class TwitterManager { private lateinit var twitterStream: TwitterStream @PostConstruct - fun initTwitter(){ + fun initTwitter() { val configuration = ConfigurationBuilder().apply { setOAuthConsumerKey(twitterConsumerKey) setOAuthConsumerSecret(twitterConsumerSecret) @@ -42,7 +42,7 @@ class TwitterManager { twitterStream = twitterStreamFactory.instance } - fun setTwitterStreamListener(listener: StatusListener):TwitterManager{ + fun setTwitterStreamListener(listener: StatusListener): TwitterManager { twitterStream.addListener(listener) return this } diff --git a/src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt b/src/main/kotlin/it/discordbot/database/filter/ATMInterface.kt similarity index 97% rename from src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt rename to src/main/kotlin/it/discordbot/database/filter/ATMInterface.kt index 2a31c49..fb5500b 100644 --- a/src/main/kotlin/it/discordbot/database/interfaces/ATMInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/ATMInterface.kt @@ -1,4 +1,4 @@ -package it.discordbot.database.interfaces +package it.discordbot.database.filter import it.discordbot.beans.ServerToChannel import it.discordbot.database.repository.RSSLinkRepository diff --git a/src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt b/src/main/kotlin/it/discordbot/database/filter/BDOBossInterface.kt similarity index 87% rename from src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt rename to src/main/kotlin/it/discordbot/database/filter/BDOBossInterface.kt index 525a796..6230db9 100644 --- a/src/main/kotlin/it/discordbot/database/interfaces/BDOBossInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/BDOBossInterface.kt @@ -1,4 +1,4 @@ -package it.discordbot.database.interfaces +package it.discordbot.database.filter import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue @@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.core.io.ClassPathResource import org.springframework.stereotype.Controller + @Scope("singleton") @Controller class BDOBossInterface { @@ -16,7 +17,7 @@ class BDOBossInterface { @Autowired lateinit var serverDiscordRepository: ServerDiscordRepository - fun setBDOBossChannel(serverID:String , channelID: String){ + fun setBDOBossChannel(serverID: String, channelID: String) { val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) serverDiscord.bdoBossIDChannel = channelID serverDiscordRepository.save(serverDiscord) @@ -30,11 +31,11 @@ class BDOBossInterface { return bossChannelRemoveID } - fun getBDOBossChannels(): ArrayList{ + fun getBDOBossChannels(): ArrayList { return serverDiscordRepository.getAllBDOBossChannels() } - fun getBDOBossList():ArrayList{ + fun getBDOBossList(): ArrayList { val inputStreamBoss = ClassPathResource("jsonboss.json").inputStream val list = jacksonObjectMapper().readValue>(inputStreamBoss) inputStreamBoss.close() diff --git a/src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt b/src/main/kotlin/it/discordbot/database/filter/BDONewsInterface.kt similarity index 69% rename from src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt rename to src/main/kotlin/it/discordbot/database/filter/BDONewsInterface.kt index 6c075fb..3d90b55 100644 --- a/src/main/kotlin/it/discordbot/database/interfaces/BDONewsInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/BDONewsInterface.kt @@ -1,7 +1,5 @@ -package it.discordbot.database.interfaces +package it.discordbot.database.filter -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import it.discordbot.beans.ServerToChannel import it.discordbot.database.repository.RSSLinkRepository import it.discordbot.database.repository.ServerDiscordRepository @@ -19,7 +17,7 @@ class BDONewsInterface { @Autowired lateinit var rssLinkRepository: RSSLinkRepository - fun setBDONewsChannel(serverID:String , channelID: String){ + fun setBDONewsChannel(serverID: String, channelID: String) { val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) serverDiscord.bdoNewsIDChannel = channelID serverDiscordRepository.save(serverDiscord) @@ -33,25 +31,25 @@ class BDONewsInterface { return newsChannelRemoveID } - fun getBDONewsChannels(): ArrayList{ + fun getBDONewsChannels(): ArrayList { return serverDiscordRepository.getAllBDONewsChannels() } - fun getBDONewsList(): ArrayList{ + fun getLastBDONews(): String { val bdoRSSNews = rssLinkRepository.getFirstById().lastNewsBDO - if (bdoRSSNews == null){ - return ArrayList() - }else{ - return jacksonObjectMapper().readValue(bdoRSSNews) + if (bdoRSSNews == null) { + return "" + } else { + return bdoRSSNews } } - fun setBDONewsList(list: ArrayList){ + fun setBDONews(link: String) { rssLinkRepository.getFirstById().apply { - lastNewsBDO = jacksonObjectMapper().writeValueAsString(list) + lastNewsBDO = link rssLinkRepository.save(this) } } diff --git a/src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt b/src/main/kotlin/it/discordbot/database/filter/BDOPatchInterface.kt similarity index 67% rename from src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt rename to src/main/kotlin/it/discordbot/database/filter/BDOPatchInterface.kt index 151e108..55e4202 100644 --- a/src/main/kotlin/it/discordbot/database/interfaces/BDOPatchInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/BDOPatchInterface.kt @@ -1,14 +1,11 @@ -package it.discordbot.database.interfaces +package it.discordbot.database.filter -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import it.discordbot.beans.ServerToChannel import it.discordbot.database.repository.RSSLinkRepository import it.discordbot.database.repository.ServerDiscordRepository import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.stereotype.Component -import org.springframework.stereotype.Controller @Scope("singleton") @Component @@ -20,7 +17,7 @@ class BDOPatchInterface { @Autowired lateinit var rssLinkRepository: RSSLinkRepository - fun setBDOPatchChannel(serverID:String , channelID: String){ + fun setBDOPatchChannel(serverID: String, channelID: String) { val serverDiscord = serverDiscordRepository.findServerDiscordByServerId(serverID) serverDiscord.bdoPatchIDChannel = channelID serverDiscordRepository.save(serverDiscord) @@ -34,19 +31,23 @@ class BDOPatchInterface { return patchChannelRemoveID } - fun getBDOPatchChannels(): ArrayList{ + fun getBDOPatchChannels(): ArrayList { return serverDiscordRepository.getAllBDOPatchChannels() } - /*fun getBDOPatchList(): ArrayList{ - return jacksonObjectMapper().readValue(rssLinkRepository.getFirstById().lastPatchBDO) - }*/ + fun getLastBDOPatch(): String { + + val bdoRSSPatch = rssLinkRepository.getFirstById().lastPatchBDO + + if (bdoRSSPatch == null) { + return "" + } else { + return bdoRSSPatch + } - fun getBDOPatchList(): String?{ - return rssLinkRepository.getFirstById().lastPatchBDO } - fun setLastPatch(linkPatch:String){ + fun setLastPatch(linkPatch: String) { val rssLink = rssLinkRepository.getFirstById() rssLink.lastPatchBDO = linkPatch rssLinkRepository.save(rssLink) diff --git a/src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt b/src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt similarity index 88% rename from src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt rename to src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt index 1e6727b..783964e 100644 --- a/src/main/kotlin/it/discordbot/database/interfaces/ServerManagementInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt @@ -1,4 +1,4 @@ -package it.discordbot.database.interfaces +package it.discordbot.database.filter import it.discordbot.beans.ServerDiscord import it.discordbot.database.repository.ServerDiscordRepository @@ -25,7 +25,7 @@ class ServerManagementInterface { serverDiscordRepository.save(serverDiscord) } - fun newServer(serverID: String, serverName:String){ + fun newServer(serverID: String, serverName: String) { val serverDiscord = ServerDiscord() serverDiscord.let { it.serverId = serverID @@ -34,7 +34,7 @@ class ServerManagementInterface { serverDiscordRepository.save(serverDiscord) } - fun deleteServer(serverID: String){ + fun deleteServer(serverID: String) { serverDiscordRepository.deleteById(serverID) } } \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt b/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt index 495316a..7d3b2d7 100644 --- a/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt +++ b/src/main/kotlin/it/discordbot/database/repository/RSSLinkRepository.kt @@ -3,7 +3,7 @@ package it.discordbot.database.repository import it.discordbot.beans.RSSLink import org.springframework.data.repository.CrudRepository -interface RSSLinkRepository: CrudRepository { +interface RSSLinkRepository : CrudRepository { fun getFirstById(id: Long = 1): RSSLink } \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt b/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt index 70d5c51..fb14ee0 100644 --- a/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt +++ b/src/main/kotlin/it/discordbot/database/repository/ServerDiscordRepository.kt @@ -5,9 +5,6 @@ import it.discordbot.beans.ServerToChannel import org.springframework.data.jpa.repository.Query import org.springframework.data.repository.CrudRepository import org.springframework.stereotype.Repository -import javax.persistence.ColumnResult -import javax.persistence.ConstructorResult -import javax.persistence.SqlResultSetMapping @Repository interface ServerDiscordRepository : CrudRepository { From b5c475c0e6f76f8782f0d8549faefa3da35273f0 Mon Sep 17 00:00:00 2001 From: samuele794 Date: Wed, 15 May 2019 13:58:02 +0200 Subject: [PATCH 05/12] Cambiato colore all'evidenziazione del testo --- docs/css/commandStyle.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/css/commandStyle.css b/docs/css/commandStyle.css index ebd17bb..c350c7b 100644 --- a/docs/css/commandStyle.css +++ b/docs/css/commandStyle.css @@ -22,6 +22,14 @@ } } +::selection { + background: #06c; +} + +::-moz-selection { + background: #06c; +} + .logoCommand { height: 32px; margin-left: 10px; From 37ea4a95708267308d3c48eb363bd224dab4cc08 Mon Sep 17 00:00:00 2001 From: samuele794 Date: Fri, 17 May 2019 11:55:25 +0200 Subject: [PATCH 06/12] Aggiunto File Logback, Aggiunto Plug-in Dokka Aggiunto file logback per creare i log su file Aggiunto Plug-in Dokka per creare la documentazione --- build.gradle | 137 +++++++++++------- .../kotlin/it/discordbot/beans/RSSLink.kt | 7 + .../it/discordbot/command/BDO/BDOCommand.kt | 98 +++++++------ .../command/BDO/RSS/BDORSSReader.kt | 4 +- .../command/generalCommand/GeneralCommand.kt | 32 ++-- .../command/generalCommand/JoinListener.kt | 2 + .../discordbot/command/music/MusicCommand.kt | 5 + .../filter/ServerManagementInterface.kt | 2 +- src/main/resources/application.properties | 1 + src/main/resources/logback.xml | 47 ++++++ .../discordbot/test/DemoApplicationTests.kt | 11 +- 11 files changed, 223 insertions(+), 123 deletions(-) create mode 100644 src/main/resources/logback.xml diff --git a/build.gradle b/build.gradle index 7a12f46..0317500 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,11 @@ plugins { - id 'org.springframework.boot' version '2.1.4.RELEASE' - id 'org.jetbrains.kotlin.jvm' version '1.3.31' - id 'org.jetbrains.kotlin.plugin.spring' version '1.3.31' - id 'java' - id 'application' - id 'com.github.johnrengelman.shadow' version '4.0.4' + id 'org.springframework.boot' version '2.1.4.RELEASE' + id 'org.jetbrains.kotlin.jvm' version '1.3.31' + id 'org.jetbrains.kotlin.plugin.spring' version '1.3.31' + id 'java' + id 'application' + id 'com.github.johnrengelman.shadow' version '4.0.4' + id 'org.jetbrains.dokka' version '0.9.18' } apply plugin: 'io.spring.dependency-management' @@ -14,87 +15,113 @@ version = '2.0' sourceCompatibility = '1.8' repositories { - mavenCentral() - jcenter() + mavenCentral() + jcenter() } jar { - enabled = true + enabled = true } springBoot { - buildInfo() + buildInfo() } bootJar { - classifier = 'boot' - manifest { - attributes 'Start-Class': 'it.discordbot.StartBotKt' + classifier = 'boot' + manifest { + attributes 'Start-Class': 'it.discordbot.StartBotKt' - } - launchScript() + } + launchScript() } +/*dokka { + outputFormat = 'html-as-java' + outputDirectory = "$buildDir/javadoc" + jdkVersion = 8 + includeNonPublic = true +}*/ + +task dokkaPureKotlindoc(type: org.jetbrains.dokka.gradle.DokkaTask) { + outputFormat = 'html' + outputDirectory = "$buildDir/kotlindoc" + jdkVersion = 8 + includeNonPublic = true +} -dependencies { +task dokkaPureJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) { + outputFormat = 'javadoc' + outputDirectory = "$buildDir/javadoc" + jdkVersion = 8 + includeNonPublic = true +} + +task dokkaKotlindocAsJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) { + outputFormat = 'html-as-java' + outputDirectory = "$buildDir/javadoc" + jdkVersion = 8 + includeNonPublic = true +} +dependencies { - implementation 'org.springframework.boot:spring-boot-starter' - implementation 'org.jetbrains.kotlin:kotlin-reflect' - annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" - implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - //SPRING LIBRARY - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web - implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.4.RELEASE' - implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.+" + implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.jetbrains.kotlin:kotlin-reflect' + annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" + implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + //SPRING LIBRARY + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web + implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.4.RELEASE' + implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.+" - implementation 'net.dv8tion:JDA:3.8.3_463' + implementation 'net.dv8tion:JDA:3.8.3_463' - //RSS + HTML PARSER - // https://mvnrepository.com/artifact/com.rometools/rome - implementation group: 'com.rometools', name: 'rome', version: '1.12.0' - // jsoup HTML parser library @ https://jsoup.org/ - implementation 'org.jsoup:jsoup:1.11.3' + //RSS + HTML PARSER + // https://mvnrepository.com/artifact/com.rometools/rome + implementation group: 'com.rometools', name: 'rome', version: '1.12.0' + // jsoup HTML parser library @ https://jsoup.org/ + implementation 'org.jsoup:jsoup:1.11.3' - //ESCAPE UTIL - // https://mvnrepository.com/artifact/commons-io/commons-io - implementation "org.apache.commons:commons-text:1.3" + //ESCAPE UTIL + // https://mvnrepository.com/artifact/commons-io/commons-io + implementation "org.apache.commons:commons-text:1.3" - //POSTGRESQL DRIVER - // https://mvnrepository.com/artifact/org.postgresql/postgresql - implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.5' + //POSTGRESQL DRIVER + // https://mvnrepository.com/artifact/org.postgresql/postgresql + implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.5' - //TwitterAPI - // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-core - implementation group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7' - // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-stream - implementation group: 'org.twitter4j', name: 'twitter4j-stream', version: '4.0.7' - // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-async - implementation group: 'org.twitter4j', name: 'twitter4j-async', version: '4.0.7' + //TwitterAPI + // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-core + implementation group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7' + // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-stream + implementation group: 'org.twitter4j', name: 'twitter4j-stream', version: '4.0.7' + // https://mvnrepository.com/artifact/org.twitter4j/twitter4j-async + implementation group: 'org.twitter4j', name: 'twitter4j-async', version: '4.0.7' - //MUSIC PLAYER - implementation 'com.sedmelluq:lavaplayer:1.3.17' + //MUSIC PLAYER + implementation 'com.sedmelluq:lavaplayer:1.3.17' } compileKotlin { - kotlinOptions { - freeCompilerArgs = ['-Xjsr305=strict'] - jvmTarget = '1.8' - } + kotlinOptions { + freeCompilerArgs = ['-Xjsr305=strict'] + jvmTarget = '1.8' + } } compileTestKotlin { - kotlinOptions { - freeCompilerArgs = ['-Xjsr305=strict'] - jvmTarget = '1.8' - } + kotlinOptions { + freeCompilerArgs = ['-Xjsr305=strict'] + jvmTarget = '1.8' + } } compileJava.options.encoding = 'UTF-8' diff --git a/src/main/kotlin/it/discordbot/beans/RSSLink.kt b/src/main/kotlin/it/discordbot/beans/RSSLink.kt index 562bd61..732b616 100644 --- a/src/main/kotlin/it/discordbot/beans/RSSLink.kt +++ b/src/main/kotlin/it/discordbot/beans/RSSLink.kt @@ -7,6 +7,13 @@ import javax.persistence.Table @Entity @Table(name = "`RSSLink`") +/** + * Entità che rappresenta la tabella contenitore dei link RSS + * @property id Long id riga + * @property lastNewsBDO String? link dell'ultima news di BDO + * @property lastPatchBDO String? link dell'ultima patch di BDO + * @property lastAtmAlert String? link dell'ultima news di ATM + */ class RSSLink { @Id @Column(name = "`id`") diff --git a/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt b/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt index 5e7643c..3389cb9 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt @@ -34,19 +34,19 @@ class BDOCommand : ListenerAdapter() { const val BDO_BOSS_START_COMMAND = "BDOBossStart" - const val BDO_BOSS_START_COMMAND_DESCRIPTION = "Questo comando permette di iscriversi agli allarmi dei boss di BDO. \n" + "Il comando deve essere lanciato sul canale su cui si desidera ricevere i boss" + const val BDO_BOSS_START_COMMAND_DESCRIPTION = "Questo comando permette di iscriversi agli allarmi dei boss di BDO. \n Il comando deve essere lanciato sul canale su cui si desidera ricevere i boss" const val BDO_BOSS_STOP_COMMAND = "BDOBossStop" - const val BDO_BOSS_STOP_COMMAND_DESCRIPTION = "Questo comando permette disiscriversi agli allarmi dei boss di BDO. \n" + "Il comando può essere lanciato su qualunque canale" + const val BDO_BOSS_STOP_COMMAND_DESCRIPTION = "Questo comando permette disiscriversi agli allarmi dei boss di BDO. \n Il comando può essere lanciato su qualunque canale" const val BDO_NEWS_START_COMMAND = "BDONewsStart" - const val BDO_NEWS_START_COMMAND_DESCRIPTION = "Questo comando permette di iscriversi al feed delle news di BDO. \n" + "Il comando deve essere lanciato sul canale su cui si desidera ricevere le news" + const val BDO_NEWS_START_COMMAND_DESCRIPTION = "Questo comando permette di iscriversi al feed delle news di BDO. \n Il comando deve essere lanciato sul canale su cui si desidera ricevere le news" const val BDO_NEWS_STOP_COMMAND = "BDONewsStop" - const val BDO_NEWS_STOP_COMMAND_DESCRIPTION = "Questo comando permette disiscriversi al feed delle news di BDO. \n" + "Il comando può essere lanciato su qualunque canale" + const val BDO_NEWS_STOP_COMMAND_DESCRIPTION = "Questo comando permette disiscriversi al feed delle news di BDO. \n Il comando può essere lanciato su qualunque canale" const val BDO_PATCH_START_COMMAND = "BDOPatchStart" @@ -63,50 +63,62 @@ class BDOCommand : ListenerAdapter() { val symbolCommand = serverManagementInterface.getSimbolCommand(event.guild.id) - if (checkCommand(event, symbolCommand, BDO_BOSS_START_COMMAND)) { - if (!checkAdminPermission(event)) { - rejectCommand(event) - } else { - bdoBossInterface.setBDOBossChannel(event.guild.id, event.textChannel.id) - sendMessageAddChannel(event, "Invio degli allarmi dei boss di BDO configurato sul canale: ") + when{ + checkCommand(event, symbolCommand, BDO_BOSS_START_COMMAND) -> { + if (checkAdminPermission(event)) { + bdoBossInterface.setBDOBossChannel(event.guild.id, event.textChannel.id) + sendMessageAddChannel(event, "Invio degli allarmi dei boss di BDO configurato sul canale: ") + } else { + rejectCommand(event) + } } - } else if (checkCommand(event, symbolCommand, BDO_BOSS_STOP_COMMAND)) { - if (!checkAdminPermission(event)) { - rejectCommand(event) - } else { - val removedChannelId = bdoBossInterface.removeBDOBossChannel(event.guild.id) - if (removedChannelId != null) - sendMessageRemoveChannel(event, "Invio degli allarmi dei boss di BDO rimosso dal canale: ", removedChannelId) + + checkCommand(event, symbolCommand, BDO_BOSS_STOP_COMMAND) ->{ + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + val removedChannelId = bdoBossInterface.removeBDOBossChannel(event.guild.id) + if (removedChannelId != null) + sendMessageRemoveChannel(event, "Invio degli allarmi dei boss di BDO rimosso dal canale: ", removedChannelId) + } } - } else if (checkCommand(event, symbolCommand, BDO_NEWS_START_COMMAND)) { - if (!checkAdminPermission(event)) { - rejectCommand(event) - } else { - bdoNewsInterface.setBDONewsChannel(event.guild.id, event.textChannel.id) - sendMessageAddChannel(event, "Invio delle news di BDO configurato sul canale: ") + + checkCommand(event, symbolCommand, BDO_NEWS_START_COMMAND) -> { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + bdoNewsInterface.setBDONewsChannel(event.guild.id, event.textChannel.id) + sendMessageAddChannel(event, "Invio delle news di BDO configurato sul canale: ") + } } - } else if (checkCommand(event, symbolCommand, BDO_NEWS_STOP_COMMAND)) { - if (!checkAdminPermission(event)) { - rejectCommand(event) - } else { - val removedChannelId = bdoNewsInterface.removeBDONewsChannel(event.guild.id) - if (removedChannelId != null) - sendMessageRemoveChannel(event, "Invio delle news di BDO rimosso dal canale: ", removedChannelId) + + checkCommand(event, symbolCommand, BDO_NEWS_STOP_COMMAND) -> { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + val removedChannelId = bdoNewsInterface.removeBDONewsChannel(event.guild.id) + if (removedChannelId != null) + sendMessageRemoveChannel(event, "Invio delle news di BDO rimosso dal canale: ", removedChannelId) + } } - } else if (checkCommand(event, symbolCommand, BDO_PATCH_START_COMMAND)) { - if (!checkAdminPermission(event)) { - rejectCommand(event) - } else { - bdoPatchInterface.setBDOPatchChannel(event.guild.id, event.textChannel.id) - sendMessageAddChannel(event, "Invio delle patch di BDO configurato sul canale: ") + + checkCommand(event, symbolCommand, BDO_PATCH_START_COMMAND) -> { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + bdoPatchInterface.setBDOPatchChannel(event.guild.id, event.textChannel.id) + sendMessageAddChannel(event, "Invio delle patch di BDO configurato sul canale: ") + } } - } else if (checkCommand(event, symbolCommand, BDO_PATCH_STOP_COMMAND)) { - if (!checkAdminPermission(event)) { - rejectCommand(event) - } else { - val removedChannelId = bdoPatchInterface.removeBDOPatchChannel(event.guild.id) - if (removedChannelId != null) - sendMessageRemoveChannel(event, "Invio delle patch di BDO rimosso dal canale: ", removedChannelId) + + checkCommand(event, symbolCommand, BDO_PATCH_STOP_COMMAND) -> { + if (!checkAdminPermission(event)) { + rejectCommand(event) + } else { + val removedChannelId = bdoPatchInterface.removeBDOPatchChannel(event.guild.id) + if (removedChannelId != null) + sendMessageRemoveChannel(event, "Invio delle patch di BDO rimosso dal canale: ", removedChannelId) + } } } diff --git a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt index 551083a..f488bcc 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt @@ -71,9 +71,7 @@ class BDORSSReader : RSSReader { } override fun prepareRSStoMessageEmbed(message: RSSMessage): MessageEmbed { - val body = Jsoup.parse(message.doc.toString().replace("(?i)]*>", "br2n")) - .text() - .replace("br2n".toRegex(), "\n") + val body = Jsoup.parse(message.doc.toString().replace("
", "br2n")).text().replace("br2n", "\n") if (!message.doc.select("img").isEmpty()) { //esite 1 immagine val imageUrl = message.doc.select("img")[0].attr("src") diff --git a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt index 8b666ee..ed03ce5 100644 --- a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt +++ b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt @@ -18,7 +18,10 @@ import org.springframework.stereotype.Service import java.awt.Color import java.util.* - +/** + * Classe per contenere comandi di uso generale e di configurazione del bot + * @property serverManagementInterface ServerManagementInterface + */ @Scope(value = "singleton") @Service class GeneralCommand : ListenerAdapter() { @@ -34,6 +37,8 @@ class GeneralCommand : ListenerAdapter() { const val HELP_COMMAND = "help" + const val HELP_COMMAND2 = "aiuto" + const val INFO_COMMAND = "info" const val INFO_COMMAND_DESCRIPTION = "Info del bot." @@ -41,27 +46,28 @@ class GeneralCommand : ListenerAdapter() { } - override fun onMessageReceived(event: MessageReceivedEvent?) { if (event!!.author.isBot) return if (event.isFromType(ChannelType.PRIVATE)) return val symbolCommand = serverManagementInterface.getSimbolCommand(event.guild.id) + when { + checkCommand(event, symbolCommand, CONFIGURATION_COMMAND) -> { + getConfigurationCommand(event) + } - if (checkCommand(event, symbolCommand, CONFIGURATION_COMMAND)) { - getConfigurationCommand(event) - } - - if (checkCommand(event, symbolCommand, HELP_COMMAND)) { - event.author.openPrivateChannel().queue { - it.sendMessage(getHelp(event.guild.id)).queue() + checkCommand(event, symbolCommand, INFO_COMMAND) -> { + event.author.openPrivateChannel().queue { + it.sendMessage(getInfo()).queue() + } } - } - if (checkCommand(event, symbolCommand, INFO_COMMAND)) { - event.author.openPrivateChannel().queue { - it.sendMessage(getInfo()).queue() + checkCommand(event, symbolCommand, HELP_COMMAND) || + checkCommand(event, symbolCommand, HELP_COMMAND2)-> { + event.author.openPrivateChannel().queue { + it.sendMessage(getHelp(event.guild.id)).queue() + } } } diff --git a/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt b/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt index 87927c0..df75a64 100644 --- a/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt +++ b/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt @@ -24,6 +24,8 @@ class JoinListener : ListenerAdapter() { override fun onGuildLeave(event: GuildLeaveEvent?) { serverManagementInterface.deleteServer(event!!.guild.id) + TakaoLog.logInfo("REGISTRAZIONE SERVER RIMOSSA \nID = " + event.guild.id + "\nNOME = " + event.guild.name) + } override fun onGuildUpdateName(event: GuildUpdateNameEvent) { diff --git a/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt b/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt index cc555b8..c2f2273 100644 --- a/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt +++ b/src/main/kotlin/it/discordbot/command/music/MusicCommand.kt @@ -70,5 +70,10 @@ class MusicCommand : ListenerAdapter() { musicManager.clearQueue(event) } + + when{ + checkCommand(event, symbolCommand, "clear") || + checkCommand(event, symbolCommand, "pulisci") -> musicManager.clearQueue(event) + } } } \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt b/src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt index 783964e..6ea2a7d 100644 --- a/src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt @@ -11,7 +11,7 @@ import org.springframework.stereotype.Component class ServerManagementInterface { @Autowired - lateinit private var serverDiscordRepository: ServerDiscordRepository + private lateinit var serverDiscordRepository: ServerDiscordRepository fun getSimbolCommand(serverID: String): String { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b4ad69e..8341fd0 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,5 +7,6 @@ logging.level.root=INFO logging.level.org.springframework.web=DEBUG logging.level.org.hibernate=ERROR +spring.output.ansi.enabled=always #logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n #logging.file=./TakaoLog/log-.log diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..07e68b1 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,47 @@ + + + + + + + + + + ${LOGS}/takaoLog-current.log + + %d %p %C{1.} [%t] %m%n + + + + + ${LOGS}/archived/takaoLog-%d{yyyy-MM-dd}.%i.log + + + 10MB + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt b/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt index d40ac82..940cc41 100644 --- a/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt +++ b/src/test/kotlin/it/discordbot/test/DemoApplicationTests.kt @@ -1,7 +1,7 @@ package it.discordbot.test -import it.discordbot.database.interfaces.BDONewsInterface -import it.discordbot.database.interfaces.ServerManagementInterface +import it.discordbot.database.filter.BDONewsInterface +import it.discordbot.database.filter.ServerManagementInterface import org.junit.Test import org.junit.runner.RunWith import org.springframework.beans.factory.annotation.Autowired @@ -18,14 +18,9 @@ class DemoApplicationTests { @Autowired private lateinit var bdoNewsInterface: BDONewsInterface - @Test - fun testGetSimbol() { - assert(managmentServerDiscord.getSimbolCommand("324517087416549377") == "(") - } - @Test fun testBDONews() { - bdoNewsInterface.getBDONewsList() + bdoNewsInterface.getLastBDONews() } } From 81a80569708760c05c6878d4413806199281e014 Mon Sep 17 00:00:00 2001 From: samuele794 Date: Fri, 17 May 2019 14:29:11 +0200 Subject: [PATCH 07/12] Aggiunta Documentazione --- build.gradle | 8 +++- src/main/kotlin/it/discordbot/TestCommand.kt | 7 --- .../kotlin/it/discordbot/beans/RSSLink.kt | 4 +- .../kotlin/it/discordbot/beans/RSSMessage.kt | 7 +++ .../it/discordbot/beans/ServerDiscord.kt | 10 +++++ .../it/discordbot/beans/ServerToChannel.kt | 8 +++- .../kotlin/it/discordbot/beans/boss/Boss.kt | 6 +++ .../kotlin/it/discordbot/beans/boss/Giorno.kt | 6 +++ .../it/discordbot/command/BDO/BDOCommand.kt | 7 +++ .../command/BDO/RSS/BDONewsRSSScheduler.kt | 12 ++++- .../command/BDO/RSS/BDOPatchRSSScheduler.kt | 12 ++--- .../command/BDO/RSS/BDORSSReader.kt | 11 +++++ .../command/BDO/boss/BDOBossScheduler.kt | 10 ++++- .../discordbot/command/BDO/boss/BossUtil.kt | 45 +++++++++++++++++-- .../it/discordbot/command/ControlCommand.kt | 19 ++++++++ .../command/generalCommand/GeneralCommand.kt | 2 +- .../command/generalCommand/JoinListener.kt | 5 +++ .../discordbot/command/pattern/RSSReader.kt | 4 ++ .../command/pattern/RSSScheduler.kt | 13 +++++- .../command/tpl/atmAlert/ATMCommand.kt | 5 +++ .../command/tpl/atmAlert/ATMRSSReader.kt | 3 ++ .../command/tpl/atmAlert/ATMRSSScheduler.kt | 5 +++ .../tpl/atmAlert/ATMTwitterScheduler.kt | 5 +++ .../it/discordbot/core/JDAController.kt | 10 +++++ .../kotlin/it/discordbot/core/TakaoLog.kt | 3 ++ .../it/discordbot/core/TwitterManager.kt | 14 ++++++ .../database/filter/ATMInterface.kt | 5 +++ .../database/filter/BDOBossInterface.kt | 4 ++ .../database/filter/BDONewsInterface.kt | 5 +++ .../database/filter/BDOPatchInterface.kt | 5 +++ .../filter/ServerManagementInterface.kt | 4 ++ 31 files changed, 240 insertions(+), 24 deletions(-) diff --git a/build.gradle b/build.gradle index 0317500..5ec4d2e 100644 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,8 @@ task dokkaPureKotlindoc(type: org.jetbrains.dokka.gradle.DokkaTask) { outputDirectory = "$buildDir/kotlindoc" jdkVersion = 8 includeNonPublic = true + noJdkLink = false + noStdlibLink = false } task dokkaPureJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) { @@ -55,13 +57,17 @@ task dokkaPureJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) { outputDirectory = "$buildDir/javadoc" jdkVersion = 8 includeNonPublic = true + noJdkLink = false + noStdlibLink = false } task dokkaKotlindocAsJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) { outputFormat = 'html-as-java' - outputDirectory = "$buildDir/javadoc" + outputDirectory = "$buildDir/kotlin-as-javadoc" jdkVersion = 8 includeNonPublic = true + noJdkLink = false + noStdlibLink = false } diff --git a/src/main/kotlin/it/discordbot/TestCommand.kt b/src/main/kotlin/it/discordbot/TestCommand.kt index 3878b77..2e43c10 100644 --- a/src/main/kotlin/it/discordbot/TestCommand.kt +++ b/src/main/kotlin/it/discordbot/TestCommand.kt @@ -1,19 +1,12 @@ package it.discordbot -import it.discordbot.database.interfaces.BDONewsInterface -import net.dv8tion.jda.bot.entities.ApplicationInfo import net.dv8tion.jda.core.events.message.MessageReceivedEvent import net.dv8tion.jda.core.hooks.ListenerAdapter -import net.dv8tion.jda.core.requests.RestAction -import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @Component class TestCommand : ListenerAdapter() { - @Autowired - lateinit var bdoNewsInterface:BDONewsInterface - override fun onMessageReceived(event: MessageReceivedEvent?) { if(event!!.author.isBot) return diff --git a/src/main/kotlin/it/discordbot/beans/RSSLink.kt b/src/main/kotlin/it/discordbot/beans/RSSLink.kt index 732b616..d1284a5 100644 --- a/src/main/kotlin/it/discordbot/beans/RSSLink.kt +++ b/src/main/kotlin/it/discordbot/beans/RSSLink.kt @@ -5,8 +5,6 @@ import javax.persistence.Entity import javax.persistence.Id import javax.persistence.Table -@Entity -@Table(name = "`RSSLink`") /** * Entità che rappresenta la tabella contenitore dei link RSS * @property id Long id riga @@ -14,6 +12,8 @@ import javax.persistence.Table * @property lastPatchBDO String? link dell'ultima patch di BDO * @property lastAtmAlert String? link dell'ultima news di ATM */ +@Entity +@Table(name = "`RSSLink`") class RSSLink { @Id @Column(name = "`id`") diff --git a/src/main/kotlin/it/discordbot/beans/RSSMessage.kt b/src/main/kotlin/it/discordbot/beans/RSSMessage.kt index c812fdc..416cebe 100644 --- a/src/main/kotlin/it/discordbot/beans/RSSMessage.kt +++ b/src/main/kotlin/it/discordbot/beans/RSSMessage.kt @@ -2,4 +2,11 @@ package it.discordbot.beans import org.jsoup.nodes.Document +/** + * Classe che contiene le informazioni utili dei messaggi RSS + * @property title String Titolo del messaggio + * @property link String Link del messaggio per il titolo + * @property doc [Document](https://jsoup.org/apidocs/org/jsoup/nodes/Document.html) Contenuto del messaggio + * @constructor + */ data class RSSMessage(val title: String, val link: String, val doc: Document) \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt b/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt index f053634..7fc921b 100644 --- a/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt +++ b/src/main/kotlin/it/discordbot/beans/ServerDiscord.kt @@ -6,6 +6,16 @@ import javax.persistence.Entity import javax.persistence.Id import javax.persistence.Table +/** + * Entità che rappresenta la tabella dei Server Discord + * @property serverId String? id del server + * @property nameServer String? nome del server + * @property simbolCommand String? simbolo di comando del server + * @property bdoNewsIDChannel String? id del canale per le news di BDO + * @property bdoPatchIDChannel String? id del canale per le path di BDO + * @property bdoBossIDChannel String? id del canale per gli alert dei boss di BDO + * @property atmAlertIDChannel String? id del canale per gli alert e news di ATM + */ @Entity @Table(name = "`ServersDiscord`") class ServerDiscord { diff --git a/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt b/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt index e6f65ab..9d5fabd 100644 --- a/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt +++ b/src/main/kotlin/it/discordbot/beans/ServerToChannel.kt @@ -1,6 +1,12 @@ package it.discordbot.beans - +/** + * Classe contenitore degli id dei server e relativi canali per + * le pubblicazioni schedulate + * @property serverID String id del server + * @property channelID String id del canale + * @constructor + */ data class ServerToChannel(val serverID: String, val channelID: String) { override fun equals(other: Any?): Boolean { return if (other != null) { diff --git a/src/main/kotlin/it/discordbot/beans/boss/Boss.kt b/src/main/kotlin/it/discordbot/beans/boss/Boss.kt index 6e3c447..579a479 100644 --- a/src/main/kotlin/it/discordbot/beans/boss/Boss.kt +++ b/src/main/kotlin/it/discordbot/beans/boss/Boss.kt @@ -1,3 +1,9 @@ package it.discordbot.beans.boss +/** + * Classe contenitore dei boss in una determinata ora + * @property ora String ora di spawn del boss + * @property nomeBoss Array nome o nomi dei boss + * @constructor + */ data class Boss(val ora: String, val nomeBoss: Array) \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt b/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt index 5858073..206e310 100644 --- a/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt +++ b/src/main/kotlin/it/discordbot/beans/boss/Giorno.kt @@ -1,3 +1,9 @@ package it.discordbot.beans.boss +/** + * Classe contenitore dei boss del giorno + * @property giorno String nome del giorno espesso in inglese e in maiuscolo + * @property bosses ArrayList lista dei boss del giorno + * @constructor + */ data class Giorno(val giorno: String, val bosses: ArrayList) \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt b/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt index 3389cb9..9da5792 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt @@ -14,6 +14,13 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.stereotype.Service +/** + * Listener per contenere i comandi di BDO + * @property serverManagementInterface ServerManagementInterface + * @property bdoNewsInterface BDONewsInterface + * @property bdoPatchInterface BDOPatchInterface + * @property bdoBossInterface BDOBossInterface + */ @Scope("singleton") @Service class BDOCommand : ListenerAdapter() { diff --git a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt index 844744f..84f961a 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDONewsRSSScheduler.kt @@ -11,6 +11,11 @@ import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service import java.util.* +/** + * Classe per la schedulaziooe dei messaggi di news di BDO + * @property bdorssReader BDORSSReader + * @property bdoNewsInterface BDONewsInterface + */ @Service class BDONewsRSSScheduler : RSSScheduler { @@ -20,7 +25,12 @@ class BDONewsRSSScheduler : RSSScheduler { @Autowired lateinit var bdoNewsInterface: BDONewsInterface - + /** + * Task per schedulare il controllo e la pubblicazione di una + * nuova news di BDO. + * + * Il controllo è fatto ogni 30 minuti. + */ @Scheduled(fixedRate = 1800000, initialDelay = 1800000) fun taskFeedRSSBDONews() { val rssNewsMessage = bdorssReader.readRSS("https://community.blackdesertonline.com/index.php?forums/news-announcements.181/index.rss") diff --git a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt index 188ef8f..2b898fd 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDOPatchRSSScheduler.kt @@ -38,18 +38,18 @@ class BDOPatchRSSScheduler : RSSScheduler { } - override fun procedurePublish(rssPatchMessage: RSSMessage) { - val patchMessage = bdorssReader.prepareRSStoMessageEmbed(rssPatchMessage) //ottieni il messaggio embedded + override fun procedurePublish(rssMessage: RSSMessage) { + val patchMessage = bdorssReader.prepareRSStoMessageEmbed(rssMessage) //ottieni il messaggio embedded val listNewsChannel = bdoPatchInterface.getBDOPatchChannels() publishMessage(patchMessage, listNewsChannel) - bdoPatchInterface.setLastPatch(rssPatchMessage.link) //salvataggio su db + bdoPatchInterface.setLastPatch(rssMessage.link) //salvataggio su db } - override fun publishMessage(patchMessage: MessageEmbed, servers: ArrayList) { - for (obj in servers) { + override fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList) { + for (obj in serversToChannel) { JDAController.jda.getGuildById(obj.serverID) .getTextChannelById(obj.channelID) - .sendMessage(patchMessage).queue() + .sendMessage(message).queue() } } diff --git a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt index f488bcc..74c71bf 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/RSS/BDORSSReader.kt @@ -14,6 +14,9 @@ import java.awt.Color import java.net.URL import java.util.regex.Pattern +/** + * Classe per leggere gli RSS di BDO + */ @Scope("singleton") @Component class BDORSSReader : RSSReader { @@ -45,6 +48,14 @@ class BDORSSReader : RSSReader { return link.substring(1, link.length - 1).toInt() } + /** + * Metodo per confrontare se una news o una patch di BDO è nuova + * rispetto all'ultima pubblicata dal bot + * + * @param linkRSS String + * @param linkDB String + * @return Boolean + */ fun isNew(linkRSS: String, linkDB: String): Boolean { val regex1 = Pattern.compile( "\\.(\\d+)/?\$", diff --git a/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt b/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt index 31e9be2..b227e50 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/boss/BDOBossScheduler.kt @@ -9,6 +9,11 @@ import java.time.LocalDateTime import java.time.format.TextStyle import java.util.* +/** + * Classe per la schedulazione dei boss + * @property bdoBossInterface BDOBossInterface + * @property bossUtil BossUtil + */ @Scope("singleton") @Service class BDOBossScheduler { @@ -19,12 +24,15 @@ class BDOBossScheduler { @Autowired lateinit var bossUtil: BossUtil + /** + * Job per la schedulazione dei boss + */ @Scheduled(cron = "0 0/5 * * * *") fun bossJob() { val time = LocalDateTime.now() val list = bdoBossInterface.getBDOBossList() bossUtil.getDayBosses(time.dayOfWeek.getDisplayName(TextStyle.FULL, Locale.ENGLISH), list).apply { - bossUtil.processHour(time.hour, time.minute, this) + bossUtil.publishBoss(time.hour, time.minute, this) } } diff --git a/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt b/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt index 9622e69..748f9a7 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt @@ -12,6 +12,10 @@ import java.time.DayOfWeek import java.time.LocalDateTime import java.time.format.DateTimeFormatter +/** + * Classe per processare i boss e ricavare il boss da notificare + * @property bdoBossInterface BDOBossInterface + */ @Scope("singleton") @Component class BossUtil { @@ -19,6 +23,12 @@ class BossUtil { @Autowired lateinit var bdoBossInterface: BDOBossInterface + /** + * Metodo per ottenere il [Giorno] + * @param giorno String nome della giornata corrente in inglese e maiuscolo + * @param list ArrayList lista dei [Giorno] + * @return Giorno? [Giorno] attuale + */ fun getDayBosses(giorno: String, list: ArrayList): Giorno? { val g = giorno.toUpperCase() @@ -30,7 +40,14 @@ class BossUtil { return null } - fun getHourBoss(ora: Int, minuto: Int, list: ArrayList?): Boss? { + /** + * Metodo per ottenere [Boss] + * @param ora Int ora per ricavare il boss + * @param minuto Int minuti per ricavare il boss + * @param list ArrayList? lista dei [Boss] di giornata + * @return Boss? [Boss] prossimo allo spawn + */ + private fun getHourBoss(ora: Int, minuto: Int, list: ArrayList?): Boss? { val time = StringBuilder().apply { append(ora.toString()) append(":") @@ -48,7 +65,13 @@ class BossUtil { } - fun processHour(ora: Int, minuto: Int, giorno: Giorno?) { + /** + * Metodo per iniziare la pubblicazione del boss + * @param ora Int ora attuale + * @param minuto Int minuti attuali + * @param giorno Giorno? [Giorno] attuale + */ + fun publishBoss(ora: Int, minuto: Int, giorno: Giorno?) { when (ora) { 1, 2, 4, 5, 8, 9, 11, 12, 15, 16, 18, 19 -> processMinute4500(ora, minuto, giorno) @@ -57,7 +80,12 @@ class BossUtil { } } - + /** + * Metodo per schedulare i boss che spawnano alle 00 dell'ora successiva + * @param ora Int ora attuale + * @param minuto Int minuti attuali + * @param giorno Giorno? [Giorno] attuale + */ private fun processMinute4500(ora: Int, minuto: Int, giorno: Giorno?) { if (giorno?.giorno.equals(DayOfWeek.WEDNESDAY.name) && (ora == 11 || ora == 12)) return @@ -80,6 +108,12 @@ class BossUtil { } } + /** + * Metodo per schedulare i boss che spawnano alle 15 dell'ora + * @param ora Int ora attuale + * @param minuto Int minuti attuali + * @param giorno Giorno? [Giorno] attuale + */ private fun processMinute0015(ora: Int, minuto: Int, giorno: Giorno?) { if (giorno?.giorno.equals(DayOfWeek.SATURDAY.name) && ora == 22) return @@ -102,6 +136,11 @@ class BossUtil { } } + /** + * Metodo per la pubblicazione effettiva del messaggio + * @param bosses Array? lista nomi dei boss + * @param orarioMancante String tempo mancante allo spawn del boss + */ private fun publish(bosses: Array?, orarioMancante: String) { if (bosses != null) { val listServerChannel = bdoBossInterface.getBDOBossChannels() diff --git a/src/main/kotlin/it/discordbot/command/ControlCommand.kt b/src/main/kotlin/it/discordbot/command/ControlCommand.kt index 9dea433..681ed19 100644 --- a/src/main/kotlin/it/discordbot/command/ControlCommand.kt +++ b/src/main/kotlin/it/discordbot/command/ControlCommand.kt @@ -5,6 +5,16 @@ import net.dv8tion.jda.core.entities.ChannelType import net.dv8tion.jda.core.events.message.MessageReceivedEvent import org.jetbrains.annotations.NotNull +/** + * Metodo per controllare se il comando inserito dall'utente + * è il comando controllato. + * Viene controllato se il messaggio è con il simbolo di comando + * o viene citato il bot. + * @param event MessageReceivedEvent evento del messaggio ricevuto + * @param simbolCommand String simbolo di comando del server + * @param commandName String nome del comando + * @return Boolean il comando confrontato e quello voluto sono uguali + */ fun checkCommand(@NotNull event: MessageReceivedEvent, @NotNull simbolCommand: String, @NotNull commandName: String): Boolean { @@ -25,10 +35,19 @@ fun checkCommand(@NotNull event: MessageReceivedEvent, } } +/** + * Metodo che controlla se l'utente ha i permessi di amministrare il server + * @param event MessageReceivedEvent evento del messaggio ricevuto + * @return Boolean True, l'utente ha permessi amministrativi + */ fun checkAdminPermission(event: MessageReceivedEvent): Boolean { return event.guild.getMember(event.author).hasPermission(Permission.ADMINISTRATOR) } +/** + * Metodo per inviare il messaggio prefatto che l'utente non ha i permessi necessari + * @param event MessageReceivedEvent + */ fun rejectCommand(event: MessageReceivedEvent) { event.textChannel.sendMessage(event.author.name + " non sei autorizzato all'uso di questo comando").queue() } \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt index ed03ce5..1419ecd 100644 --- a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt +++ b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt @@ -19,7 +19,7 @@ import java.awt.Color import java.util.* /** - * Classe per contenere comandi di uso generale e di configurazione del bot + * Listener per contenere comandi di uso generale e di configurazione del bot * @property serverManagementInterface ServerManagementInterface */ @Scope(value = "singleton") diff --git a/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt b/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt index df75a64..7eabab0 100644 --- a/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt +++ b/src/main/kotlin/it/discordbot/command/generalCommand/JoinListener.kt @@ -10,6 +10,11 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.stereotype.Service +/** + * Listener per contenere quando il bot entra o esce + * da un server Discord + * @property serverManagementInterface ServerManagementInterface + */ @Scope("singleton") @Service class JoinListener : ListenerAdapter() { diff --git a/src/main/kotlin/it/discordbot/command/pattern/RSSReader.kt b/src/main/kotlin/it/discordbot/command/pattern/RSSReader.kt index 9d2f23a..d19915d 100644 --- a/src/main/kotlin/it/discordbot/command/pattern/RSSReader.kt +++ b/src/main/kotlin/it/discordbot/command/pattern/RSSReader.kt @@ -3,6 +3,10 @@ package it.discordbot.command.pattern import it.discordbot.beans.RSSMessage import net.dv8tion.jda.core.entities.MessageEmbed +/** + * Interfaccia per la lettura e la conversione + * dei messaggi RSS a MessageEmbed + */ interface RSSReader { fun readRSS(url: String): RSSMessage diff --git a/src/main/kotlin/it/discordbot/command/pattern/RSSScheduler.kt b/src/main/kotlin/it/discordbot/command/pattern/RSSScheduler.kt index 0e21619..d9d3a99 100644 --- a/src/main/kotlin/it/discordbot/command/pattern/RSSScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/pattern/RSSScheduler.kt @@ -4,9 +4,20 @@ import it.discordbot.beans.RSSMessage import it.discordbot.beans.ServerToChannel import net.dv8tion.jda.core.entities.MessageEmbed +/** + * Interfaccia base per i metodi di pubblicazione dei messaggi RSS + */ interface RSSScheduler { - + /** + * Metodo per la preparazione alla pubblicazione dei messaggi RSS + * @param rssMessage RSSMessage messaggio RSS + */ fun procedurePublish(rssMessage: RSSMessage) + /** + * Metodo per la pubblicazione dei messaggi + * @param message MessageEmbed Messaggio + * @param serversToChannel ArrayList Lista server e canali + */ fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList) } \ No newline at end of file diff --git a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt index 4f48a73..405b389 100644 --- a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt +++ b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMCommand.kt @@ -12,6 +12,11 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.stereotype.Service +/** + * Per i comandi dell'ATM + * @property serverManagementInterface ServerManagementInterface + * @property atmInterface ATMInterface + */ @Scope("singleton") @Service class ATMCommand : ListenerAdapter() { diff --git a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt index 2c557f7..784af24 100644 --- a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt +++ b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSReader.kt @@ -14,6 +14,9 @@ import java.awt.Color import java.net.URL import java.util.regex.Pattern +/** + * Classe per leggere il feed RSS di atm + */ @Scope("singleton") @Component class ATMRSSReader : RSSReader { diff --git a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt index 0c78039..beec793 100644 --- a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMRSSScheduler.kt @@ -11,6 +11,11 @@ import org.springframework.context.annotation.Scope import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service +/** + * Classe per la schedulaziooe dei messaggi RSS di ATM + * @property atmrssReader ATMRSSReader + * @property atmInterface ATMInterface + */ @Scope("singleton") @Service class ATMRSSScheduler : RSSScheduler { diff --git a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt index ea0fecf..b44d724 100644 --- a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt @@ -13,6 +13,11 @@ import java.awt.Color import javax.annotation.PostConstruct import kotlin.concurrent.thread +/** + * Classe per la schedulaziooe dei messaggi Twitter di ATM + * @property twitterManager TwitterManager + * @property atmInterface ATMInterface + */ @Scope("singleton") @Service class ATMTwitterScheduler { diff --git a/src/main/kotlin/it/discordbot/core/JDAController.kt b/src/main/kotlin/it/discordbot/core/JDAController.kt index 76b279b..714f87a 100644 --- a/src/main/kotlin/it/discordbot/core/JDAController.kt +++ b/src/main/kotlin/it/discordbot/core/JDAController.kt @@ -14,6 +14,16 @@ import org.springframework.context.annotation.Scope import org.springframework.stereotype.Component import javax.annotation.PostConstruct +/** + * Classe principale di avviamento del Bot Discord + * @property jdaToken String Chiave API per il bot Discord + * @property testCommand TestCommand + * @property generalCommand GeneralCommand + * @property bdoCommand BDOCommand + * @property atmCommand ATMCommand + * @property musicCommand MusicCommand + * @property joinListener JoinListener + */ @Scope(value = "singleton") @Component class JDAController { diff --git a/src/main/kotlin/it/discordbot/core/TakaoLog.kt b/src/main/kotlin/it/discordbot/core/TakaoLog.kt index 3170a32..519c607 100644 --- a/src/main/kotlin/it/discordbot/core/TakaoLog.kt +++ b/src/main/kotlin/it/discordbot/core/TakaoLog.kt @@ -3,6 +3,9 @@ package it.discordbot.core import org.slf4j.LoggerFactory import org.springframework.stereotype.Component +/** + * Logger Unico per il bot + */ @Component class TakaoLog { companion object { diff --git a/src/main/kotlin/it/discordbot/core/TwitterManager.kt b/src/main/kotlin/it/discordbot/core/TwitterManager.kt index 9e05795..533cc43 100644 --- a/src/main/kotlin/it/discordbot/core/TwitterManager.kt +++ b/src/main/kotlin/it/discordbot/core/TwitterManager.kt @@ -10,6 +10,15 @@ import twitter4j.TwitterStreamFactory import twitter4j.conf.ConfigurationBuilder import javax.annotation.PostConstruct +/** + * Classe che si occupa di collegarsi ai sistemi di twitter + * @property twitterConsumerKey String ConsumerKey + * @property twitterConsumerSecret String ConsumerSecret + * @property twitterAccessToken String AccessToken + * @property twitterAccessTokenSecret String AccessTokenSecret + * @property twitterStreamFactory TwitterStreamFactory + * @property twitterStream TwitterStream + */ @Scope("singleton") @Component class TwitterManager { @@ -42,6 +51,11 @@ class TwitterManager { twitterStream = twitterStreamFactory.instance } + /** + * Metodo per aggiungere un listener di Twitter + * @param listener StatusListener + * @return TwitterManager + */ fun setTwitterStreamListener(listener: StatusListener): TwitterManager { twitterStream.addListener(listener) return this diff --git a/src/main/kotlin/it/discordbot/database/filter/ATMInterface.kt b/src/main/kotlin/it/discordbot/database/filter/ATMInterface.kt index fb5500b..9fe8658 100644 --- a/src/main/kotlin/it/discordbot/database/filter/ATMInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/ATMInterface.kt @@ -7,6 +7,11 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.stereotype.Component +/** + * Classe di interfacciamento al db per le funzioni di ATM + * @property serverDiscordRepository ServerDiscordRepository + * @property rssLinkRepository RSSLinkRepository + */ @Scope("singleton") @Component class ATMInterface { diff --git a/src/main/kotlin/it/discordbot/database/filter/BDOBossInterface.kt b/src/main/kotlin/it/discordbot/database/filter/BDOBossInterface.kt index 6230db9..151cb8e 100644 --- a/src/main/kotlin/it/discordbot/database/filter/BDOBossInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/BDOBossInterface.kt @@ -10,6 +10,10 @@ import org.springframework.context.annotation.Scope import org.springframework.core.io.ClassPathResource import org.springframework.stereotype.Controller +/** + * Classe di interfacciamento al db per le funzioni di BDO Boss + * @property serverDiscordRepository ServerDiscordRepository + */ @Scope("singleton") @Controller class BDOBossInterface { diff --git a/src/main/kotlin/it/discordbot/database/filter/BDONewsInterface.kt b/src/main/kotlin/it/discordbot/database/filter/BDONewsInterface.kt index 3d90b55..e48a63c 100644 --- a/src/main/kotlin/it/discordbot/database/filter/BDONewsInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/BDONewsInterface.kt @@ -7,6 +7,11 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.stereotype.Component +/** + * Classe di interfacciamento al db per le funzioni di BDO News + * @property serverDiscordRepository ServerDiscordRepository + * @property rssLinkRepository RSSLinkRepository + */ @Scope("singleton") @Component class BDONewsInterface { diff --git a/src/main/kotlin/it/discordbot/database/filter/BDOPatchInterface.kt b/src/main/kotlin/it/discordbot/database/filter/BDOPatchInterface.kt index 55e4202..1c2462a 100644 --- a/src/main/kotlin/it/discordbot/database/filter/BDOPatchInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/BDOPatchInterface.kt @@ -7,6 +7,11 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.stereotype.Component +/** + * Classe di interfacciamento al db per le funzioni di BDO Patch + * @property serverDiscordRepository ServerDiscordRepository + * @property rssLinkRepository RSSLinkRepository + */ @Scope("singleton") @Component class BDOPatchInterface { diff --git a/src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt b/src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt index 6ea2a7d..b44440a 100644 --- a/src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt +++ b/src/main/kotlin/it/discordbot/database/filter/ServerManagementInterface.kt @@ -6,6 +6,10 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.stereotype.Component +/** + * Classe di interfacciamento al db per le funzioni base del BOT + * @property serverDiscordRepository ServerDiscordRepository + */ @Scope("singleton") @Component class ServerManagementInterface { From 1e93eef4a1f9915fa6550e92e34ad45da11f8b40 Mon Sep 17 00:00:00 2001 From: samuele794 Date: Fri, 17 May 2019 14:32:15 +0200 Subject: [PATCH 08/12] Aggiunto file di configurazione profilo dev --- src/main/resources/application-dev.properties | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/resources/application-dev.properties diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties new file mode 100644 index 0000000..f709004 --- /dev/null +++ b/src/main/resources/application-dev.properties @@ -0,0 +1,20 @@ + +#discord key +discordBot.jdaToken = + +#twitter key +oauth.consumerKey = +oauth.consumerSecret = +oauth.accessToken = +oauth.accessTokenSecret = + +# Datasource +spring.datasource.url= +spring.datasource.username= +spring.datasource.password= +spring.datasource.driver-class-name=org.postgresql.Driver +# JPA +spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=true +spring.jpa.hibernate.naming.physical-strategy =org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl +#spring.jpa.properties.hibernate.format_sql=true From 9074631b8fcc6d39ce99427b5ac69aff511f6f78 Mon Sep 17 00:00:00 2001 From: samuele794 Date: Fri, 17 May 2019 14:37:39 +0200 Subject: [PATCH 09/12] Delete application-dev.properties --- src/main/resources/application-dev.properties | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/main/resources/application-dev.properties diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties deleted file mode 100644 index f709004..0000000 --- a/src/main/resources/application-dev.properties +++ /dev/null @@ -1,20 +0,0 @@ - -#discord key -discordBot.jdaToken = - -#twitter key -oauth.consumerKey = -oauth.consumerSecret = -oauth.accessToken = -oauth.accessTokenSecret = - -# Datasource -spring.datasource.url= -spring.datasource.username= -spring.datasource.password= -spring.datasource.driver-class-name=org.postgresql.Driver -# JPA -spring.jpa.hibernate.ddl-auto=update -spring.jpa.show-sql=true -spring.jpa.hibernate.naming.physical-strategy =org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl -#spring.jpa.properties.hibernate.format_sql=true From 3999d1b62b8cb905542866ea66eca6f6eddc8238 Mon Sep 17 00:00:00 2001 From: samuele794 Date: Fri, 17 May 2019 22:26:14 +0200 Subject: [PATCH 10/12] Aggiunto comando BDOBossTable --- .../it/discordbot/command/BDO/BDOCommand.kt | 18 ++++++++++++++++-- .../command/generalCommand/GeneralCommand.kt | 3 ++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt b/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt index 9da5792..5e147c6 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/BDOCommand.kt @@ -7,12 +7,14 @@ import it.discordbot.database.filter.BDOBossInterface import it.discordbot.database.filter.BDONewsInterface import it.discordbot.database.filter.BDOPatchInterface import it.discordbot.database.filter.ServerManagementInterface +import net.dv8tion.jda.core.EmbedBuilder import net.dv8tion.jda.core.MessageBuilder import net.dv8tion.jda.core.events.message.MessageReceivedEvent import net.dv8tion.jda.core.hooks.ListenerAdapter import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Scope import org.springframework.stereotype.Service +import java.awt.Color /** * Listener per contenere i comandi di BDO @@ -47,6 +49,11 @@ class BDOCommand : ListenerAdapter() { const val BDO_BOSS_STOP_COMMAND_DESCRIPTION = "Questo comando permette disiscriversi agli allarmi dei boss di BDO. \n Il comando può essere lanciato su qualunque canale" + const val BDO_BOSS_TABLE = "BDOBossTable" + + const val BDO_BOSS_TABLE_COMMAND_DESCRIPTION = "Questo comando ti fa vedere la tabella dei boss di BDO." + + const val BDO_NEWS_START_COMMAND = "BDONewsStart" const val BDO_NEWS_START_COMMAND_DESCRIPTION = "Questo comando permette di iscriversi al feed delle news di BDO. \n Il comando deve essere lanciato sul canale su cui si desidera ricevere le news" @@ -70,7 +77,7 @@ class BDOCommand : ListenerAdapter() { val symbolCommand = serverManagementInterface.getSimbolCommand(event.guild.id) - when{ + when { checkCommand(event, symbolCommand, BDO_BOSS_START_COMMAND) -> { if (checkAdminPermission(event)) { bdoBossInterface.setBDOBossChannel(event.guild.id, event.textChannel.id) @@ -80,7 +87,7 @@ class BDOCommand : ListenerAdapter() { } } - checkCommand(event, symbolCommand, BDO_BOSS_STOP_COMMAND) ->{ + checkCommand(event, symbolCommand, BDO_BOSS_STOP_COMMAND) -> { if (!checkAdminPermission(event)) { rejectCommand(event) } else { @@ -90,6 +97,13 @@ class BDOCommand : ListenerAdapter() { } } + checkCommand(event, symbolCommand, BDO_BOSS_TABLE) -> { + event.textChannel.sendMessage(EmbedBuilder().apply { + setImage("https://i.imgur.com/0JdziL3.png") + setColor(Color(40,40,40)) + }.build()).queue() + } + checkCommand(event, symbolCommand, BDO_NEWS_START_COMMAND) -> { if (!checkAdminPermission(event)) { rejectCommand(event) diff --git a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt index 1419ecd..40d7615 100644 --- a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt +++ b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt @@ -64,7 +64,7 @@ class GeneralCommand : ListenerAdapter() { } checkCommand(event, symbolCommand, HELP_COMMAND) || - checkCommand(event, symbolCommand, HELP_COMMAND2)-> { + checkCommand(event, symbolCommand, HELP_COMMAND2) -> { event.author.openPrivateChannel().queue { it.sendMessage(getHelp(event.guild.id)).queue() } @@ -90,6 +90,7 @@ class GeneralCommand : ListenerAdapter() { addField(symbolCommand + BDOCommand.BDO_PATCH_STOP_COMMAND, BDOCommand.BDO_PATCH_STOP_COMMAND_DESCRIPTION, false) addField(symbolCommand + BDOCommand.BDO_BOSS_START_COMMAND, BDOCommand.BDO_BOSS_START_COMMAND_DESCRIPTION, false) addField(symbolCommand + BDOCommand.BDO_BOSS_STOP_COMMAND, BDOCommand.BDO_BOSS_STOP_COMMAND_DESCRIPTION, false) + addField(symbolCommand + BDOCommand.BDO_BOSS_TABLE, BDOCommand.BDO_BOSS_TABLE_COMMAND_DESCRIPTION, false) }.build() } From bce70b76b0f13cb17ddd6ff46dd6ede07e513fa8 Mon Sep 17 00:00:00 2001 From: samuele794 Date: Fri, 17 May 2019 22:38:20 +0200 Subject: [PATCH 11/12] Aggiunto BDOBossTable al sito web aggiornato DOC --- docs/css/docStyle.css | 34 + docs/page/commands.html | 38 + docs/page/documentazione.html | 36 +- docs/page/javadoc/allclasses-frame.html | 61 - docs/page/javadoc/allclasses-noframe.html | 61 - docs/page/javadoc/beans/BDOBossBean/Boss.html | 402 ----- .../javadoc/beans/BDOBossBean/Giorno.html | 377 ---- .../beans/BDOBossBean/class-use/Boss.html | 210 --- .../beans/BDOBossBean/class-use/Giorno.html | 236 --- .../beans/BDOBossBean/package-frame.html | 21 - .../beans/BDOBossBean/package-summary.html | 150 -- .../beans/BDOBossBean/package-tree.html | 138 -- .../beans/BDOBossBean/package-use.html | 185 -- docs/page/javadoc/beans/RSSMessage.html | 450 ----- docs/page/javadoc/beans/Rsslink.html | 445 ----- docs/page/javadoc/beans/ServerToChannel.html | 408 ----- docs/page/javadoc/beans/ServersDiscord.html | 591 ------ .../javadoc/beans/class-use/RSSMessage.html | 226 --- .../page/javadoc/beans/class-use/Rsslink.html | 124 -- .../beans/class-use/ServerToChannel.html | 235 --- .../beans/class-use/ServersDiscord.html | 124 -- docs/page/javadoc/beans/package-frame.html | 23 - docs/page/javadoc/beans/package-summary.html | 164 -- docs/page/javadoc/beans/package-tree.html | 140 -- docs/page/javadoc/beans/package-use.html | 210 --- .../command/pattern/ControlCommand.html | 340 ---- .../pattern/class-use/ControlCommand.html | 124 -- .../command/pattern/package-frame.html | 20 - .../command/pattern/package-summary.html | 144 -- .../javadoc/command/pattern/package-tree.html | 137 -- .../javadoc/command/pattern/package-use.html | 124 -- .../javadoc/command/real/BDO/BDOReceiver.html | 447 ----- .../real/BDO/RSS/BDONewsStartCommand.html | 331 ---- .../real/BDO/RSS/BDONewsStopCommand.html | 331 ---- .../real/BDO/RSS/BDOPatchStartCommand.html | 331 ---- .../real/BDO/RSS/BDOPatchStopCommand.html | 331 ---- .../command/real/BDO/RSS/BDORSSReader.html | 305 ---- .../command/real/BDO/RSS/BDORSScheduler.html | 305 ---- .../RSS/class-use/BDONewsStartCommand.html | 124 -- .../BDO/RSS/class-use/BDONewsStopCommand.html | 124 -- .../RSS/class-use/BDOPatchStartCommand.html | 124 -- .../RSS/class-use/BDOPatchStopCommand.html | 124 -- .../real/BDO/RSS/class-use/BDORSSReader.html | 124 -- .../BDO/RSS/class-use/BDORSScheduler.html | 124 -- .../command/real/BDO/RSS/package-frame.html | 25 - .../command/real/BDO/RSS/package-summary.html | 162 -- .../command/real/BDO/RSS/package-tree.html | 146 -- .../command/real/BDO/RSS/package-use.html | 124 -- .../real/BDO/boss/BDOBossStartCommand.html | 331 ---- .../real/BDO/boss/BDOBossStopCommand.html | 331 ---- .../command/real/BDO/boss/BossJob.html | 281 --- .../command/real/BDO/boss/BossRetriver.html | 380 ---- .../boss/class-use/BDOBossStartCommand.html | 124 -- .../boss/class-use/BDOBossStopCommand.html | 124 -- .../real/BDO/boss/class-use/BossJob.html | 124 -- .../real/BDO/boss/class-use/BossRetriver.html | 124 -- .../command/real/BDO/boss/package-frame.html | 23 - .../real/BDO/boss/package-summary.html | 158 -- .../command/real/BDO/boss/package-tree.html | 144 -- .../command/real/BDO/boss/package-use.html | 124 -- .../real/BDO/class-use/BDOReceiver.html | 124 -- .../command/real/BDO/package-frame.html | 20 - .../command/real/BDO/package-summary.html | 142 -- .../command/real/BDO/package-tree.html | 141 -- .../javadoc/command/real/BDO/package-use.html | 124 -- .../javadoc/command/real/JoinListener.html | 325 ---- .../command/real/class-use/JoinListener.html | 124 -- .../configuration/ConfigurationCommand.html | 347 ---- .../configuration/ConfigurationReceiver.html | 369 ---- .../real/configuration/HelpCommand.html | 331 ---- .../real/configuration/InfoCommand.html | 331 ---- .../class-use/ConfigurationCommand.html | 124 -- .../class-use/ConfigurationReceiver.html | 124 -- .../configuration/class-use/HelpCommand.html | 124 -- .../configuration/class-use/InfoCommand.html | 124 -- .../real/configuration/package-frame.html | 23 - .../real/configuration/package-summary.html | 154 -- .../real/configuration/package-tree.html | 144 -- .../real/configuration/package-use.html | 124 -- .../javadoc/command/real/package-frame.html | 20 - .../javadoc/command/real/package-summary.html | 142 -- .../javadoc/command/real/package-tree.html | 141 -- .../javadoc/command/real/package-use.html | 124 -- .../real/sound/AudioPlayerSendHandler.html | 377 ---- .../command/real/sound/GuildMusicManager.html | 316 ---- .../command/real/sound/MusicManager.html | 701 -------- .../real/sound/PlayerControlCommand.html | 327 ---- .../command/real/sound/TrackScheduler.html | 463 ----- .../class-use/AudioPlayerSendHandler.html | 166 -- .../sound/class-use/GuildMusicManager.html | 195 -- .../real/sound/class-use/MusicManager.html | 164 -- .../sound/class-use/PlayerControlCommand.html | 124 -- .../real/sound/class-use/TrackScheduler.html | 166 -- .../command/real/sound/package-frame.html | 24 - .../command/real/sound/package-summary.html | 166 -- .../command/real/sound/package-tree.html | 149 -- .../command/real/sound/package-use.html | 174 -- .../real/tpl/atmAlert/ATMAlertReceiver.html | 343 ---- .../tpl/atmAlert/ATMAlertStartCommand.html | 331 ---- .../tpl/atmAlert/ATMAlertStopCommand.html | 331 ---- .../real/tpl/atmAlert/ATMRSSReader.html | 284 --- .../real/tpl/atmAlert/AtmScheduler.html | 365 ---- .../atmAlert/class-use/ATMAlertReceiver.html | 124 -- .../class-use/ATMAlertStartCommand.html | 124 -- .../class-use/ATMAlertStopCommand.html | 124 -- .../tpl/atmAlert/class-use/ATMRSSReader.html | 124 -- .../tpl/atmAlert/class-use/AtmScheduler.html | 124 -- .../real/tpl/atmAlert/package-frame.html | 24 - .../real/tpl/atmAlert/package-summary.html | 158 -- .../real/tpl/atmAlert/package-tree.html | 145 -- .../real/tpl/atmAlert/package-use.html | 124 -- docs/page/javadoc/constant-values.html | 186 -- docs/page/javadoc/deprecated-list.html | 198 -- docs/page/javadoc/help-doc.html | 229 --- docs/page/javadoc/index-files/index-1.html | 167 -- docs/page/javadoc/index-files/index-10.html | 160 -- docs/page/javadoc/index-files/index-11.html | 141 -- docs/page/javadoc/index-files/index-12.html | 152 -- docs/page/javadoc/index-files/index-13.html | 191 -- docs/page/javadoc/index-files/index-14.html | 190 -- docs/page/javadoc/index-files/index-15.html | 133 -- docs/page/javadoc/index-files/index-16.html | 204 --- docs/page/javadoc/index-files/index-17.html | 339 ---- docs/page/javadoc/index-files/index-18.html | 153 -- docs/page/javadoc/index-files/index-19.html | 129 -- docs/page/javadoc/index-files/index-2.html | 223 --- docs/page/javadoc/index-files/index-20.html | 149 -- docs/page/javadoc/index-files/index-3.html | 189 -- docs/page/javadoc/index-files/index-4.html | 150 -- docs/page/javadoc/index-files/index-5.html | 131 -- docs/page/javadoc/index-files/index-6.html | 436 ----- docs/page/javadoc/index-files/index-7.html | 135 -- docs/page/javadoc/index-files/index-8.html | 154 -- docs/page/javadoc/index-files/index-9.html | 137 -- docs/page/javadoc/index.html | 75 - .../javadoc/interfaces/DiscordScheduler.html | 271 --- .../interfaces/DiscordTokenInterfaces.html | 272 --- .../interfaces/PostgreSQLInterface.html | 793 -------- .../interfaces/PropertyInterfaces.html | 271 --- .../SQLiteInterfaces.RSS_DB_COLUMN.html | 369 ---- .../SQLiteInterfaces.SD_DB_COLUMN.html | 406 ----- .../javadoc/interfaces/SQLiteInterfaces.html | 896 --------- docs/page/javadoc/interfaces/TakaoLog.html | 333 ---- .../javadoc/interfaces/TwitterManager.html | 359 ---- .../class-use/DiscordScheduler.html | 124 -- .../class-use/DiscordTokenInterfaces.html | 124 -- .../class-use/PostgreSQLInterface.html | 124 -- .../class-use/PropertyInterfaces.html | 124 -- .../SQLiteInterfaces.RSS_DB_COLUMN.html | 173 -- .../SQLiteInterfaces.SD_DB_COLUMN.html | 173 -- .../class-use/SQLiteInterfaces.html | 124 -- .../interfaces/class-use/TakaoLog.html | 124 -- .../interfaces/class-use/TwitterManager.html | 194 -- .../javadoc/interfaces/package-frame.html | 31 - .../javadoc/interfaces/package-summary.html | 189 -- .../page/javadoc/interfaces/package-tree.html | 156 -- docs/page/javadoc/interfaces/package-use.html | 187 -- docs/page/javadoc/overview-frame.html | 32 - docs/page/javadoc/overview-summary.html | 182 -- docs/page/javadoc/overview-tree.html | 209 --- docs/page/javadoc/package-list | 12 - docs/page/javadoc/script.js | 30 - docs/page/javadoc/starter/Start.html | 320 ---- .../page/javadoc/starter/class-use/Start.html | 124 -- docs/page/javadoc/starter/package-frame.html | 20 - .../page/javadoc/starter/package-summary.html | 142 -- docs/page/javadoc/starter/package-tree.html | 137 -- docs/page/javadoc/starter/package-use.html | 124 -- docs/page/javadoc/stylesheet.css | 574 ------ docs/page/kotlindoc/alltypes/index.html | 266 +++ docs/page/kotlindoc/index-outline.html | 1597 +++++++++++++++++ docs/page/kotlindoc/index.html | 121 ++ .../-boss/-init-.html | 16 + .../it.discordbot.beans.boss/-boss/index.html | 49 + .../-boss/nome-boss.html | 18 + .../it.discordbot.beans.boss/-boss/ora.html | 18 + .../-giorno/-init-.html | 16 + .../-giorno/bosses.html | 18 + .../-giorno/giorno.html | 18 + .../-giorno/index.html | 49 + .../it.discordbot.beans.boss/index.html | 35 + .../-r-s-s-link/-init-.html | 15 + .../it.discordbot.beans/-r-s-s-link/id.html | 18 + .../-r-s-s-link/index.html | 69 + .../-r-s-s-link/last-atm-alert.html | 15 + .../-r-s-s-link/last-news-b-d-o.html | 15 + .../-r-s-s-link/last-patch-b-d-o.html | 15 + .../-r-s-s-message/-init-.html | 16 + .../-r-s-s-message/doc.html | 18 + .../-r-s-s-message/index.html | 58 + .../-r-s-s-message/link.html | 18 + .../-r-s-s-message/title.html | 18 + .../-server-discord/-init-.html | 15 + .../atm-alert-i-d-channel.html | 15 + .../-server-discord/bdo-boss-i-d-channel.html | 15 + .../-server-discord/bdo-news-i-d-channel.html | 15 + .../bdo-patch-i-d-channel.html | 15 + .../-server-discord/index.html | 96 + .../-server-discord/name-server.html | 15 + .../-server-discord/server-id.html | 15 + .../-server-discord/simbol-command.html | 15 + .../-server-to-channel/-init-.html | 16 + .../-server-to-channel/channel-i-d.html | 18 + .../-server-to-channel/equals.html | 14 + .../-server-to-channel/index.html | 62 + .../-server-to-channel/server-i-d.html | 18 + .../kotlindoc/it.discordbot.beans/index.html | 54 + .../-b-d-o-news-r-s-s-scheduler/-init-.html | 15 + .../bdo-news-interface.html | 18 + .../bdorss-reader.html | 18 + .../-b-d-o-news-r-s-s-scheduler/index.html | 84 + .../procedure-publish.html | 19 + .../publish-message.html | 21 + .../task-feed-r-s-s-b-d-o-news.html | 17 + .../-b-d-o-patch-r-s-s-scheduler/-init-.html | 14 + .../bdo-patch-interface.html | 14 + .../bdorss-reader.html | 14 + .../-b-d-o-patch-r-s-s-scheduler/index.html | 74 + .../procedure-publish.html | 19 + .../publish-message.html | 21 + .../task-feed-r-s-s-b-d-o-patch.html | 14 + .../-b-d-o-r-s-s-reader/-init-.html | 15 + .../-b-d-o-r-s-s-reader/index.html | 66 + .../-b-d-o-r-s-s-reader/is-new.html | 23 + .../link-number-parser.html | 14 + .../prepare-r-s-sto-message-embed.html | 15 + .../-b-d-o-r-s-s-reader/read-r-s-s.html | 21 + .../index.html | 42 + .../-b-d-o-boss-scheduler/-init-.html | 15 + .../bdo-boss-interface.html | 18 + .../-b-d-o-boss-scheduler/boss-job.html | 15 + .../-b-d-o-boss-scheduler/boss-util.html | 18 + .../-b-d-o-boss-scheduler/index.html | 65 + .../-boss-util/-init-.html | 15 + .../-boss-util/bdo-boss-interface.html | 18 + .../-boss-util/get-day-bosses.html | 22 + .../-boss-util/get-hour-boss.html | 24 + .../-boss-util/index.html | 101 ++ .../-boss-util/process-hour.html | 14 + .../-boss-util/process-minute0015.html | 22 + .../-boss-util/process-minute4500.html | 22 + .../-boss-util/publish-boss.html | 22 + .../-boss-util/publish.html | 20 + .../index.html | 35 + ...-o_-b-o-s-s_-s-t-a-r-t_-c-o-m-m-a-n-d.html | 14 + ...-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html | 14 + ...-d-o_-b-o-s-s_-s-t-o-p_-c-o-m-m-a-n-d.html | 14 + ...-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html | 14 + ...-o_-n-e-w-s_-s-t-a-r-t_-c-o-m-m-a-n-d.html | 14 + ...-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html | 14 + ...-d-o_-n-e-w-s_-s-t-o-p_-c-o-m-m-a-n-d.html | 14 + ...-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html | 14 + ..._-p-a-t-c-h_-s-t-a-r-t_-c-o-m-m-a-n-d.html | 14 + ...-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html | 14 + ...-o_-p-a-t-c-h_-s-t-o-p_-c-o-m-m-a-n-d.html | 14 + ...-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html | 14 + .../-b-d-o-command/-init-.html | 15 + .../-b-d-o-command/bdo-boss-interface.html | 18 + .../-b-d-o-command/bdo-news-interface.html | 18 + .../-b-d-o-command/bdo-patch-interface.html | 18 + .../-b-d-o-command/index.html | 184 ++ .../-b-d-o-command/on-message-received.html | 14 + .../send-message-add-channel.html | 14 + .../send-message-remove-channel.html | 14 + .../server-management-interface.html | 18 + .../it.discordbot.command.-b-d-o/index.html | 26 + ...-n-f-i-g-u-r-a-t-i-o-n_-c-o-m-m-a-n-d.html | 14 + ...-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html | 14 + .../-h-e-l-p_-c-o-m-m-a-n-d.html | 14 + .../-h-e-l-p_-c-o-m-m-a-n-d2.html | 14 + .../-i-n-f-o_-c-o-m-m-a-n-d.html | 14 + ...-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html | 14 + .../-general-command/-init-.html | 15 + .../-general-command/configure-symbol.html | 14 + .../get-configuration-command.html | 14 + .../-general-command/get-help.html | 14 + .../-general-command/get-info.html | 14 + .../-general-command/index.html | 129 ++ .../-general-command/on-message-received.html | 14 + .../server-management-interface.html | 18 + .../-join-listener/-init-.html | 16 + .../-join-listener/index.html | 70 + .../-join-listener/on-guild-join.html | 14 + .../-join-listener/on-guild-leave.html | 14 + .../-join-listener/on-guild-update-name.html | 14 + .../server-management-interface.html | 18 + .../index.html | 36 + .../-audio-player-send-handler/-init-.html | 14 + .../audio-player.html | 14 + .../can-provide.html | 14 + .../-audio-player-send-handler/index.html | 70 + .../-audio-player-send-handler/is-opus.html | 14 + .../last-frame.html | 14 + .../provide20-ms-audio.html | 14 + .../-guild-music-manager/-init-.html | 14 + .../-guild-music-manager/index.html | 58 + .../-guild-music-manager/manager.html | 14 + .../-guild-music-manager/player.html | 14 + .../-guild-music-manager/scheduler.html | 14 + .../-guild-music-manager/send-handler.html | 14 + .../-d-e-f-a-u-l-t_-v-o-l-u-m-e.html | 14 + .../-music-manager/-init-.html | 14 + .../-music-manager/change-volume.html | 19 + .../-music-manager/clear-queue.html | 14 + .../-music-manager/get-list-queue.html | 18 + .../-music-manager/get-music-manager.html | 14 + .../-music-manager/get-timestamp.html | 14 + .../-music-manager/get-url.html | 20 + .../-music-manager/index.html | 225 +++ .../-music-manager/join.html | 18 + .../-music-manager/leave.html | 19 + .../-music-manager/load-and-play.html | 24 + .../-music-manager/music-managers.html | 14 + .../-music-manager/now-play.html | 18 + .../-music-manager/pause-resume.html | 19 + .../-music-manager/play-playlist.html | 18 + .../-music-manager/play.html | 18 + .../-music-manager/player-manager.html | 14 + .../-music-manager/repeat.html | 18 + .../-music-manager/reset.html | 19 + .../-music-manager/restart.html | 18 + .../-music-manager/shuffle-queue.html | 18 + .../-music-manager/skip.html | 18 + .../-music-manager/stop.html | 18 + .../-track-scheduler/-init-.html | 14 + .../-track-scheduler/index.html | 109 ++ .../-track-scheduler/is-repeating.html | 14 + .../-track-scheduler/last-track.html | 14 + .../-track-scheduler/next-track.html | 15 + .../-track-scheduler/on-track-end.html | 14 + .../-track-scheduler/player.html | 14 + .../-track-scheduler/queue.html | 19 + .../-track-scheduler/repeating.html | 14 + .../-track-scheduler/set-repeating.html | 14 + .../-track-scheduler/shuffle.html | 14 + .../index.html | 45 + .../-music-command/-init-.html | 14 + .../-music-command/index.html | 56 + .../-music-command/music-manager.html | 14 + .../-music-command/on-message-received.html | 14 + .../server-management-interface.html | 14 + .../it.discordbot.command.music/index.html | 24 + .../-r-s-s-reader/index.html | 57 + .../prepare-r-s-sto-message-embed.html | 14 + .../-r-s-s-reader/read-r-s-s.html | 14 + .../-r-s-s-scheduler/index.html | 67 + .../-r-s-s-scheduler/procedure-publish.html | 18 + .../-r-s-s-scheduler/publish-message.html | 20 + .../it.discordbot.command.pattern/index.html | 36 + .../-a-t-m_-s-t-a-r-t_-c-o-m-m-a-n-d.html | 14 + ...-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html | 14 + .../-a-t-m_-s-t-o-p_-c-o-m-m-a-n-d.html | 14 + ...-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html | 14 + .../-a-t-m-command/-init-.html | 15 + .../-a-t-m-command/atm-interface.html | 18 + .../-a-t-m-command/index.html | 96 + .../-a-t-m-command/on-message-received.html | 14 + .../server-management-interface.html | 18 + .../-a-t-m_-l-o-g-o_-r-s-s.html | 14 + .../-a-t-m-r-s-s-reader/-init-.html | 15 + .../-a-t-m-r-s-s-reader/index.html | 59 + .../prepare-r-s-sto-message-embed.html | 15 + .../-a-t-m-r-s-s-reader/read-r-s-s.html | 15 + .../-a-t-m_-r-s-s_-l-i-n-k.html | 14 + .../-a-t-m-r-s-s-scheduler/-init-.html | 15 + .../-a-t-m-r-s-s-scheduler/atm-interface.html | 18 + .../-a-t-m-r-s-s-scheduler/atmrss-reader.html | 18 + .../-a-t-m-r-s-s-scheduler/index.html | 93 + .../procedure-publish.html | 19 + .../publish-message.html | 21 + .../task-feed-r-s-s-a-t-m.html | 14 + .../-a-t-m_-t-w-i-t-t-e-r_-i-d.html | 14 + .../-a-t-m-twitter-scheduler/-init-.html | 15 + .../-q-u-e-r-y_-p-a-r-a-m.html | 14 + .../-t-w-i-t-t-e-r_-i-m-a-g-e.html | 14 + .../-t-w-i-t-t-e-r_-u-r-l.html | 14 + .../atm-interface.html | 18 + .../-a-t-m-twitter-scheduler/index.html | 103 ++ .../init-a-t-m-twitter-scheduler.html | 14 + .../-a-t-m-twitter-scheduler/publish.html | 14 + .../twitter-manager.html | 18 + .../index.html | 53 + .../check-admin-permission.html | 20 + .../it.discordbot.command/check-command.html | 27 + .../it.discordbot.command/index.html | 47 + .../it.discordbot.command/reject-command.html | 18 + .../-j-d-a-controller/-init-.html | 15 + .../-j-d-a-controller/atm-command.html | 18 + .../-j-d-a-controller/bdo-command.html | 18 + .../-j-d-a-controller/general-command.html | 18 + .../-j-d-a-controller/index.html | 120 ++ .../-j-d-a-controller/init.html | 14 + .../-j-d-a-controller/jda-token.html | 18 + .../-j-d-a-controller/jda.html | 14 + .../-j-d-a-controller/join-listener.html | 18 + .../-j-d-a-controller/music-command.html | 18 + .../-j-d-a-controller/test-command.html | 18 + .../it.discordbot.core/-takao-log/-init-.html | 15 + .../it.discordbot.core/-takao-log/index.html | 66 + .../-takao-log/log-debug.html | 14 + .../-takao-log/log-error.html | 14 + .../-takao-log/log-info.html | 14 + .../it.discordbot.core/-takao-log/logger.html | 14 + .../-twitter-manager/-init-.html | 15 + .../-twitter-manager/get-twitter-stream.html | 14 + .../-twitter-manager/index.html | 122 ++ .../-twitter-manager/init-twitter.html | 14 + .../set-twitter-stream-filter.html | 14 + .../set-twitter-stream-listener.html | 20 + .../twitter-access-token-secret.html | 18 + .../twitter-access-token.html | 18 + .../twitter-consumer-key.html | 18 + .../twitter-consumer-secret.html | 18 + .../twitter-stream-factory.html | 18 + .../-twitter-manager/twitter-stream.html | 18 + .../kotlindoc/it.discordbot.core/index.html | 44 + .../-a-t-m-interface/-init-.html | 15 + .../get-a-t-m-alert-channels.html | 14 + .../get-last-a-t-m-alert.html | 14 + .../-a-t-m-interface/index.html | 91 + .../remove-a-t-m-alert-channel.html | 14 + .../-a-t-m-interface/rss-link-repository.html | 18 + .../server-discord-repository.html | 18 + .../set-a-t-m-alert-channel.html | 14 + .../set-last-a-t-m-alert.html | 14 + .../-b-d-o-boss-interface/-init-.html | 15 + .../get-b-d-o-boss-channels.html | 14 + .../get-b-d-o-boss-list.html | 14 + .../-b-d-o-boss-interface/index.html | 75 + .../remove-b-d-o-boss-channel.html | 14 + .../server-discord-repository.html | 18 + .../set-b-d-o-boss-channel.html | 14 + .../-b-d-o-news-interface/-init-.html | 15 + .../get-b-d-o-news-channels.html | 14 + .../get-last-b-d-o-news.html | 14 + .../-b-d-o-news-interface/index.html | 91 + .../remove-b-d-o-news-channel.html | 14 + .../rss-link-repository.html | 18 + .../server-discord-repository.html | 18 + .../set-b-d-o-news-channel.html | 14 + .../-b-d-o-news-interface/set-b-d-o-news.html | 14 + .../-b-d-o-patch-interface/-init-.html | 15 + .../get-b-d-o-patch-channels.html | 14 + .../get-last-b-d-o-patch.html | 14 + .../-b-d-o-patch-interface/index.html | 91 + .../remove-b-d-o-patch-channel.html | 14 + .../rss-link-repository.html | 18 + .../server-discord-repository.html | 18 + .../set-b-d-o-patch-channel.html | 14 + .../set-last-patch.html | 14 + .../-server-management-interface/-init-.html | 15 + .../delete-server.html | 14 + .../get-simbol-command.html | 14 + .../-server-management-interface/index.html | 75 + .../new-server.html | 14 + .../server-discord-repository.html | 18 + .../set-simbol-command.html | 14 + .../it.discordbot.database.filter/index.html | 62 + .../get-first-by-id.html | 14 + .../-r-s-s-link-repository/index.html | 25 + .../find-server-discord-by-server-id.html | 14 + .../get-all-a-t-m-alert-channels.html | 14 + .../get-all-b-d-o-boss-channels.html | 14 + .../get-all-b-d-o-news-channels.html | 14 + .../get-all-b-d-o-patch-channels.html | 14 + .../-server-discord-repository/index.html | 53 + .../index.html | 31 + .../it.discordbot/-start-bot/-init-.html | 14 + .../it.discordbot/-start-bot/index.html | 25 + .../it.discordbot/-test-command/-init-.html | 14 + .../-test-command/bdo-news-interface.html | 14 + .../it.discordbot/-test-command/index.html | 37 + .../-test-command/on-message-received.html | 14 + docs/page/kotlindoc/it.discordbot/index.html | 43 + docs/page/kotlindoc/it.discordbot/main.html | 14 + docs/page/kotlindoc/package-list | 18 + docs/page/kotlindoc/style.css | 283 +++ 477 files changed, 9996 insertions(+), 33781 deletions(-) create mode 100644 docs/css/docStyle.css delete mode 100644 docs/page/javadoc/allclasses-frame.html delete mode 100644 docs/page/javadoc/allclasses-noframe.html delete mode 100644 docs/page/javadoc/beans/BDOBossBean/Boss.html delete mode 100644 docs/page/javadoc/beans/BDOBossBean/Giorno.html delete mode 100644 docs/page/javadoc/beans/BDOBossBean/class-use/Boss.html delete mode 100644 docs/page/javadoc/beans/BDOBossBean/class-use/Giorno.html delete mode 100644 docs/page/javadoc/beans/BDOBossBean/package-frame.html delete mode 100644 docs/page/javadoc/beans/BDOBossBean/package-summary.html delete mode 100644 docs/page/javadoc/beans/BDOBossBean/package-tree.html delete mode 100644 docs/page/javadoc/beans/BDOBossBean/package-use.html delete mode 100644 docs/page/javadoc/beans/RSSMessage.html delete mode 100644 docs/page/javadoc/beans/Rsslink.html delete mode 100644 docs/page/javadoc/beans/ServerToChannel.html delete mode 100644 docs/page/javadoc/beans/ServersDiscord.html delete mode 100644 docs/page/javadoc/beans/class-use/RSSMessage.html delete mode 100644 docs/page/javadoc/beans/class-use/Rsslink.html delete mode 100644 docs/page/javadoc/beans/class-use/ServerToChannel.html delete mode 100644 docs/page/javadoc/beans/class-use/ServersDiscord.html delete mode 100644 docs/page/javadoc/beans/package-frame.html delete mode 100644 docs/page/javadoc/beans/package-summary.html delete mode 100644 docs/page/javadoc/beans/package-tree.html delete mode 100644 docs/page/javadoc/beans/package-use.html delete mode 100644 docs/page/javadoc/command/pattern/ControlCommand.html delete mode 100644 docs/page/javadoc/command/pattern/class-use/ControlCommand.html delete mode 100644 docs/page/javadoc/command/pattern/package-frame.html delete mode 100644 docs/page/javadoc/command/pattern/package-summary.html delete mode 100644 docs/page/javadoc/command/pattern/package-tree.html delete mode 100644 docs/page/javadoc/command/pattern/package-use.html delete mode 100644 docs/page/javadoc/command/real/BDO/BDOReceiver.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/BDONewsStartCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/BDONewsStopCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/BDOPatchStartCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/BDOPatchStopCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/BDORSSReader.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/BDORSScheduler.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/class-use/BDONewsStartCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/class-use/BDONewsStopCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/class-use/BDOPatchStartCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/class-use/BDOPatchStopCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/class-use/BDORSSReader.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/class-use/BDORSScheduler.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/package-frame.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/package-summary.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/package-tree.html delete mode 100644 docs/page/javadoc/command/real/BDO/RSS/package-use.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/BDOBossStartCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/BDOBossStopCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/BossJob.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/BossRetriver.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/class-use/BDOBossStartCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/class-use/BDOBossStopCommand.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/class-use/BossJob.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/class-use/BossRetriver.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/package-frame.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/package-summary.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/package-tree.html delete mode 100644 docs/page/javadoc/command/real/BDO/boss/package-use.html delete mode 100644 docs/page/javadoc/command/real/BDO/class-use/BDOReceiver.html delete mode 100644 docs/page/javadoc/command/real/BDO/package-frame.html delete mode 100644 docs/page/javadoc/command/real/BDO/package-summary.html delete mode 100644 docs/page/javadoc/command/real/BDO/package-tree.html delete mode 100644 docs/page/javadoc/command/real/BDO/package-use.html delete mode 100644 docs/page/javadoc/command/real/JoinListener.html delete mode 100644 docs/page/javadoc/command/real/class-use/JoinListener.html delete mode 100644 docs/page/javadoc/command/real/configuration/ConfigurationCommand.html delete mode 100644 docs/page/javadoc/command/real/configuration/ConfigurationReceiver.html delete mode 100644 docs/page/javadoc/command/real/configuration/HelpCommand.html delete mode 100644 docs/page/javadoc/command/real/configuration/InfoCommand.html delete mode 100644 docs/page/javadoc/command/real/configuration/class-use/ConfigurationCommand.html delete mode 100644 docs/page/javadoc/command/real/configuration/class-use/ConfigurationReceiver.html delete mode 100644 docs/page/javadoc/command/real/configuration/class-use/HelpCommand.html delete mode 100644 docs/page/javadoc/command/real/configuration/class-use/InfoCommand.html delete mode 100644 docs/page/javadoc/command/real/configuration/package-frame.html delete mode 100644 docs/page/javadoc/command/real/configuration/package-summary.html delete mode 100644 docs/page/javadoc/command/real/configuration/package-tree.html delete mode 100644 docs/page/javadoc/command/real/configuration/package-use.html delete mode 100644 docs/page/javadoc/command/real/package-frame.html delete mode 100644 docs/page/javadoc/command/real/package-summary.html delete mode 100644 docs/page/javadoc/command/real/package-tree.html delete mode 100644 docs/page/javadoc/command/real/package-use.html delete mode 100644 docs/page/javadoc/command/real/sound/AudioPlayerSendHandler.html delete mode 100644 docs/page/javadoc/command/real/sound/GuildMusicManager.html delete mode 100644 docs/page/javadoc/command/real/sound/MusicManager.html delete mode 100644 docs/page/javadoc/command/real/sound/PlayerControlCommand.html delete mode 100644 docs/page/javadoc/command/real/sound/TrackScheduler.html delete mode 100644 docs/page/javadoc/command/real/sound/class-use/AudioPlayerSendHandler.html delete mode 100644 docs/page/javadoc/command/real/sound/class-use/GuildMusicManager.html delete mode 100644 docs/page/javadoc/command/real/sound/class-use/MusicManager.html delete mode 100644 docs/page/javadoc/command/real/sound/class-use/PlayerControlCommand.html delete mode 100644 docs/page/javadoc/command/real/sound/class-use/TrackScheduler.html delete mode 100644 docs/page/javadoc/command/real/sound/package-frame.html delete mode 100644 docs/page/javadoc/command/real/sound/package-summary.html delete mode 100644 docs/page/javadoc/command/real/sound/package-tree.html delete mode 100644 docs/page/javadoc/command/real/sound/package-use.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertReceiver.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertStartCommand.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertStopCommand.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/ATMRSSReader.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/AtmScheduler.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertReceiver.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertStartCommand.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertStopCommand.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMRSSReader.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/class-use/AtmScheduler.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/package-frame.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/package-summary.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/package-tree.html delete mode 100644 docs/page/javadoc/command/real/tpl/atmAlert/package-use.html delete mode 100644 docs/page/javadoc/constant-values.html delete mode 100644 docs/page/javadoc/deprecated-list.html delete mode 100644 docs/page/javadoc/help-doc.html delete mode 100644 docs/page/javadoc/index-files/index-1.html delete mode 100644 docs/page/javadoc/index-files/index-10.html delete mode 100644 docs/page/javadoc/index-files/index-11.html delete mode 100644 docs/page/javadoc/index-files/index-12.html delete mode 100644 docs/page/javadoc/index-files/index-13.html delete mode 100644 docs/page/javadoc/index-files/index-14.html delete mode 100644 docs/page/javadoc/index-files/index-15.html delete mode 100644 docs/page/javadoc/index-files/index-16.html delete mode 100644 docs/page/javadoc/index-files/index-17.html delete mode 100644 docs/page/javadoc/index-files/index-18.html delete mode 100644 docs/page/javadoc/index-files/index-19.html delete mode 100644 docs/page/javadoc/index-files/index-2.html delete mode 100644 docs/page/javadoc/index-files/index-20.html delete mode 100644 docs/page/javadoc/index-files/index-3.html delete mode 100644 docs/page/javadoc/index-files/index-4.html delete mode 100644 docs/page/javadoc/index-files/index-5.html delete mode 100644 docs/page/javadoc/index-files/index-6.html delete mode 100644 docs/page/javadoc/index-files/index-7.html delete mode 100644 docs/page/javadoc/index-files/index-8.html delete mode 100644 docs/page/javadoc/index-files/index-9.html delete mode 100644 docs/page/javadoc/index.html delete mode 100644 docs/page/javadoc/interfaces/DiscordScheduler.html delete mode 100644 docs/page/javadoc/interfaces/DiscordTokenInterfaces.html delete mode 100644 docs/page/javadoc/interfaces/PostgreSQLInterface.html delete mode 100644 docs/page/javadoc/interfaces/PropertyInterfaces.html delete mode 100644 docs/page/javadoc/interfaces/SQLiteInterfaces.RSS_DB_COLUMN.html delete mode 100644 docs/page/javadoc/interfaces/SQLiteInterfaces.SD_DB_COLUMN.html delete mode 100644 docs/page/javadoc/interfaces/SQLiteInterfaces.html delete mode 100644 docs/page/javadoc/interfaces/TakaoLog.html delete mode 100644 docs/page/javadoc/interfaces/TwitterManager.html delete mode 100644 docs/page/javadoc/interfaces/class-use/DiscordScheduler.html delete mode 100644 docs/page/javadoc/interfaces/class-use/DiscordTokenInterfaces.html delete mode 100644 docs/page/javadoc/interfaces/class-use/PostgreSQLInterface.html delete mode 100644 docs/page/javadoc/interfaces/class-use/PropertyInterfaces.html delete mode 100644 docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.RSS_DB_COLUMN.html delete mode 100644 docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.SD_DB_COLUMN.html delete mode 100644 docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.html delete mode 100644 docs/page/javadoc/interfaces/class-use/TakaoLog.html delete mode 100644 docs/page/javadoc/interfaces/class-use/TwitterManager.html delete mode 100644 docs/page/javadoc/interfaces/package-frame.html delete mode 100644 docs/page/javadoc/interfaces/package-summary.html delete mode 100644 docs/page/javadoc/interfaces/package-tree.html delete mode 100644 docs/page/javadoc/interfaces/package-use.html delete mode 100644 docs/page/javadoc/overview-frame.html delete mode 100644 docs/page/javadoc/overview-summary.html delete mode 100644 docs/page/javadoc/overview-tree.html delete mode 100644 docs/page/javadoc/package-list delete mode 100644 docs/page/javadoc/script.js delete mode 100644 docs/page/javadoc/starter/Start.html delete mode 100644 docs/page/javadoc/starter/class-use/Start.html delete mode 100644 docs/page/javadoc/starter/package-frame.html delete mode 100644 docs/page/javadoc/starter/package-summary.html delete mode 100644 docs/page/javadoc/starter/package-tree.html delete mode 100644 docs/page/javadoc/starter/package-use.html delete mode 100644 docs/page/javadoc/stylesheet.css create mode 100644 docs/page/kotlindoc/alltypes/index.html create mode 100644 docs/page/kotlindoc/index-outline.html create mode 100644 docs/page/kotlindoc/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans.boss/-boss/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans.boss/-boss/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans.boss/-boss/nome-boss.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans.boss/-boss/ora.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/bosses.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/giorno.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans.boss/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/id.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-atm-alert.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-news-b-d-o.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-patch-b-d-o.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/doc.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/link.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/title.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-discord/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-discord/atm-alert-i-d-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-boss-i-d-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-news-i-d-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-patch-i-d-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-discord/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-discord/name-server.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-discord/server-id.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-discord/simbol-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/channel-i-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/equals.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/server-i-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.beans/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/bdo-news-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/bdorss-reader.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/procedure-publish.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/publish-message.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/task-feed-r-s-s-b-d-o-news.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/bdo-patch-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/bdorss-reader.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/procedure-publish.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/publish-message.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/task-feed-r-s-s-b-d-o-patch.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/is-new.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/link-number-parser.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/prepare-r-s-sto-message-embed.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/read-r-s-s.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/bdo-boss-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/boss-job.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/boss-util.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/bdo-boss-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/get-day-bosses.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/get-hour-boss.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-hour.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-minute0015.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-minute4500.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/publish-boss.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/publish.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-a-r-t_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-o-p_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-a-r-t_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-o-p_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-a-r-t_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-o-p_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-boss-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-news-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-patch-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/on-message-received.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/send-message-add-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/send-message-remove-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/server-management-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.-b-d-o/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-c-o-n-f-i-g-u-r-a-t-i-o-n_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-c-o-n-f-i-g-u-r-a-t-i-o-n_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-h-e-l-p_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-h-e-l-p_-c-o-m-m-a-n-d2.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-i-n-f-o_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-i-n-f-o_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/configure-symbol.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-configuration-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-help.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-info.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/on-message-received.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/server-management-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-join.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-leave.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-update-name.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/server-management-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.general-command/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/audio-player.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/can-provide.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/is-opus.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/last-frame.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/provide20-ms-audio.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/manager.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/player.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/scheduler.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/send-handler.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/-d-e-f-a-u-l-t_-v-o-l-u-m-e.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/change-volume.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/clear-queue.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-list-queue.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-music-manager.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-timestamp.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-url.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/join.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/leave.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/load-and-play.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/music-managers.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/now-play.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/pause-resume.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/play-playlist.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/play.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/player-manager.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/repeat.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/reset.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/restart.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/shuffle-queue.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/skip.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/stop.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/is-repeating.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/last-track.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/next-track.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/on-track-end.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/player.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/queue.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/repeating.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/set-repeating.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/shuffle.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music.config/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music/-music-command/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music/-music-command/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music/-music-command/music-manager.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music/-music-command/on-message-received.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music/-music-command/server-management-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.music/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/prepare-r-s-sto-message-embed.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/read-r-s-s.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/procedure-publish.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/publish-message.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.pattern/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-a-r-t_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-o-p_-c-o-m-m-a-n-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/atm-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/on-message-received.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/server-management-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/-a-t-m_-l-o-g-o_-r-s-s.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/prepare-r-s-sto-message-embed.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/read-r-s-s.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/-a-t-m_-r-s-s_-l-i-n-k.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/atm-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/atmrss-reader.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/procedure-publish.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/publish-message.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/task-feed-r-s-s-a-t-m.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-a-t-m_-t-w-i-t-t-e-r_-i-d.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-q-u-e-r-y_-p-a-r-a-m.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-t-w-i-t-t-e-r_-i-m-a-g-e.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-t-w-i-t-t-e-r_-u-r-l.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/atm-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/init-a-t-m-twitter-scheduler.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/publish.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/twitter-manager.html create mode 100644 docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command/check-admin-permission.html create mode 100644 docs/page/kotlindoc/it.discordbot.command/check-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.command/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.command/reject-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/atm-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/bdo-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/general-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/init.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/jda-token.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/jda.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/join-listener.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/music-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/test-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-takao-log/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-takao-log/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-takao-log/log-debug.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-takao-log/log-error.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-takao-log/log-info.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-takao-log/logger.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/get-twitter-stream.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/init-twitter.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/set-twitter-stream-filter.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/set-twitter-stream-listener.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-access-token-secret.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-access-token.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-consumer-key.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-consumer-secret.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-stream-factory.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-stream.html create mode 100644 docs/page/kotlindoc/it.discordbot.core/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/get-a-t-m-alert-channels.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/get-last-a-t-m-alert.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/remove-a-t-m-alert-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/rss-link-repository.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/server-discord-repository.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/set-a-t-m-alert-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/set-last-a-t-m-alert.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/get-b-d-o-boss-channels.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/get-b-d-o-boss-list.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/remove-b-d-o-boss-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/server-discord-repository.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/set-b-d-o-boss-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/get-b-d-o-news-channels.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/get-last-b-d-o-news.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/remove-b-d-o-news-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/rss-link-repository.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/server-discord-repository.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/set-b-d-o-news-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/set-b-d-o-news.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/get-b-d-o-patch-channels.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/get-last-b-d-o-patch.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/remove-b-d-o-patch-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/rss-link-repository.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/server-discord-repository.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/set-b-d-o-patch-channel.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/set-last-patch.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/delete-server.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/get-simbol-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/new-server.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/server-discord-repository.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/set-simbol-command.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.filter/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.repository/-r-s-s-link-repository/get-first-by-id.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.repository/-r-s-s-link-repository/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/find-server-discord-by-server-id.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-a-t-m-alert-channels.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-boss-channels.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-news-channels.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-patch-channels.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/index.html create mode 100644 docs/page/kotlindoc/it.discordbot.database.repository/index.html create mode 100644 docs/page/kotlindoc/it.discordbot/-start-bot/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot/-start-bot/index.html create mode 100644 docs/page/kotlindoc/it.discordbot/-test-command/-init-.html create mode 100644 docs/page/kotlindoc/it.discordbot/-test-command/bdo-news-interface.html create mode 100644 docs/page/kotlindoc/it.discordbot/-test-command/index.html create mode 100644 docs/page/kotlindoc/it.discordbot/-test-command/on-message-received.html create mode 100644 docs/page/kotlindoc/it.discordbot/index.html create mode 100644 docs/page/kotlindoc/it.discordbot/main.html create mode 100644 docs/page/kotlindoc/package-list create mode 100644 docs/page/kotlindoc/style.css diff --git a/docs/css/docStyle.css b/docs/css/docStyle.css new file mode 100644 index 0000000..5315002 --- /dev/null +++ b/docs/css/docStyle.css @@ -0,0 +1,34 @@ +#parent>#button-left { + opacity: 0.3; + position: absolute; + left: 5px; + top: 5px; + transition: 0.5s; +} + +#parent>#button-right { + opacity: 0.3; + position: absolute; + left: 55px; + top: 5px; + transition: 0.5s; +} + +.btn{ + padding: 5px 5px; +} +.svg-arrow{ + margin-top: 10px +} + +iframe{ + background-color: #ffffff; +} + +#parent>#button-left { + opacity: 1; +} + +#parent>#button-right { + opacity: 1; +} \ No newline at end of file diff --git a/docs/page/commands.html b/docs/page/commands.html index 29abd11..988cded 100644 --- a/docs/page/commands.html +++ b/docs/page/commands.html @@ -208,6 +208,21 @@

Indice

BDO Patch Stop + + + + + + @@ -325,6 +340,29 @@

BDO Patch Stop


Il comando può essere lanciato su qualunque canale.

+
+

BDO Boss Start

+

+ %BDOBossStart
+ Questo comando permette di iscriversi agli allarmi dei boss di BDO. +
+ Il comando deve essere lanciato sul canale su cui si desidera + ricevere i boss. +

+
+

BDO Boss Stop

+

+ %BDOBossStopt
+ Questo comando permette disiscriversi agli allarmi dei boss di BDO. +
+ Il comando può essere lanciato su qualunque canale +

+
+

BDO Boss Table

+

+ %BDOBossTable
+ Questo comando ti fa vedere la tabella dei boss di BDO. +


diff --git a/docs/page/documentazione.html b/docs/page/documentazione.html index 56f0f69..afe3c91 100644 --- a/docs/page/documentazione.html +++ b/docs/page/documentazione.html @@ -14,11 +14,25 @@ + + + @@ -129,9 +143,21 @@

TakaoBot

-
- +
+ + + +
@@ -180,7 +206,9 @@

  • - + diff --git a/docs/page/javadoc/allclasses-frame.html b/docs/page/javadoc/allclasses-frame.html deleted file mode 100644 index ab5620e..0000000 --- a/docs/page/javadoc/allclasses-frame.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - -All Classes (Documentazione TakaoBot) - - - - - -

    All Classes

    -
    - - diff --git a/docs/page/javadoc/allclasses-noframe.html b/docs/page/javadoc/allclasses-noframe.html deleted file mode 100644 index 074689e..0000000 --- a/docs/page/javadoc/allclasses-noframe.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - -All Classes (Documentazione TakaoBot) - - - - - -

    All Classes

    - - - diff --git a/docs/page/javadoc/beans/BDOBossBean/Boss.html b/docs/page/javadoc/beans/BDOBossBean/Boss.html deleted file mode 100644 index 6c9208c..0000000 --- a/docs/page/javadoc/beans/BDOBossBean/Boss.html +++ /dev/null @@ -1,402 +0,0 @@ - - - - - -Boss (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    beans.BDOBossBean
    -

    Class Boss

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • beans.BDOBossBean.Boss
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class Boss
      -extends java.lang.Object
      -
      Rappresentazione dei boss
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        private java.lang.String[]nomeBoss -
        Lista boss dell'ora
        -
        private java.lang.Stringora -
        Ora di spawn
        -
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        Boss(java.lang.String[] nomeBoss, - java.lang.String ora) 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static java.lang.String[]getHourBoss(int ora, - int minuto, - java.util.ArrayList<Boss> lists) -
        Metodo per ottenere i boss dell'ora
        -
        java.lang.String[]getNomeBoss() -
        Ottieni i nomi dei boss
        -
        private java.lang.StringgetOra() 
        private voidsetNomeBoss(java.lang.String[] nomeBoss) 
        private voidsetOra(java.lang.String ora) 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          nomeBoss

          -
          private java.lang.String[] nomeBoss
          -
          Lista boss dell'ora
          -
        • -
        - - - -
          -
        • -

          ora

          -
          private java.lang.String ora
          -
          Ora di spawn
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          Boss

          -
          public Boss(java.lang.String[] nomeBoss,
          -            java.lang.String ora)
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getHourBoss

          -
          public static java.lang.String[] getHourBoss(int ora,
          -                                             int minuto,
          -                                             java.util.ArrayList<Boss> lists)
          -
          Metodo per ottenere i boss dell'ora
          -
          -
          Parameters:
          -
          ora - Ora di spawn del boss
          -
          minuto - Minuto di spawn del boss
          -
          lists - Lista dei boss del giorno
          -
          Returns:
          -
          Lista dei boss dell'ora indicata
          -
          -
        • -
        - - - -
          -
        • -

          getNomeBoss

          -
          public java.lang.String[] getNomeBoss()
          -
          Ottieni i nomi dei boss
          -
          -
          Returns:
          -
          -
        • -
        - - - -
          -
        • -

          setNomeBoss

          -
          private void setNomeBoss(java.lang.String[] nomeBoss)
          -
        • -
        - - - -
          -
        • -

          getOra

          -
          private java.lang.String getOra()
          -
        • -
        - - - -
          -
        • -

          setOra

          -
          private void setOra(java.lang.String ora)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/beans/BDOBossBean/Giorno.html b/docs/page/javadoc/beans/BDOBossBean/Giorno.html deleted file mode 100644 index 6c0185d..0000000 --- a/docs/page/javadoc/beans/BDOBossBean/Giorno.html +++ /dev/null @@ -1,377 +0,0 @@ - - - - - -Giorno (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    beans.BDOBossBean
    -

    Class Giorno

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • beans.BDOBossBean.Giorno
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class Giorno
      -extends java.lang.Object
      -
      Rappresentazione del giorno di spawn dei boss di BDO
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        private java.util.ArrayList<Boss>bosses 
        private java.lang.Stringgiorno 
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        Giorno(java.lang.String giorno, - java.util.ArrayList<Boss> bosses) 
        -
      • -
      - - -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          giorno

          -
          private java.lang.String giorno
          -
        • -
        - - - -
          -
        • -

          bosses

          -
          private java.util.ArrayList<Boss> bosses
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          Giorno

          -
          public Giorno(java.lang.String giorno,
          -              java.util.ArrayList<Boss> bosses)
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getDayBosses

          -
          public static Giorno getDayBosses(java.lang.String giorno,
          -                                  java.util.ArrayList<Giorno> list)
          -
        • -
        - - - -
          -
        • -

          getGiorno

          -
          public java.lang.String getGiorno()
          -
        • -
        - - - -
          -
        • -

          setGiorno

          -
          private void setGiorno(java.lang.String giorno)
          -
        • -
        - - - -
          -
        • -

          getBosses

          -
          public java.util.ArrayList<Boss> getBosses()
          -
        • -
        - - - -
          -
        • -

          setBosses

          -
          private void setBosses(java.util.ArrayList<Boss> bosses)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/beans/BDOBossBean/class-use/Boss.html b/docs/page/javadoc/beans/BDOBossBean/class-use/Boss.html deleted file mode 100644 index 07359bc..0000000 --- a/docs/page/javadoc/beans/BDOBossBean/class-use/Boss.html +++ /dev/null @@ -1,210 +0,0 @@ - - - - - -Uses of Class beans.BDOBossBean.Boss (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    beans.BDOBossBean.Boss

    -
    -
    -
      -
    • - - - - - - - - - - - - -
      Packages that use Boss 
      PackageDescription
      beans.BDOBossBean 
      -
    • -
    • -
        -
      • - - -

        Uses of Boss in beans.BDOBossBean

        - - - - - - - - - - - - -
        Fields in beans.BDOBossBean with type parameters of type Boss 
        Modifier and TypeField and Description
        private java.util.ArrayList<Boss>Giorno.bosses 
        - - - - - - - - - - - - -
        Methods in beans.BDOBossBean that return types with arguments of type Boss 
        Modifier and TypeMethod and Description
        java.util.ArrayList<Boss>Giorno.getBosses() 
        - - - - - - - - - - - - - - - - -
        Method parameters in beans.BDOBossBean with type arguments of type Boss 
        Modifier and TypeMethod and Description
        static java.lang.String[]Boss.getHourBoss(int ora, - int minuto, - java.util.ArrayList<Boss> lists) -
        Metodo per ottenere i boss dell'ora
        -
        private voidGiorno.setBosses(java.util.ArrayList<Boss> bosses) 
        - - - - - - - - - - -
        Constructor parameters in beans.BDOBossBean with type arguments of type Boss 
        Constructor and Description
        Giorno(java.lang.String giorno, - java.util.ArrayList<Boss> bosses) 
        -
      • -
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/beans/BDOBossBean/class-use/Giorno.html b/docs/page/javadoc/beans/BDOBossBean/class-use/Giorno.html deleted file mode 100644 index 815c23f..0000000 --- a/docs/page/javadoc/beans/BDOBossBean/class-use/Giorno.html +++ /dev/null @@ -1,236 +0,0 @@ - - - - - -Uses of Class beans.BDOBossBean.Giorno (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    beans.BDOBossBean.Giorno

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/beans/BDOBossBean/package-frame.html b/docs/page/javadoc/beans/BDOBossBean/package-frame.html deleted file mode 100644 index 3b85ed4..0000000 --- a/docs/page/javadoc/beans/BDOBossBean/package-frame.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - -beans.BDOBossBean (Documentazione TakaoBot) - - - - - -

    beans.BDOBossBean

    -
    -

    Classes

    - -
    - - diff --git a/docs/page/javadoc/beans/BDOBossBean/package-summary.html b/docs/page/javadoc/beans/BDOBossBean/package-summary.html deleted file mode 100644 index d7af63e..0000000 --- a/docs/page/javadoc/beans/BDOBossBean/package-summary.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - - -beans.BDOBossBean (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package beans.BDOBossBean

    -
    -
    -
      -
    • - - - - - - - - - - - - - - - - -
      Class Summary 
      ClassDescription
      Boss -
      Rappresentazione dei boss
      -
      Giorno -
      Rappresentazione del giorno di spawn dei boss di BDO
      -
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/beans/BDOBossBean/package-tree.html b/docs/page/javadoc/beans/BDOBossBean/package-tree.html deleted file mode 100644 index 70e9eaa..0000000 --- a/docs/page/javadoc/beans/BDOBossBean/package-tree.html +++ /dev/null @@ -1,138 +0,0 @@ - - - - - -beans.BDOBossBean Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package beans.BDOBossBean

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    -
      -
    • java.lang.Object -
        -
      • beans.BDOBossBean.Boss
      • -
      • beans.BDOBossBean.Giorno
      • -
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/beans/BDOBossBean/package-use.html b/docs/page/javadoc/beans/BDOBossBean/package-use.html deleted file mode 100644 index 050fee9..0000000 --- a/docs/page/javadoc/beans/BDOBossBean/package-use.html +++ /dev/null @@ -1,185 +0,0 @@ - - - - - -Uses of Package beans.BDOBossBean (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    beans.BDOBossBean

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/beans/RSSMessage.html b/docs/page/javadoc/beans/RSSMessage.html deleted file mode 100644 index a058ceb..0000000 --- a/docs/page/javadoc/beans/RSSMessage.html +++ /dev/null @@ -1,450 +0,0 @@ - - - - - -RSSMessage (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    beans
    -

    Class RSSMessage

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • beans.RSSMessage
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class RSSMessage
      -extends java.lang.Object
      -
      Classe contenitore per il titolo, il link e il body HTML - del feed RSS
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        private org.jsoup.nodes.Documentdoc 
        private java.lang.Stringlink 
        private java.lang.Stringtitle 
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        RSSMessage(java.lang.String title, - java.lang.String link, - org.jsoup.nodes.Document doc) 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        org.jsoup.nodes.DocumentgetDoc() -
        Metodo per ottenere il body del feed RSS
        -
        java.lang.StringgetLink() -
        Metodo per ottenere il link del feed
        -
        java.lang.StringgetTitle() -
        Metodo per ottenre il titolo del feed
        -
        voidsetDoc(org.jsoup.nodes.Document doc) -
        Metodo per impostare il body del feed RSS
        -
        voidsetLink(java.lang.String link) -
        Metodo per impostare il link del feed
        -
        voidsetTitle(java.lang.String title) -
        Metodo per ottenre il titolo del feed
        -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          title

          -
          private java.lang.String title
          -
        • -
        - - - -
          -
        • -

          link

          -
          private java.lang.String link
          -
        • -
        - - - -
          -
        • -

          doc

          -
          private org.jsoup.nodes.Document doc
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          RSSMessage

          -
          public RSSMessage(java.lang.String title,
          -                  java.lang.String link,
          -                  org.jsoup.nodes.Document doc)
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getTitle

          -
          public java.lang.String getTitle()
          -
          Metodo per ottenre il titolo del feed
          -
          -
          Returns:
          -
          String titolo del feed
          -
          -
        • -
        - - - -
          -
        • -

          setTitle

          -
          public void setTitle(java.lang.String title)
          -
          Metodo per ottenre il titolo del feed
          -
          -
          Parameters:
          -
          title - titolo del feed
          -
          -
        • -
        - - - -
          -
        • -

          getLink

          -
          public java.lang.String getLink()
          -
          Metodo per ottenere il link del feed
          -
          -
          Returns:
          -
          String
          -
          -
        • -
        - - - -
          -
        • -

          setLink

          -
          public void setLink(java.lang.String link)
          -
          Metodo per impostare il link del feed
          -
          -
          Parameters:
          -
          link - Url del feed in stringa
          -
          -
        • -
        - - - -
          -
        • -

          getDoc

          -
          public org.jsoup.nodes.Document getDoc()
          -
          Metodo per ottenere il body del feed RSS
          -
          -
          Returns:
          -
          documento HTML
          -
          See Also:
          -
          Document
          -
          -
        • -
        - - - -
          -
        • -

          setDoc

          -
          public void setDoc(org.jsoup.nodes.Document doc)
          -
          Metodo per impostare il body del feed RSS
          -
          -
          Parameters:
          -
          doc - documento HTMl
          -
          See Also:
          -
          Document
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/beans/Rsslink.html b/docs/page/javadoc/beans/Rsslink.html deleted file mode 100644 index d3c7595..0000000 --- a/docs/page/javadoc/beans/Rsslink.html +++ /dev/null @@ -1,445 +0,0 @@ - - - - - -Rsslink (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    beans
    -

    Class Rsslink

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • beans.Rsslink
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      @Entity
      -public class Rsslink
      -extends java.lang.Object
      -
      Tabella RSSLink
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        private longid 
        private java.lang.StringlastAtmAlert -
        Link ultimo feed di atm
        -
        private java.lang.StringlastNewsBDO -
        Lista link ultime news di BDO
        -
        private java.lang.StringlastPatchBDO 
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        Rsslink() 
        -
      • -
      - - -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          id

          -
          private long id
          -
        • -
        - - - -
          -
        • -

          lastNewsBDO

          -
          private java.lang.String lastNewsBDO
          -
          Lista link ultime news di BDO
          -
        • -
        - - - -
          -
        • -

          lastPatchBDO

          -
          private java.lang.String lastPatchBDO
          -
        • -
        - - - -
          -
        • -

          lastAtmAlert

          -
          private java.lang.String lastAtmAlert
          -
          Link ultimo feed di atm
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          Rsslink

          -
          public Rsslink()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getId

          -
          public long getId()
          -
        • -
        - - - -
          -
        • -

          setId

          -
          public void setId(long id)
          -
        • -
        - - - -
          -
        • -

          getLastNewsBDO

          -
          public java.lang.String getLastNewsBDO()
          -
        • -
        - - - -
          -
        • -

          setLastNewsBDO

          -
          public void setLastNewsBDO(java.lang.String lastNewsBDO)
          -
        • -
        - - - -
          -
        • -

          getLastPatchBDO

          -
          public java.lang.String getLastPatchBDO()
          -
        • -
        - - - -
          -
        • -

          setLastPatchBDO

          -
          public void setLastPatchBDO(java.lang.String lastPatchBDO)
          -
        • -
        - - - -
          -
        • -

          getLastAtmAlert

          -
          public java.lang.String getLastAtmAlert()
          -
        • -
        - - - -
          -
        • -

          setLastAtmAlert

          -
          public void setLastAtmAlert(java.lang.String lastAtmAlert)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/beans/ServerToChannel.html b/docs/page/javadoc/beans/ServerToChannel.html deleted file mode 100644 index 4bcdcbf..0000000 --- a/docs/page/javadoc/beans/ServerToChannel.html +++ /dev/null @@ -1,408 +0,0 @@ - - - - - -ServerToChannel (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    beans
    -

    Class ServerToChannel

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • beans.ServerToChannel
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class ServerToChannel
      -extends java.lang.Object
      -
      Classe di appoggio per ottenere serverID e channelID - per i publish del feed RSS
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        private java.lang.StringchannelID 
        private java.lang.StringserverID 
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        ServerToChannel(java.lang.String serverID, - java.lang.String channelID) 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        booleanequals(java.lang.Object object) 
        java.lang.StringgetChannelID() -
        Metodo per ottenere il channelID
        -
        java.lang.StringgetServerID() -
        Metodo per ottenere il serverID
        -
        voidsetChannelID(java.lang.String channelID) -
        Metodo per impostare il channelID
        -
        voidsetServerID(java.lang.String serverID) -
        Metodo per impostare il serverID
        -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          serverID

          -
          private java.lang.String serverID
          -
        • -
        - - - -
          -
        • -

          channelID

          -
          private java.lang.String channelID
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          ServerToChannel

          -
          public ServerToChannel(java.lang.String serverID,
          -                       java.lang.String channelID)
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getServerID

          -
          public java.lang.String getServerID()
          -
          Metodo per ottenere il serverID
          -
          -
          Returns:
          -
          serverID
          -
          -
        • -
        - - - -
          -
        • -

          setServerID

          -
          public void setServerID(java.lang.String serverID)
          -
          Metodo per impostare il serverID
          -
          -
          Parameters:
          -
          serverID - id del server discord
          -
          -
        • -
        - - - -
          -
        • -

          getChannelID

          -
          public java.lang.String getChannelID()
          -
          Metodo per ottenere il channelID
          -
          -
          Returns:
          -
          String id del canale
          -
          -
        • -
        - - - -
          -
        • -

          setChannelID

          -
          public void setChannelID(java.lang.String channelID)
          -
          Metodo per impostare il channelID
          -
          -
          Parameters:
          -
          channelID - id del canale testuale
          -
          -
        • -
        - - - -
          -
        • -

          equals

          -
          public boolean equals(java.lang.Object object)
          -
          -
          Overrides:
          -
          equals in class java.lang.Object
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/beans/ServersDiscord.html b/docs/page/javadoc/beans/ServersDiscord.html deleted file mode 100644 index 216c495..0000000 --- a/docs/page/javadoc/beans/ServersDiscord.html +++ /dev/null @@ -1,591 +0,0 @@ - - - - - -ServersDiscord (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    beans
    -

    Class ServersDiscord

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • beans.ServersDiscord
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      @Entity
      -public class ServersDiscord
      -extends java.lang.Object
      -
      Tabella contenente tutti gli id dei canali per le funzionalità del bot
      -
    • -
    -
    -
    - -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          serverId

          -
          private java.lang.String serverId
          -
          Id del server
          -
        • -
        - - - -
          -
        • -

          nameServer

          -
          private java.lang.String nameServer
          -
          Nome del server
          -
        • -
        - - - -
          -
        • -

          simbolCommand

          -
          private java.lang.String simbolCommand
          -
          Simbolo di comando
          -
        • -
        - - - -
          -
        • -

          bdoNewsIDChannel

          -
          private java.lang.String bdoNewsIDChannel
          -
          ID Canale per invio news di BDO
          -
        • -
        - - - -
          -
        • -

          bdoPatchIDChannel

          -
          private java.lang.String bdoPatchIDChannel
          -
          ID Canale per invio patch di BDO
          -
        • -
        - - - -
          -
        • -

          bdoBossIDChannel

          -
          private java.lang.String bdoBossIDChannel
          -
          ID Canale per invio alert boss di BDO
          -
        • -
        - - - -
          -
        • -

          atmAlertIDChannel

          -
          private java.lang.String atmAlertIDChannel
          -
          ID Canale per invio degli alert dell'ATM
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          ServersDiscord

          -
          public ServersDiscord()
          -
        • -
        - - - -
          -
        • -

          ServersDiscord

          -
          public ServersDiscord(java.lang.String serverId,
          -                      java.lang.String bdoNewsIDChannel)
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getServerId

          -
          public java.lang.String getServerId()
          -
        • -
        - - - -
          -
        • -

          setServerId

          -
          public void setServerId(java.lang.String serverId)
          -
        • -
        - - - -
          -
        • -

          getNameServer

          -
          public java.lang.String getNameServer()
          -
        • -
        - - - -
          -
        • -

          setNameServer

          -
          public void setNameServer(java.lang.String nameServer)
          -
        • -
        - - - -
          -
        • -

          getSimbolCommand

          -
          public java.lang.String getSimbolCommand()
          -
        • -
        - - - -
          -
        • -

          setSimbolCommand

          -
          public void setSimbolCommand(java.lang.String simbolCommand)
          -
        • -
        - - - -
          -
        • -

          getBdoNewsIDChannel

          -
          public java.lang.String getBdoNewsIDChannel()
          -
        • -
        - - - -
          -
        • -

          setBdoNewsIDChannel

          -
          public void setBdoNewsIDChannel(java.lang.String bdoNewsIDChannel)
          -
        • -
        - - - -
          -
        • -

          getBdoPatchIDChannel

          -
          public java.lang.String getBdoPatchIDChannel()
          -
        • -
        - - - -
          -
        • -

          setBdoPatchIDChannel

          -
          public void setBdoPatchIDChannel(java.lang.String bdoPatchIDChannel)
          -
        • -
        - - - -
          -
        • -

          getAtmAlertIDChannel

          -
          public java.lang.String getAtmAlertIDChannel()
          -
        • -
        - - - -
          -
        • -

          setAtmAlertIDChannel

          -
          public void setAtmAlertIDChannel(java.lang.String atmAlertIDChannel)
          -
        • -
        - - - -
          -
        • -

          getBdoBossIDChannel

          -
          public java.lang.String getBdoBossIDChannel()
          -
        • -
        - - - -
          -
        • -

          setBdoBossIDChannel

          -
          public void setBdoBossIDChannel(java.lang.String bdoBossIDChannel)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/beans/class-use/RSSMessage.html b/docs/page/javadoc/beans/class-use/RSSMessage.html deleted file mode 100644 index 3a2caf8..0000000 --- a/docs/page/javadoc/beans/class-use/RSSMessage.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - -Uses of Class beans.RSSMessage (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    beans.RSSMessage

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/beans/class-use/Rsslink.html b/docs/page/javadoc/beans/class-use/Rsslink.html deleted file mode 100644 index 39e7937..0000000 --- a/docs/page/javadoc/beans/class-use/Rsslink.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class beans.Rsslink (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    beans.Rsslink

    -
    -
    No usage of beans.Rsslink
    - - - - - - diff --git a/docs/page/javadoc/beans/class-use/ServerToChannel.html b/docs/page/javadoc/beans/class-use/ServerToChannel.html deleted file mode 100644 index 1b6395a..0000000 --- a/docs/page/javadoc/beans/class-use/ServerToChannel.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - -Uses of Class beans.ServerToChannel (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    beans.ServerToChannel

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/beans/class-use/ServersDiscord.html b/docs/page/javadoc/beans/class-use/ServersDiscord.html deleted file mode 100644 index 6739585..0000000 --- a/docs/page/javadoc/beans/class-use/ServersDiscord.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class beans.ServersDiscord (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    beans.ServersDiscord

    -
    -
    No usage of beans.ServersDiscord
    - - - - - - diff --git a/docs/page/javadoc/beans/package-frame.html b/docs/page/javadoc/beans/package-frame.html deleted file mode 100644 index 7b57410..0000000 --- a/docs/page/javadoc/beans/package-frame.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -beans (Documentazione TakaoBot) - - - - - -

    beans

    - - - diff --git a/docs/page/javadoc/beans/package-summary.html b/docs/page/javadoc/beans/package-summary.html deleted file mode 100644 index 53232cb..0000000 --- a/docs/page/javadoc/beans/package-summary.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - -beans (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package beans

    -
    -
    -
      -
    • - - - - - - - - - - - - - - - - - - - - - - - - -
      Class Summary 
      ClassDescription
      Rsslink -
      Tabella RSSLink
      -
      RSSMessage -
      Classe contenitore per il titolo, il link e il body HTML - del feed RSS
      -
      ServersDiscord -
      Tabella contenente tutti gli id dei canali per le funzionalità del bot
      -
      ServerToChannel -
      Classe di appoggio per ottenere serverID e channelID - per i publish del feed RSS
      -
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/beans/package-tree.html b/docs/page/javadoc/beans/package-tree.html deleted file mode 100644 index 4b55e67..0000000 --- a/docs/page/javadoc/beans/package-tree.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - - -beans Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package beans

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    - -
    - - - - - - diff --git a/docs/page/javadoc/beans/package-use.html b/docs/page/javadoc/beans/package-use.html deleted file mode 100644 index f3e04d5..0000000 --- a/docs/page/javadoc/beans/package-use.html +++ /dev/null @@ -1,210 +0,0 @@ - - - - - -Uses of Package beans (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    beans

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/command/pattern/ControlCommand.html b/docs/page/javadoc/command/pattern/ControlCommand.html deleted file mode 100644 index 58db282..0000000 --- a/docs/page/javadoc/command/pattern/ControlCommand.html +++ /dev/null @@ -1,340 +0,0 @@ - - - - - -ControlCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.pattern
    -

    Class ControlCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • command.pattern.ControlCommand
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class ControlCommand
      -extends java.lang.Object
      -
      Classe per gestire i controlli tra i simbolo di comanndo e il comando stesso
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        ControlCommand() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static booleancheckCommand(@NotNull net.dv8tion.jda.core.events.message.MessageReceivedEvent event, - @NotNull java.lang.String simbolCommand, - @NotNull java.lang.String commandName) -
        Controllo del comando lanciato dalla chat se sia corretto con quelli attivi sul bot.
        -
        static booleancontrolCommand(net.dv8tion.jda.core.events.message.MessageReceivedEvent event, - java.lang.String commandName) -
        Deprecated. 
        -
        static java.lang.StringgetSimbolCommand(java.lang.String serverId) -
        Metodo per ottere il simbolo di comando del server
        -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          ControlCommand

          -
          public ControlCommand()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          controlCommand

          -
          @Deprecated
          -public static boolean controlCommand(net.dv8tion.jda.core.events.message.MessageReceivedEvent event,
          -                                                  java.lang.String commandName)
          -
          Deprecated. 
          -
          Metodo per eseguire il controllo se il comando inserito è quello di controllo
          -
          -
          Parameters:
          -
          event - evento del messaggio
          -
          commandName - nome del comando
          -
          Returns:
          -
          boolean il comando corrisponde a quello ricevuto con quello controllato
          -
          -
        • -
        - - - -
          -
        • -

          getSimbolCommand

          -
          public static java.lang.String getSimbolCommand(java.lang.String serverId)
          -
          Metodo per ottere il simbolo di comando del server
          -
          -
          Parameters:
          -
          serverId - ID del server
          -
          Returns:
          -
          String simbolo di comando
          -
          -
        • -
        - - - -
          -
        • -

          checkCommand

          -
          public static boolean checkCommand(@NotNull
          -                                   @NotNull net.dv8tion.jda.core.events.message.MessageReceivedEvent event,
          -                                   @NotNull
          -                                   @NotNull java.lang.String simbolCommand,
          -                                   @NotNull
          -                                   @NotNull java.lang.String commandName)
          -
          Controllo del comando lanciato dalla chat se sia corretto con quelli attivi sul bot. - Combaciando il simbolo di comando con il nome del comando oppure con la menzione del bot, seguito dal nome del comando.
          -
          -
          Parameters:
          -
          event - Evento del messaggio
          -
          simbolCommand - Simbolo di comando
          -
          commandName - Nome del comando
          -
          Returns:
          -
          boolean Validità del comando
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/pattern/class-use/ControlCommand.html b/docs/page/javadoc/command/pattern/class-use/ControlCommand.html deleted file mode 100644 index 3865e61..0000000 --- a/docs/page/javadoc/command/pattern/class-use/ControlCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.pattern.ControlCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.pattern.ControlCommand

    -
    -
    No usage of command.pattern.ControlCommand
    - - - - - - diff --git a/docs/page/javadoc/command/pattern/package-frame.html b/docs/page/javadoc/command/pattern/package-frame.html deleted file mode 100644 index 8f93651..0000000 --- a/docs/page/javadoc/command/pattern/package-frame.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - -command.pattern (Documentazione TakaoBot) - - - - - -

    command.pattern

    -
    -

    Classes

    - -
    - - diff --git a/docs/page/javadoc/command/pattern/package-summary.html b/docs/page/javadoc/command/pattern/package-summary.html deleted file mode 100644 index 8130a3a..0000000 --- a/docs/page/javadoc/command/pattern/package-summary.html +++ /dev/null @@ -1,144 +0,0 @@ - - - - - -command.pattern (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package command.pattern

    -
    -
    -
      -
    • - - - - - - - - - - - - -
      Class Summary 
      ClassDescription
      ControlCommand -
      Classe per gestire i controlli tra i simbolo di comanndo e il comando stesso
      -
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/command/pattern/package-tree.html b/docs/page/javadoc/command/pattern/package-tree.html deleted file mode 100644 index c15840c..0000000 --- a/docs/page/javadoc/command/pattern/package-tree.html +++ /dev/null @@ -1,137 +0,0 @@ - - - - - -command.pattern Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package command.pattern

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    - -
    - - - - - - diff --git a/docs/page/javadoc/command/pattern/package-use.html b/docs/page/javadoc/command/pattern/package-use.html deleted file mode 100644 index c413cc5..0000000 --- a/docs/page/javadoc/command/pattern/package-use.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Package command.pattern (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    command.pattern

    -
    -
    No usage of command.pattern
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/BDOReceiver.html b/docs/page/javadoc/command/real/BDO/BDOReceiver.html deleted file mode 100644 index 66e1e69..0000000 --- a/docs/page/javadoc/command/real/BDO/BDOReceiver.html +++ /dev/null @@ -1,447 +0,0 @@ - - - - - -BDOReceiver (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO
    -

    Class BDOReceiver

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.BDO.BDOReceiver
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      -
      public class BDOReceiver
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BDOReceiver() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetBDOBossStartCommand() 
        static java.lang.StringgetBDOBossStartCommandDescription() 
        static java.lang.StringgetBDOBossStopCommand() 
        static java.lang.StringgetBDOBossStopCommandDescription() 
        static java.lang.StringgetBDONewsStartCommand() 
        static java.lang.StringgetBDONewsStartCommandDecription() 
        static java.lang.StringgetBDONewsStopCommand() 
        static java.lang.StringgetBDONewsStopCommandDecription() 
        static java.lang.StringgetBDOPatchStartCommand() 
        static java.lang.StringgetBDOPatchStartCommandDecription() 
        static java.lang.StringgetBDOPatchStopCommand() 
        static java.lang.StringgetBDOPatchStopCommandDecription() 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BDOReceiver

          -
          public BDOReceiver()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getBDOBossStartCommand

          -
          public static java.lang.String getBDOBossStartCommand()
          -
        • -
        - - - -
          -
        • -

          getBDOBossStartCommandDescription

          -
          public static java.lang.String getBDOBossStartCommandDescription()
          -
        • -
        - - - -
          -
        • -

          getBDOBossStopCommand

          -
          public static java.lang.String getBDOBossStopCommand()
          -
        • -
        - - - -
          -
        • -

          getBDOBossStopCommandDescription

          -
          public static java.lang.String getBDOBossStopCommandDescription()
          -
        • -
        - - - -
          -
        • -

          getBDONewsStartCommand

          -
          public static java.lang.String getBDONewsStartCommand()
          -
        • -
        - - - -
          -
        • -

          getBDONewsStartCommandDecription

          -
          public static java.lang.String getBDONewsStartCommandDecription()
          -
        • -
        - - - -
          -
        • -

          getBDONewsStopCommand

          -
          public static java.lang.String getBDONewsStopCommand()
          -
        • -
        - - - -
          -
        • -

          getBDONewsStopCommandDecription

          -
          public static java.lang.String getBDONewsStopCommandDecription()
          -
        • -
        - - - -
          -
        • -

          getBDOPatchStartCommand

          -
          public static java.lang.String getBDOPatchStartCommand()
          -
        • -
        - - - -
          -
        • -

          getBDOPatchStartCommandDecription

          -
          public static java.lang.String getBDOPatchStartCommandDecription()
          -
        • -
        - - - -
          -
        • -

          getBDOPatchStopCommand

          -
          public static java.lang.String getBDOPatchStopCommand()
          -
        • -
        - - - -
          -
        • -

          getBDOPatchStopCommandDecription

          -
          public static java.lang.String getBDOPatchStopCommandDecription()
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/BDONewsStartCommand.html b/docs/page/javadoc/command/real/BDO/RSS/BDONewsStartCommand.html deleted file mode 100644 index 9c8744d..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/BDONewsStartCommand.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -BDONewsStartCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO.RSS
    -

    Class BDONewsStartCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.BDO.RSS.BDONewsStartCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class BDONewsStartCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BDONewsStartCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetCommand() -
        Deprecated. 
        static java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BDONewsStartCommand

          -
          public BDONewsStartCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public static java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public static java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/BDONewsStopCommand.html b/docs/page/javadoc/command/real/BDO/RSS/BDONewsStopCommand.html deleted file mode 100644 index 5200b58..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/BDONewsStopCommand.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -BDONewsStopCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO.RSS
    -

    Class BDONewsStopCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.BDO.RSS.BDONewsStopCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class BDONewsStopCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BDONewsStopCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetCommand() -
        Deprecated. 
        static java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BDONewsStopCommand

          -
          public BDONewsStopCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public static java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public static java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/BDOPatchStartCommand.html b/docs/page/javadoc/command/real/BDO/RSS/BDOPatchStartCommand.html deleted file mode 100644 index 7d903aa..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/BDOPatchStartCommand.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -BDOPatchStartCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO.RSS
    -

    Class BDOPatchStartCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.BDO.RSS.BDOPatchStartCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class BDOPatchStartCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BDOPatchStartCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetCommand() -
        Deprecated. 
        static java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BDOPatchStartCommand

          -
          public BDOPatchStartCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public static java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public static java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/BDOPatchStopCommand.html b/docs/page/javadoc/command/real/BDO/RSS/BDOPatchStopCommand.html deleted file mode 100644 index 421897f..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/BDOPatchStopCommand.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -BDOPatchStopCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO.RSS
    -

    Class BDOPatchStopCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.BDO.RSS.BDOPatchStopCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class BDOPatchStopCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BDOPatchStopCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetCommand() -
        Deprecated. 
        static java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BDOPatchStopCommand

          -
          public BDOPatchStopCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public static java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public static java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/BDORSSReader.html b/docs/page/javadoc/command/real/BDO/RSS/BDORSSReader.html deleted file mode 100644 index c10e9d7..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/BDORSSReader.html +++ /dev/null @@ -1,305 +0,0 @@ - - - - - -BDORSSReader (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO.RSS
    -

    Class BDORSSReader

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • command.real.BDO.RSS.BDORSSReader
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class BDORSSReader
      -extends java.lang.Object
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BDORSSReader() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static net.dv8tion.jda.core.entities.MessageEmbedprepareRSStoEmbeddedMessage(RSSMessage message) -
        Metodo per preparare il messaggio per discord in modalità da embedded
        -
        static RSSMessagereadRSS(java.lang.String URL) -
        Metodo per leggere un feed RSS
        -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BDORSSReader

          -
          public BDORSSReader()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          readRSS

          -
          public static RSSMessage readRSS(java.lang.String URL)
          -
          Metodo per leggere un feed RSS
          -
          -
          Parameters:
          -
          URL - Url da cui bisogna leggere il feed
          -
          Returns:
          -
          Ultimo feed registrato
          -
          -
        • -
        - - - -
          -
        • -

          prepareRSStoEmbeddedMessage

          -
          public static net.dv8tion.jda.core.entities.MessageEmbed prepareRSStoEmbeddedMessage(RSSMessage message)
          -
          Metodo per preparare il messaggio per discord in modalità da embedded
          -
          -
          Parameters:
          -
          message - Ultimo feed prelevato dal metodo di lettura
          -
          Returns:
          -
          Messaggio pronto per l'invio a discord
          -
          See Also:
          -
          readRSS, -MessageEmbedded
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/BDORSScheduler.html b/docs/page/javadoc/command/real/BDO/RSS/BDORSScheduler.html deleted file mode 100644 index b436eae..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/BDORSScheduler.html +++ /dev/null @@ -1,305 +0,0 @@ - - - - - -BDORSScheduler (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO.RSS
    -

    Class BDORSScheduler

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • command.real.BDO.RSS.BDORSScheduler
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class BDORSScheduler
      -extends java.lang.Object
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BDORSScheduler() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        private static voidprocedurePublish(RSSMessage rssNewsMessage, - java.util.ArrayList<java.lang.String> newsBDOList, - net.dv8tion.jda.core.JDA jda) 
        private static voidpublishMessage(net.dv8tion.jda.core.entities.MessageEmbed newsMessage, - java.util.ArrayList<ServerToChannel> servers, - net.dv8tion.jda.core.JDA jda) 
        static java.util.TimerTasktaskFeedRSSBDO(net.dv8tion.jda.core.JDA jda) 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BDORSScheduler

          -
          public BDORSScheduler()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          taskFeedRSSBDO

          -
          public static java.util.TimerTask taskFeedRSSBDO(net.dv8tion.jda.core.JDA jda)
          -
        • -
        - - - -
          -
        • -

          procedurePublish

          -
          private static void procedurePublish(RSSMessage rssNewsMessage,
          -                                     java.util.ArrayList<java.lang.String> newsBDOList,
          -                                     net.dv8tion.jda.core.JDA jda)
          -
        • -
        - - - -
          -
        • -

          publishMessage

          -
          private static void publishMessage(net.dv8tion.jda.core.entities.MessageEmbed newsMessage,
          -                                   java.util.ArrayList<ServerToChannel> servers,
          -                                   net.dv8tion.jda.core.JDA jda)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDONewsStartCommand.html b/docs/page/javadoc/command/real/BDO/RSS/class-use/BDONewsStartCommand.html deleted file mode 100644 index 4b498cc..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDONewsStartCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.RSS.BDONewsStartCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.RSS.BDONewsStartCommand

    -
    -
    No usage of command.real.BDO.RSS.BDONewsStartCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDONewsStopCommand.html b/docs/page/javadoc/command/real/BDO/RSS/class-use/BDONewsStopCommand.html deleted file mode 100644 index 0c7f4f7..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDONewsStopCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.RSS.BDONewsStopCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.RSS.BDONewsStopCommand

    -
    -
    No usage of command.real.BDO.RSS.BDONewsStopCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDOPatchStartCommand.html b/docs/page/javadoc/command/real/BDO/RSS/class-use/BDOPatchStartCommand.html deleted file mode 100644 index fbae56f..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDOPatchStartCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.RSS.BDOPatchStartCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.RSS.BDOPatchStartCommand

    -
    -
    No usage of command.real.BDO.RSS.BDOPatchStartCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDOPatchStopCommand.html b/docs/page/javadoc/command/real/BDO/RSS/class-use/BDOPatchStopCommand.html deleted file mode 100644 index bbcdb90..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDOPatchStopCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.RSS.BDOPatchStopCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.RSS.BDOPatchStopCommand

    -
    -
    No usage of command.real.BDO.RSS.BDOPatchStopCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDORSSReader.html b/docs/page/javadoc/command/real/BDO/RSS/class-use/BDORSSReader.html deleted file mode 100644 index 87ebf57..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDORSSReader.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.RSS.BDORSSReader (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.RSS.BDORSSReader

    -
    -
    No usage of command.real.BDO.RSS.BDORSSReader
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDORSScheduler.html b/docs/page/javadoc/command/real/BDO/RSS/class-use/BDORSScheduler.html deleted file mode 100644 index 7068dff..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/class-use/BDORSScheduler.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.RSS.BDORSScheduler (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.RSS.BDORSScheduler

    -
    -
    No usage of command.real.BDO.RSS.BDORSScheduler
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/package-frame.html b/docs/page/javadoc/command/real/BDO/RSS/package-frame.html deleted file mode 100644 index 6c5ae92..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/package-frame.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -command.real.BDO.RSS (Documentazione TakaoBot) - - - - - -

    command.real.BDO.RSS

    - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/package-summary.html b/docs/page/javadoc/command/real/BDO/RSS/package-summary.html deleted file mode 100644 index 4462bbd..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/package-summary.html +++ /dev/null @@ -1,162 +0,0 @@ - - - - - -command.real.BDO.RSS (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package command.real.BDO.RSS

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/package-tree.html b/docs/page/javadoc/command/real/BDO/RSS/package-tree.html deleted file mode 100644 index a45cb9f..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/package-tree.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - -command.real.BDO.RSS Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package command.real.BDO.RSS

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/RSS/package-use.html b/docs/page/javadoc/command/real/BDO/RSS/package-use.html deleted file mode 100644 index f4bf349..0000000 --- a/docs/page/javadoc/command/real/BDO/RSS/package-use.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Package command.real.BDO.RSS (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    command.real.BDO.RSS

    -
    -
    No usage of command.real.BDO.RSS
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/BDOBossStartCommand.html b/docs/page/javadoc/command/real/BDO/boss/BDOBossStartCommand.html deleted file mode 100644 index 4419be6..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/BDOBossStartCommand.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -BDOBossStartCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO.boss
    -

    Class BDOBossStartCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.BDO.boss.BDOBossStartCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class BDOBossStartCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BDOBossStartCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetCommand() -
        Deprecated. 
        static java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BDOBossStartCommand

          -
          public BDOBossStartCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public static java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public static java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/BDOBossStopCommand.html b/docs/page/javadoc/command/real/BDO/boss/BDOBossStopCommand.html deleted file mode 100644 index 82d25e1..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/BDOBossStopCommand.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -BDOBossStopCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO.boss
    -

    Class BDOBossStopCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.BDO.boss.BDOBossStopCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class BDOBossStopCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BDOBossStopCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetCommand() -
        Deprecated. 
        static java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BDOBossStopCommand

          -
          public BDOBossStopCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public static java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public static java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/BossJob.html b/docs/page/javadoc/command/real/BDO/boss/BossJob.html deleted file mode 100644 index 7f6cb6d..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/BossJob.html +++ /dev/null @@ -1,281 +0,0 @@ - - - - - -BossJob (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO.boss
    -

    Class BossJob

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • command.real.BDO.boss.BossJob
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      org.quartz.Job
      -
      -
      -
      -
      public class BossJob
      -extends java.lang.Object
      -implements org.quartz.Job
      -
      Job per l'ottenimento dei boss
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BossJob() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - -
        All Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        voidexecute(org.quartz.JobExecutionContext context) 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BossJob

          -
          public BossJob()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          execute

          -
          public void execute(org.quartz.JobExecutionContext context)
          -
          -
          Specified by:
          -
          execute in interface org.quartz.Job
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/BossRetriver.html b/docs/page/javadoc/command/real/BDO/boss/BossRetriver.html deleted file mode 100644 index 383e80a..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/BossRetriver.html +++ /dev/null @@ -1,380 +0,0 @@ - - - - - -BossRetriver (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.BDO.boss
    -

    Class BossRetriver

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • command.real.BDO.boss.BossRetriver
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class BossRetriver
      -extends java.lang.Object
      -
      Classe per leggere il json dei boss
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        BossRetriver() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static java.util.ArrayList<Giorno>getBossList() -
        Ottieni la lista dei boss da file
        -
        static voidprocessHour(int ora, - int minuto, - Giorno giorno) -
        Processa l'ora per ottenere il boss
        -
        private static voidprocessMinute0015(int ora, - int minuto, - Giorno giorno) -
        Metodo per ottenere il boss che spawna alle 15
        -
        private static voidprocessMinute4500(int ora, - int minuto, - Giorno giorno) -
        Metodo per ottenere il boss che spawna alle 00
        -
        private static voidpublish(java.lang.String[] bosses, - java.lang.String orarioMancante) -
        Metoto per eseguire la pubblicazione dei messaggi
        -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          BossRetriver

          -
          public BossRetriver()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getBossList

          -
          public static java.util.ArrayList<Giorno> getBossList()
          -
          Ottieni la lista dei boss da file
          -
          -
          Returns:
          -
          ArrayList lista Boss
          -
          -
        • -
        - - - -
          -
        • -

          processHour

          -
          public static void processHour(int ora,
          -                               int minuto,
          -                               Giorno giorno)
          -
          Processa l'ora per ottenere il boss
          -
          -
          Parameters:
          -
          ora - ora attuale
          -
          minuto - minuti attuali
          -
          giorno - giorno attuale
          -
          -
        • -
        - - - -
          -
        • -

          processMinute4500

          -
          private static void processMinute4500(int ora,
          -                                      int minuto,
          -                                      Giorno giorno)
          -
          Metodo per ottenere il boss che spawna alle 00
          -
          -
          Parameters:
          -
          ora - ora attuale
          -
          minuto - minuto attuale
          -
          giorno - giorno attuale
          -
          -
        • -
        - - - -
          -
        • -

          processMinute0015

          -
          private static void processMinute0015(int ora,
          -                                      int minuto,
          -                                      Giorno giorno)
          -
          Metodo per ottenere il boss che spawna alle 15
          -
          -
          Parameters:
          -
          ora - ora attuale
          -
          minuto - minuto attuale
          -
          giorno - giorno attuale
          -
          -
        • -
        - - - -
          -
        • -

          publish

          -
          private static void publish(java.lang.String[] bosses,
          -                            java.lang.String orarioMancante)
          -
          Metoto per eseguire la pubblicazione dei messaggi
          -
          -
          Parameters:
          -
          bosses - lista boss trovati
          -
          orarioMancante - minuti mancanti allo spawn dei boss
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/class-use/BDOBossStartCommand.html b/docs/page/javadoc/command/real/BDO/boss/class-use/BDOBossStartCommand.html deleted file mode 100644 index 8f9da26..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/class-use/BDOBossStartCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.boss.BDOBossStartCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.boss.BDOBossStartCommand

    -
    -
    No usage of command.real.BDO.boss.BDOBossStartCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/class-use/BDOBossStopCommand.html b/docs/page/javadoc/command/real/BDO/boss/class-use/BDOBossStopCommand.html deleted file mode 100644 index 9b5ebe9..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/class-use/BDOBossStopCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.boss.BDOBossStopCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.boss.BDOBossStopCommand

    -
    -
    No usage of command.real.BDO.boss.BDOBossStopCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/class-use/BossJob.html b/docs/page/javadoc/command/real/BDO/boss/class-use/BossJob.html deleted file mode 100644 index b64b81d..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/class-use/BossJob.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.boss.BossJob (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.boss.BossJob

    -
    -
    No usage of command.real.BDO.boss.BossJob
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/class-use/BossRetriver.html b/docs/page/javadoc/command/real/BDO/boss/class-use/BossRetriver.html deleted file mode 100644 index 4db3ced..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/class-use/BossRetriver.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.boss.BossRetriver (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.boss.BossRetriver

    -
    -
    No usage of command.real.BDO.boss.BossRetriver
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/package-frame.html b/docs/page/javadoc/command/real/BDO/boss/package-frame.html deleted file mode 100644 index d9923d1..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/package-frame.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -command.real.BDO.boss (Documentazione TakaoBot) - - - - - -

    command.real.BDO.boss

    - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/package-summary.html b/docs/page/javadoc/command/real/BDO/boss/package-summary.html deleted file mode 100644 index daf95ed..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/package-summary.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - -command.real.BDO.boss (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package command.real.BDO.boss

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/package-tree.html b/docs/page/javadoc/command/real/BDO/boss/package-tree.html deleted file mode 100644 index f588904..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/package-tree.html +++ /dev/null @@ -1,144 +0,0 @@ - - - - - -command.real.BDO.boss Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package command.real.BDO.boss

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    -
      -
    • java.lang.Object -
        -
      • command.real.BDO.boss.BossJob (implements org.quartz.Job)
      • -
      • command.real.BDO.boss.BossRetriver
      • -
      • net.dv8tion.jda.core.hooks.ListenerAdapter (implements net.dv8tion.jda.core.hooks.EventListener) - -
      • -
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/boss/package-use.html b/docs/page/javadoc/command/real/BDO/boss/package-use.html deleted file mode 100644 index 7527afb..0000000 --- a/docs/page/javadoc/command/real/BDO/boss/package-use.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Package command.real.BDO.boss (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    command.real.BDO.boss

    -
    -
    No usage of command.real.BDO.boss
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/class-use/BDOReceiver.html b/docs/page/javadoc/command/real/BDO/class-use/BDOReceiver.html deleted file mode 100644 index d024d8f..0000000 --- a/docs/page/javadoc/command/real/BDO/class-use/BDOReceiver.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.BDO.BDOReceiver (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.BDO.BDOReceiver

    -
    -
    No usage of command.real.BDO.BDOReceiver
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/package-frame.html b/docs/page/javadoc/command/real/BDO/package-frame.html deleted file mode 100644 index ad364c6..0000000 --- a/docs/page/javadoc/command/real/BDO/package-frame.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - -command.real.BDO (Documentazione TakaoBot) - - - - - -

    command.real.BDO

    -
    -

    Classes

    - -
    - - diff --git a/docs/page/javadoc/command/real/BDO/package-summary.html b/docs/page/javadoc/command/real/BDO/package-summary.html deleted file mode 100644 index 651147f..0000000 --- a/docs/page/javadoc/command/real/BDO/package-summary.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - -command.real.BDO (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package command.real.BDO

    -
    -
    -
      -
    • - - - - - - - - - - - - -
      Class Summary 
      ClassDescription
      BDOReceiver 
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/package-tree.html b/docs/page/javadoc/command/real/BDO/package-tree.html deleted file mode 100644 index 974227e..0000000 --- a/docs/page/javadoc/command/real/BDO/package-tree.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - -command.real.BDO Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package command.real.BDO

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    -
      -
    • java.lang.Object -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter (implements net.dv8tion.jda.core.hooks.EventListener) - -
      • -
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/command/real/BDO/package-use.html b/docs/page/javadoc/command/real/BDO/package-use.html deleted file mode 100644 index 712295e..0000000 --- a/docs/page/javadoc/command/real/BDO/package-use.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Package command.real.BDO (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    command.real.BDO

    -
    -
    No usage of command.real.BDO
    - - - - - - diff --git a/docs/page/javadoc/command/real/JoinListener.html b/docs/page/javadoc/command/real/JoinListener.html deleted file mode 100644 index 58f858c..0000000 --- a/docs/page/javadoc/command/real/JoinListener.html +++ /dev/null @@ -1,325 +0,0 @@ - - - - - -JoinListener (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real
    -

    Class JoinListener

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.JoinListener
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      -
      public class JoinListener
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        JoinListener() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        voidonGuildJoin(net.dv8tion.jda.core.events.guild.GuildJoinEvent event) 
        voidonGuildLeave(net.dv8tion.jda.core.events.guild.GuildLeaveEvent event) 
        voidonGuildUpdateName(net.dv8tion.jda.core.events.guild.update.GuildUpdateNameEvent event) 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageReceived, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          JoinListener

          -
          public JoinListener()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          onGuildJoin

          -
          public void onGuildJoin(net.dv8tion.jda.core.events.guild.GuildJoinEvent event)
          -
          -
          Overrides:
          -
          onGuildJoin in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        - - - -
          -
        • -

          onGuildLeave

          -
          public void onGuildLeave(net.dv8tion.jda.core.events.guild.GuildLeaveEvent event)
          -
          -
          Overrides:
          -
          onGuildLeave in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        - - - -
          -
        • -

          onGuildUpdateName

          -
          public void onGuildUpdateName(net.dv8tion.jda.core.events.guild.update.GuildUpdateNameEvent event)
          -
          -
          Overrides:
          -
          onGuildUpdateName in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/class-use/JoinListener.html b/docs/page/javadoc/command/real/class-use/JoinListener.html deleted file mode 100644 index 82079cf..0000000 --- a/docs/page/javadoc/command/real/class-use/JoinListener.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.JoinListener (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.JoinListener

    -
    -
    No usage of command.real.JoinListener
    - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/ConfigurationCommand.html b/docs/page/javadoc/command/real/configuration/ConfigurationCommand.html deleted file mode 100644 index bccdbb0..0000000 --- a/docs/page/javadoc/command/real/configuration/ConfigurationCommand.html +++ /dev/null @@ -1,347 +0,0 @@ - - - - - -ConfigurationCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.configuration
    -

    Class ConfigurationCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.configuration.ConfigurationCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class ConfigurationCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        ConfigurationCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        private voidconfiguration(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        static java.lang.StringgetCommand() -
        Deprecated. 
        static java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          ConfigurationCommand

          -
          public ConfigurationCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public static java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public static java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        - - - -
          -
        • -

          configuration

          -
          private void configuration(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/ConfigurationReceiver.html b/docs/page/javadoc/command/real/configuration/ConfigurationReceiver.html deleted file mode 100644 index 4958073..0000000 --- a/docs/page/javadoc/command/real/configuration/ConfigurationReceiver.html +++ /dev/null @@ -1,369 +0,0 @@ - - - - - -ConfigurationReceiver (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.configuration
    -

    Class ConfigurationReceiver

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.configuration.ConfigurationReceiver
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      -
      public class ConfigurationReceiver
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - - - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        private voidconfiguration(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) 
        static java.lang.StringgetConfigurationCommandCommand() 
        static java.lang.StringgetConfigurationCommandCommandDescription() 
        java.lang.StringgetHelpCommand() 
        static java.lang.StringgetInfoCommand() 
        static java.lang.StringgetInfoCommandDescription() 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          ConfigurationReceiver

          -
          public ConfigurationReceiver()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getConfigurationCommandCommand

          -
          public static java.lang.String getConfigurationCommandCommand()
          -
        • -
        - - - -
          -
        • -

          getConfigurationCommandCommandDescription

          -
          public static java.lang.String getConfigurationCommandCommandDescription()
          -
        • -
        - - - -
          -
        • -

          getInfoCommand

          -
          public static java.lang.String getInfoCommand()
          -
        • -
        - - - -
          -
        • -

          getInfoCommandDescription

          -
          public static java.lang.String getInfoCommandDescription()
          -
        • -
        - - - -
          -
        • -

          getHelpCommand

          -
          public java.lang.String getHelpCommand()
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        - - - -
          -
        • -

          configuration

          -
          private void configuration(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/HelpCommand.html b/docs/page/javadoc/command/real/configuration/HelpCommand.html deleted file mode 100644 index 5d33f6a..0000000 --- a/docs/page/javadoc/command/real/configuration/HelpCommand.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -HelpCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.configuration
    -

    Class HelpCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.configuration.HelpCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class HelpCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        HelpCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        java.lang.StringgetCommand() -
        Deprecated. 
        java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          HelpCommand

          -
          public HelpCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/InfoCommand.html b/docs/page/javadoc/command/real/configuration/InfoCommand.html deleted file mode 100644 index 36a814d..0000000 --- a/docs/page/javadoc/command/real/configuration/InfoCommand.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -InfoCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.configuration
    -

    Class InfoCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.configuration.InfoCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class InfoCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        InfoCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetCommand() -
        Deprecated. 
        static java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          InfoCommand

          -
          public InfoCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public static java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public static java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/class-use/ConfigurationCommand.html b/docs/page/javadoc/command/real/configuration/class-use/ConfigurationCommand.html deleted file mode 100644 index 23ca34c..0000000 --- a/docs/page/javadoc/command/real/configuration/class-use/ConfigurationCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.configuration.ConfigurationCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.configuration.ConfigurationCommand

    -
    -
    No usage of command.real.configuration.ConfigurationCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/class-use/ConfigurationReceiver.html b/docs/page/javadoc/command/real/configuration/class-use/ConfigurationReceiver.html deleted file mode 100644 index 4936e55..0000000 --- a/docs/page/javadoc/command/real/configuration/class-use/ConfigurationReceiver.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.configuration.ConfigurationReceiver (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.configuration.ConfigurationReceiver

    -
    -
    No usage of command.real.configuration.ConfigurationReceiver
    - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/class-use/HelpCommand.html b/docs/page/javadoc/command/real/configuration/class-use/HelpCommand.html deleted file mode 100644 index 02b60e8..0000000 --- a/docs/page/javadoc/command/real/configuration/class-use/HelpCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.configuration.HelpCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.configuration.HelpCommand

    -
    -
    No usage of command.real.configuration.HelpCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/class-use/InfoCommand.html b/docs/page/javadoc/command/real/configuration/class-use/InfoCommand.html deleted file mode 100644 index 3e9fc11..0000000 --- a/docs/page/javadoc/command/real/configuration/class-use/InfoCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.configuration.InfoCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.configuration.InfoCommand

    -
    -
    No usage of command.real.configuration.InfoCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/package-frame.html b/docs/page/javadoc/command/real/configuration/package-frame.html deleted file mode 100644 index 79d5aed..0000000 --- a/docs/page/javadoc/command/real/configuration/package-frame.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -command.real.configuration (Documentazione TakaoBot) - - - - - -

    command.real.configuration

    - - - diff --git a/docs/page/javadoc/command/real/configuration/package-summary.html b/docs/page/javadoc/command/real/configuration/package-summary.html deleted file mode 100644 index 42de41b..0000000 --- a/docs/page/javadoc/command/real/configuration/package-summary.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - -command.real.configuration (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package command.real.configuration

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/package-tree.html b/docs/page/javadoc/command/real/configuration/package-tree.html deleted file mode 100644 index 5ce03d1..0000000 --- a/docs/page/javadoc/command/real/configuration/package-tree.html +++ /dev/null @@ -1,144 +0,0 @@ - - - - - -command.real.configuration Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package command.real.configuration

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/configuration/package-use.html b/docs/page/javadoc/command/real/configuration/package-use.html deleted file mode 100644 index b3286f4..0000000 --- a/docs/page/javadoc/command/real/configuration/package-use.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Package command.real.configuration (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    command.real.configuration

    -
    -
    No usage of command.real.configuration
    - - - - - - diff --git a/docs/page/javadoc/command/real/package-frame.html b/docs/page/javadoc/command/real/package-frame.html deleted file mode 100644 index 602dd8c..0000000 --- a/docs/page/javadoc/command/real/package-frame.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - -command.real (Documentazione TakaoBot) - - - - - -

    command.real

    -
    -

    Classes

    - -
    - - diff --git a/docs/page/javadoc/command/real/package-summary.html b/docs/page/javadoc/command/real/package-summary.html deleted file mode 100644 index 37d59aa..0000000 --- a/docs/page/javadoc/command/real/package-summary.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - -command.real (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package command.real

    -
    -
    -
      -
    • - - - - - - - - - - - - -
      Class Summary 
      ClassDescription
      JoinListener 
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/command/real/package-tree.html b/docs/page/javadoc/command/real/package-tree.html deleted file mode 100644 index 54d9f44..0000000 --- a/docs/page/javadoc/command/real/package-tree.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - -command.real Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package command.real

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    -
      -
    • java.lang.Object -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter (implements net.dv8tion.jda.core.hooks.EventListener) - -
      • -
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/command/real/package-use.html b/docs/page/javadoc/command/real/package-use.html deleted file mode 100644 index 7865f38..0000000 --- a/docs/page/javadoc/command/real/package-use.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Package command.real (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    command.real

    -
    -
    No usage of command.real
    - - - - - - diff --git a/docs/page/javadoc/command/real/sound/AudioPlayerSendHandler.html b/docs/page/javadoc/command/real/sound/AudioPlayerSendHandler.html deleted file mode 100644 index a939ab8..0000000 --- a/docs/page/javadoc/command/real/sound/AudioPlayerSendHandler.html +++ /dev/null @@ -1,377 +0,0 @@ - - - - - -AudioPlayerSendHandler (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.sound
    -

    Class AudioPlayerSendHandler

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • command.real.sound.AudioPlayerSendHandler
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.audio.AudioSendHandler
      -
      -
      -
      -
      public class AudioPlayerSendHandler
      -extends java.lang.Object
      -implements net.dv8tion.jda.core.audio.AudioSendHandler
      -
      This is a wrapper around AudioPlayer which makes it behave as an AudioSendHandler for JDA. As JDA calls canProvide - before every call to provide20MsAudio(), we pull the frame in canProvide() and use the frame we already pulled in - provide20MsAudio().
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        private com.sedmelluq.discord.lavaplayer.player.AudioPlayeraudioPlayer 
        private com.sedmelluq.discord.lavaplayer.track.playback.AudioFramelastFrame 
        -
          -
        • - - -

          Fields inherited from interface net.dv8tion.jda.core.audio.AudioSendHandler

          -INPUT_FORMAT
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        AudioPlayerSendHandler(com.sedmelluq.discord.lavaplayer.player.AudioPlayer audioPlayer) 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        booleancanProvide() 
        booleanisOpus() 
        byte[]provide20MsAudio() 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          audioPlayer

          -
          private final com.sedmelluq.discord.lavaplayer.player.AudioPlayer audioPlayer
          -
        • -
        - - - -
          -
        • -

          lastFrame

          -
          private com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame lastFrame
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          AudioPlayerSendHandler

          -
          public AudioPlayerSendHandler(com.sedmelluq.discord.lavaplayer.player.AudioPlayer audioPlayer)
          -
          -
          Parameters:
          -
          audioPlayer - Audio player to wrap.
          -
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          canProvide

          -
          public boolean canProvide()
          -
          -
          Specified by:
          -
          canProvide in interface net.dv8tion.jda.core.audio.AudioSendHandler
          -
          -
        • -
        - - - -
          -
        • -

          provide20MsAudio

          -
          public byte[] provide20MsAudio()
          -
          -
          Specified by:
          -
          provide20MsAudio in interface net.dv8tion.jda.core.audio.AudioSendHandler
          -
          -
        • -
        - - - -
          -
        • -

          isOpus

          -
          public boolean isOpus()
          -
          -
          Specified by:
          -
          isOpus in interface net.dv8tion.jda.core.audio.AudioSendHandler
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/sound/GuildMusicManager.html b/docs/page/javadoc/command/real/sound/GuildMusicManager.html deleted file mode 100644 index b513ed0..0000000 --- a/docs/page/javadoc/command/real/sound/GuildMusicManager.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - -GuildMusicManager (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.sound
    -

    Class GuildMusicManager

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • command.real.sound.GuildMusicManager
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class GuildMusicManager
      -extends java.lang.Object
      -
      Holder for both the player and a track scheduler for one guild.
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        com.sedmelluq.discord.lavaplayer.player.AudioPlayerplayer -
        Audio player for the guild.
        -
        TrackSchedulerscheduler -
        Track scheduler for the player.
        -
        AudioPlayerSendHandlersendHandler -
        Wrapper around AudioPlayer to use it as an AudioSendHandler.
        -
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        GuildMusicManager(com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager manager) -
        Creates a player and a track scheduler.
        -
        -
      • -
      - -
        -
      • - - -

        Method Summary

        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          player

          -
          public final com.sedmelluq.discord.lavaplayer.player.AudioPlayer player
          -
          Audio player for the guild.
          -
        • -
        - - - -
          -
        • -

          scheduler

          -
          public final TrackScheduler scheduler
          -
          Track scheduler for the player.
          -
        • -
        - - - -
          -
        • -

          sendHandler

          -
          public final AudioPlayerSendHandler sendHandler
          -
          Wrapper around AudioPlayer to use it as an AudioSendHandler.
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          GuildMusicManager

          -
          public GuildMusicManager(com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager manager)
          -
          Creates a player and a track scheduler.
          -
          -
          Parameters:
          -
          manager - Audio player manager to use for creating the player.
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/sound/MusicManager.html b/docs/page/javadoc/command/real/sound/MusicManager.html deleted file mode 100644 index cdab2bc..0000000 --- a/docs/page/javadoc/command/real/sound/MusicManager.html +++ /dev/null @@ -1,701 +0,0 @@ - - - - - -MusicManager (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.sound
    -

    Class MusicManager

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • command.real.sound.MusicManager
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class MusicManager
      -extends java.lang.Object
      -
      Classe per gestire il musicBot
      -
    • -
    -
    -
    -
      -
    • - - - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        MusicManager() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        private voidchangeVolume(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per cambiare il volume, attualmente non in uso.
        -
        (package private) voidclearQueue(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) 
        (package private) voidgetListQueue(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per ottenere la lista della coda
        -
        private GuildMusicManagergetMusicManager(java.lang.String guildId) 
        private static java.lang.StringgetTimestamp(long milliseconds) 
        private static java.lang.StringgetUrl(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Parsing del messaggio per ottenere l'url
        -
        private voidjoin(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per eseguire il join nel canale
        -
        (package private) voidleave(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per far uscire il bot dalla lobby, bloccherà la queue - e la svuoterà
        -
        private voidloadAndPlay(GuildMusicManager mng, - net.dv8tion.jda.core.entities.MessageChannel channel, - java.lang.String url, - boolean addPlaylist) -
        Metodo per caricare una traccia o una playlist nella coda
        -
        (package private) voidnowPlay(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per ottenere la traccia attualmente in riproduzione
        -
        (package private) voidpauseResume(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per mettere in pausa o riprendere la traccia attualmente - in riproduzione
        -
        (package private) voidplay(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per riprodurre l'url audio passato come parametro
        -
        (package private) voidplayPlaylist(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per riprodurre una playlist dall'url passato come parametro
        -
        (package private) voidrepeat(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per ripetere la traccia attualmente in riproduzione
        -
        (package private) voidreset(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per resettare il bot in caso di problemi.
        -
        (package private) voidrestart(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per riavviare la traccia attualmente in riproduzione
        -
        (package private) voidshuffleQueue(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per randomizzare la coda
        -
        (package private) voidskip(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per saltare la traccia attualmente in riproduzione
        -
        (package private) voidstop(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Metodo per stoppare la riproduzione e pulire la coda
        -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - - - - - -
          -
        • -

          musicManagers

          -
          private final java.util.Map<java.lang.String,GuildMusicManager> musicManagers
          -
        • -
        - - - -
          -
        • -

          playerManager

          -
          private com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager playerManager
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          MusicManager

          -
          public MusicManager()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getUrl

          -
          private static java.lang.String getUrl(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Parsing del messaggio per ottenere l'url
          -
          -
          Parameters:
          -
          event -
          -
          Returns:
          -
          String url della canzone
          -
          -
        • -
        - - - -
          -
        • -

          getTimestamp

          -
          private static java.lang.String getTimestamp(long milliseconds)
          -
        • -
        - - - -
          -
        • -

          join

          -
          private void join(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per eseguire il join nel canale
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          leave

          -
          void leave(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per far uscire il bot dalla lobby, bloccherà la queue - e la svuoterà
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          play

          -
          void play(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per riprodurre l'url audio passato come parametro
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          playPlaylist

          -
          void playPlaylist(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per riprodurre una playlist dall'url passato come parametro
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          skip

          -
          void skip(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per saltare la traccia attualmente in riproduzione
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          pauseResume

          -
          void pauseResume(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per mettere in pausa o riprendere la traccia attualmente - in riproduzione
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          stop

          -
          void stop(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per stoppare la riproduzione e pulire la coda
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          changeVolume

          -
          private void changeVolume(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per cambiare il volume, attualmente non in uso. - Bisogno di calcolo computazionale extra per il cambio del volume.
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          restart

          -
          void restart(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per riavviare la traccia attualmente in riproduzione
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          repeat

          -
          void repeat(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per ripetere la traccia attualmente in riproduzione
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          reset

          -
          void reset(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per resettare il bot in caso di problemi. - Pulisce la coda, e resetta i canali audio
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          nowPlay

          -
          void nowPlay(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per ottenere la traccia attualmente in riproduzione
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          getListQueue

          -
          void getListQueue(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per ottenere la lista della coda
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          shuffleQueue

          -
          void shuffleQueue(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Metodo per randomizzare la coda
          -
          -
          Parameters:
          -
          event -
          -
          -
        • -
        - - - -
          -
        • -

          clearQueue

          -
          void clearQueue(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
        • -
        - - - -
          -
        • -

          loadAndPlay

          -
          private void loadAndPlay(GuildMusicManager mng,
          -                         net.dv8tion.jda.core.entities.MessageChannel channel,
          -                         java.lang.String url,
          -                         boolean addPlaylist)
          -
          Metodo per caricare una traccia o una playlist nella coda
          -
          -
          Parameters:
          -
          mng -
          -
          channel -
          -
          url -
          -
          addPlaylist -
          -
          -
        • -
        - - - -
          -
        • -

          getMusicManager

          -
          private GuildMusicManager getMusicManager(java.lang.String guildId)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/sound/PlayerControlCommand.html b/docs/page/javadoc/command/real/sound/PlayerControlCommand.html deleted file mode 100644 index 202f768..0000000 --- a/docs/page/javadoc/command/real/sound/PlayerControlCommand.html +++ /dev/null @@ -1,327 +0,0 @@ - - - - - -PlayerControlCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.sound
    -

    Class PlayerControlCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.sound.PlayerControlCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      -
      public class PlayerControlCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - - - - - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - -
        All Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - - - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          PlayerControlCommand

          -
          public PlayerControlCommand()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/sound/TrackScheduler.html b/docs/page/javadoc/command/real/sound/TrackScheduler.html deleted file mode 100644 index 84355c6..0000000 --- a/docs/page/javadoc/command/real/sound/TrackScheduler.html +++ /dev/null @@ -1,463 +0,0 @@ - - - - - -TrackScheduler (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.sound
    -

    Class TrackScheduler

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter
      • -
      • -
          -
        • command.real.sound.TrackScheduler
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      com.sedmelluq.discord.lavaplayer.player.event.AudioEventListener
      -
      -
      -
      -
      public class TrackScheduler
      -extends com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter
      -
      This class schedules tracks for the audio player. It contains the queue of tracks.
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        com.sedmelluq.discord.lavaplayer.track.AudioTracklastTrack 
        (package private) com.sedmelluq.discord.lavaplayer.player.AudioPlayerplayer 
        private java.util.Queue<com.sedmelluq.discord.lavaplayer.track.AudioTrack>queue 
        private booleanrepeating 
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        TrackScheduler(com.sedmelluq.discord.lavaplayer.player.AudioPlayer player) 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        java.util.Queue<com.sedmelluq.discord.lavaplayer.track.AudioTrack>getQueue() 
        booleanisRepeating() 
        voidnextTrack() -
        Start the next track, stopping the current one if it is playing.
        -
        voidonTrackEnd(com.sedmelluq.discord.lavaplayer.player.AudioPlayer player, - com.sedmelluq.discord.lavaplayer.track.AudioTrack track, - com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason endReason) 
        voidqueue(com.sedmelluq.discord.lavaplayer.track.AudioTrack track) -
        Add the next track to queue or play right away if nothing is in the queue.
        -
        voidsetRepeating(boolean repeating) 
        voidshuffle() 
        -
          -
        • - - -

          Methods inherited from class com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter

          -onEvent, onPlayerPause, onPlayerResume, onTrackException, onTrackStart, onTrackStuck
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          repeating

          -
          private boolean repeating
          -
        • -
        - - - -
          -
        • -

          player

          -
          final com.sedmelluq.discord.lavaplayer.player.AudioPlayer player
          -
        • -
        - - - -
          -
        • -

          queue

          -
          private final java.util.Queue<com.sedmelluq.discord.lavaplayer.track.AudioTrack> queue
          -
        • -
        - - - -
          -
        • -

          lastTrack

          -
          public com.sedmelluq.discord.lavaplayer.track.AudioTrack lastTrack
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          TrackScheduler

          -
          public TrackScheduler(com.sedmelluq.discord.lavaplayer.player.AudioPlayer player)
          -
          -
          Parameters:
          -
          player - The audio player this scheduler uses
          -
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          queue

          -
          public void queue(com.sedmelluq.discord.lavaplayer.track.AudioTrack track)
          -
          Add the next track to queue or play right away if nothing is in the queue.
          -
          -
          Parameters:
          -
          track - The track to play or add to queue.
          -
          -
        • -
        - - - -
          -
        • -

          nextTrack

          -
          public void nextTrack()
          -
          Start the next track, stopping the current one if it is playing.
          -
        • -
        - - - -
          -
        • -

          onTrackEnd

          -
          public void onTrackEnd(com.sedmelluq.discord.lavaplayer.player.AudioPlayer player,
          -                       com.sedmelluq.discord.lavaplayer.track.AudioTrack track,
          -                       com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason endReason)
          -
          -
          Overrides:
          -
          onTrackEnd in class com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter
          -
          -
        • -
        - - - -
          -
        • -

          getQueue

          -
          public java.util.Queue<com.sedmelluq.discord.lavaplayer.track.AudioTrack> getQueue()
          -
        • -
        - - - -
          -
        • -

          isRepeating

          -
          public boolean isRepeating()
          -
        • -
        - - - -
          -
        • -

          setRepeating

          -
          public void setRepeating(boolean repeating)
          -
        • -
        - - - -
          -
        • -

          shuffle

          -
          public void shuffle()
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/sound/class-use/AudioPlayerSendHandler.html b/docs/page/javadoc/command/real/sound/class-use/AudioPlayerSendHandler.html deleted file mode 100644 index 0b1a94f..0000000 --- a/docs/page/javadoc/command/real/sound/class-use/AudioPlayerSendHandler.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - -Uses of Class command.real.sound.AudioPlayerSendHandler (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.sound.AudioPlayerSendHandler

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/sound/class-use/GuildMusicManager.html b/docs/page/javadoc/command/real/sound/class-use/GuildMusicManager.html deleted file mode 100644 index b2a69fc..0000000 --- a/docs/page/javadoc/command/real/sound/class-use/GuildMusicManager.html +++ /dev/null @@ -1,195 +0,0 @@ - - - - - -Uses of Class command.real.sound.GuildMusicManager (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.sound.GuildMusicManager

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/sound/class-use/MusicManager.html b/docs/page/javadoc/command/real/sound/class-use/MusicManager.html deleted file mode 100644 index 1d6704f..0000000 --- a/docs/page/javadoc/command/real/sound/class-use/MusicManager.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - -Uses of Class command.real.sound.MusicManager (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.sound.MusicManager

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/sound/class-use/PlayerControlCommand.html b/docs/page/javadoc/command/real/sound/class-use/PlayerControlCommand.html deleted file mode 100644 index b2f9534..0000000 --- a/docs/page/javadoc/command/real/sound/class-use/PlayerControlCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.sound.PlayerControlCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.sound.PlayerControlCommand

    -
    -
    No usage of command.real.sound.PlayerControlCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/sound/class-use/TrackScheduler.html b/docs/page/javadoc/command/real/sound/class-use/TrackScheduler.html deleted file mode 100644 index 5b929e7..0000000 --- a/docs/page/javadoc/command/real/sound/class-use/TrackScheduler.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - -Uses of Class command.real.sound.TrackScheduler (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.sound.TrackScheduler

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/sound/package-frame.html b/docs/page/javadoc/command/real/sound/package-frame.html deleted file mode 100644 index a84f3dd..0000000 --- a/docs/page/javadoc/command/real/sound/package-frame.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -command.real.sound (Documentazione TakaoBot) - - - - - -

    command.real.sound

    - - - diff --git a/docs/page/javadoc/command/real/sound/package-summary.html b/docs/page/javadoc/command/real/sound/package-summary.html deleted file mode 100644 index 839d866..0000000 --- a/docs/page/javadoc/command/real/sound/package-summary.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - -command.real.sound (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package command.real.sound

    -
    -
    -
      -
    • - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Class Summary 
      ClassDescription
      AudioPlayerSendHandler -
      This is a wrapper around AudioPlayer which makes it behave as an AudioSendHandler for JDA.
      -
      GuildMusicManager -
      Holder for both the player and a track scheduler for one guild.
      -
      MusicManager -
      Classe per gestire il musicBot
      -
      PlayerControlCommand 
      TrackScheduler -
      This class schedules tracks for the audio player.
      -
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/command/real/sound/package-tree.html b/docs/page/javadoc/command/real/sound/package-tree.html deleted file mode 100644 index 81cf99e..0000000 --- a/docs/page/javadoc/command/real/sound/package-tree.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - -command.real.sound Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package command.real.sound

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    -
      -
    • java.lang.Object -
        -
      • com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter (implements com.sedmelluq.discord.lavaplayer.player.event.AudioEventListener) - -
      • -
      • command.real.sound.AudioPlayerSendHandler (implements net.dv8tion.jda.core.audio.AudioSendHandler)
      • -
      • command.real.sound.GuildMusicManager
      • -
      • net.dv8tion.jda.core.hooks.ListenerAdapter (implements net.dv8tion.jda.core.hooks.EventListener) - -
      • -
      • command.real.sound.MusicManager
      • -
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/command/real/sound/package-use.html b/docs/page/javadoc/command/real/sound/package-use.html deleted file mode 100644 index be4c0f5..0000000 --- a/docs/page/javadoc/command/real/sound/package-use.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - -Uses of Package command.real.sound (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    command.real.sound

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertReceiver.html b/docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertReceiver.html deleted file mode 100644 index 699c8bf..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertReceiver.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - - -ATMAlertReceiver (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.tpl.atmAlert
    -

    Class ATMAlertReceiver

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.tpl.atmAlert.ATMAlertReceiver
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      -
      public class ATMAlertReceiver
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        ATMAlertReceiver() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetATMStartCommand() 
        static java.lang.StringgetATMStartCommandDescription() 
        static java.lang.StringgetATMStopCommand() 
        static java.lang.StringgetATMStopCommandDescription() 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          ATMAlertReceiver

          -
          public ATMAlertReceiver()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getATMStartCommand

          -
          public static java.lang.String getATMStartCommand()
          -
        • -
        - - - -
          -
        • -

          getATMStartCommandDescription

          -
          public static java.lang.String getATMStartCommandDescription()
          -
        • -
        - - - -
          -
        • -

          getATMStopCommand

          -
          public static java.lang.String getATMStopCommand()
          -
        • -
        - - - -
          -
        • -

          getATMStopCommandDescription

          -
          public static java.lang.String getATMStopCommandDescription()
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertStartCommand.html b/docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertStartCommand.html deleted file mode 100644 index c6ee3aa..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertStartCommand.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -ATMAlertStartCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.tpl.atmAlert
    -

    Class ATMAlertStartCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.tpl.atmAlert.ATMAlertStartCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class ATMAlertStartCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        ATMAlertStartCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetCommand() -
        Deprecated. 
        static java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          ATMAlertStartCommand

          -
          public ATMAlertStartCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public static java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public static java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertStopCommand.html b/docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertStopCommand.html deleted file mode 100644 index bb95d5a..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/ATMAlertStopCommand.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -ATMAlertStopCommand (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.tpl.atmAlert
    -

    Class ATMAlertStopCommand

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • net.dv8tion.jda.core.hooks.ListenerAdapter
      • -
      • -
          -
        • command.real.tpl.atmAlert.ATMAlertStopCommand
        • -
        -
      • -
      -
    • -
    -
    -
      -
    • -
      -
      All Implemented Interfaces:
      -
      net.dv8tion.jda.core.hooks.EventListener
      -
      -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class ATMAlertStopCommand
      -extends net.dv8tion.jda.core.hooks.ListenerAdapter
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        ATMAlertStopCommand() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetCommand() -
        Deprecated. 
        static java.lang.StringgetCommandDescription() -
        Deprecated. 
        voidonMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event) -
        Deprecated. 
        -
          -
        • - - -

          Methods inherited from class net.dv8tion.jda.core.hooks.ListenerAdapter

          -onCallCreate, onCallDelete, onCallUpdateRegion, onCallUpdateRingingUsers, onCallVoiceJoin, onCallVoiceLeave, onCallVoiceSelfDeafen, onCallVoiceSelfMute, onCategoryCreate, onCategoryDelete, onCategoryUpdateName, onCategoryUpdatePermissions, onCategoryUpdatePosition, onDisconnect, onEmoteAdded, onEmoteRemoved, onEmoteUpdateName, onEmoteUpdateRoles, onEvent, onException, onFriendAdded, onFriendRemoved, onFriendRequestCanceled, onFriendRequestIgnored, onFriendRequestReceived, onFriendRequestSent, onGenericCall, onGenericCallUpdate, onGenericCallVoice, onGenericCategory, onGenericCategoryUpdate, onGenericEmote, onGenericEmoteUpdate, onGenericEvent, onGenericGroup, onGenericGroupMessage, onGenericGroupMessageReaction, onGenericGroupUpdate, onGenericGuild, onGenericGuildMember, onGenericGuildMessage, onGenericGuildMessageReaction, onGenericGuildUpdate, onGenericGuildVoice, onGenericMessage, onGenericMessageReaction, onGenericPrivateMessage, onGenericPrivateMessageReaction, onGenericRelationship, onGenericRelationshipAdd, onGenericRelationshipRemove, onGenericRole, onGenericRoleUpdate, onGenericSelfUpdate, onGenericTextChannel, onGenericTextChannelUpdate, onGenericUpdate, onGenericUser, onGenericUserPresence, onGenericVoiceChannel, onGenericVoiceChannelUpdate, onGroupJoin, onGroupLeave, onGroupMessageDelete, onGroupMessageEmbed, onGroupMessageReactionAdd, onGroupMessageReactionRemove, onGroupMessageReactionRemoveAll, onGroupMessageReceived, onGroupMessageUpdate, onGroupUpdateIcon, onGroupUpdateName, onGroupUpdateOwner, onGroupUserJoin, onGroupUserLeave, onGuildAvailable, onGuildBan, onGuildJoin, onGuildLeave, onGuildMemberJoin, onGuildMemberLeave, onGuildMemberNickChange, onGuildMemberRoleAdd, onGuildMemberRoleRemove, onGuildMessageDelete, onGuildMessageEmbed, onGuildMessageReactionAdd, onGuildMessageReactionRemove, onGuildMessageReactionRemoveAll, onGuildMessageReceived, onGuildMessageUpdate, onGuildReady, onGuildUnavailable, onGuildUnban, onGuildUpdateAfkChannel, onGuildUpdateAfkTimeout, onGuildUpdateExplicitContentLevel, onGuildUpdateFeatures, onGuildUpdateIcon, onGuildUpdateMFALevel, onGuildUpdateName, onGuildUpdateNotificationLevel, onGuildUpdateOwner, onGuildUpdateRegion, onGuildUpdateSplash, onGuildUpdateSystemChannel, onGuildUpdateVerificationLevel, onGuildVoiceDeafen, onGuildVoiceGuildDeafen, onGuildVoiceGuildMute, onGuildVoiceJoin, onGuildVoiceLeave, onGuildVoiceMove, onGuildVoiceMute, onGuildVoiceSelfDeafen, onGuildVoiceSelfMute, onGuildVoiceSuppress, onGuildVoiceUpdate, onHttpRequest, onMessageBulkDelete, onMessageDelete, onMessageEmbed, onMessageReactionAdd, onMessageReactionRemove, onMessageReactionRemoveAll, onMessageUpdate, onPrivateChannelCreate, onPrivateChannelDelete, onPrivateMessageDelete, onPrivateMessageEmbed, onPrivateMessageReactionAdd, onPrivateMessageReactionRemove, onPrivateMessageReceived, onPrivateMessageUpdate, onReady, onReconnect, onResume, onRoleCreate, onRoleDelete, onRoleUpdateColor, onRoleUpdateHoisted, onRoleUpdateMentionable, onRoleUpdateName, onRoleUpdatePermissions, onRoleUpdatePosition, onSelfUpdateAvatar, onSelfUpdateEmail, onSelfUpdateMFA, onSelfUpdateName, onSelfUpdateVerified, onShutdown, onStatusChange, onTextChannelCreate, onTextChannelDelete, onTextChannelUpdateName, onTextChannelUpdateNSFW, onTextChannelUpdateParent, onTextChannelUpdatePermissions, onTextChannelUpdatePosition, onTextChannelUpdateSlowmode, onTextChannelUpdateTopic, onUnavailableGuildJoined, onUserBlocked, onUserTyping, onUserUnblocked, onUserUpdateAvatar, onUserUpdateDiscriminator, onUserUpdateGame, onUserUpdateName, onUserUpdateOnlineStatus, onVoiceChannelCreate, onVoiceChannelDelete, onVoiceChannelUpdateBitrate, onVoiceChannelUpdateName, onVoiceChannelUpdateParent, onVoiceChannelUpdatePermissions, onVoiceChannelUpdatePosition, onVoiceChannelUpdateUserLimit
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          ATMAlertStopCommand

          -
          public ATMAlertStopCommand()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getCommand

          -
          public static java.lang.String getCommand()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getCommandDescription

          -
          public static java.lang.String getCommandDescription()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          onMessageReceived

          -
          public void onMessageReceived(net.dv8tion.jda.core.events.message.MessageReceivedEvent event)
          -
          Deprecated. 
          -
          -
          Overrides:
          -
          onMessageReceived in class net.dv8tion.jda.core.hooks.ListenerAdapter
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/ATMRSSReader.html b/docs/page/javadoc/command/real/tpl/atmAlert/ATMRSSReader.html deleted file mode 100644 index 6d83ce4..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/ATMRSSReader.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - -ATMRSSReader (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.tpl.atmAlert
    -

    Class ATMRSSReader

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • command.real.tpl.atmAlert.ATMRSSReader
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class ATMRSSReader
      -extends java.lang.Object
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        ATMRSSReader() 
        -
      • -
      - - -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          ATMRSSReader

          -
          public ATMRSSReader()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          readRSS

          -
          public static RSSMessage readRSS(java.lang.String URL)
          -
        • -
        - - - -
          -
        • -

          prepareRSStoEmbeddedMessage

          -
          public static net.dv8tion.jda.core.entities.MessageEmbed prepareRSStoEmbeddedMessage(RSSMessage message)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/AtmScheduler.html b/docs/page/javadoc/command/real/tpl/atmAlert/AtmScheduler.html deleted file mode 100644 index c642231..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/AtmScheduler.html +++ /dev/null @@ -1,365 +0,0 @@ - - - - - -AtmScheduler (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    command.real.tpl.atmAlert
    -

    Class AtmScheduler

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • command.real.tpl.atmAlert.AtmScheduler
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class AtmScheduler
      -extends java.lang.Object
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        private static TwitterManagermanager 
        private static java.lang.StringtwitterUrl 
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        AtmScheduler() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        private static voidgetMessage(long tweetId, - java.lang.String twitterMessage, - java.lang.String mediaUrl, - java.lang.String profileImageUrl) 
        private static voidpublish(RSSMessage message) 
        static voidstartAtmTweetScheduler() 
        static java.util.TimerTasktaskFeedRSSATM() 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - - - - - -
          -
        • -

          twitterUrl

          -
          private static java.lang.String twitterUrl
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          AtmScheduler

          -
          public AtmScheduler()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          startAtmTweetScheduler

          -
          public static void startAtmTweetScheduler()
          -
        • -
        - - - -
          -
        • -

          taskFeedRSSATM

          -
          public static java.util.TimerTask taskFeedRSSATM()
          -
        • -
        - - - -
          -
        • -

          publish

          -
          private static void publish(RSSMessage message)
          -
        • -
        - - - -
          -
        • -

          getMessage

          -
          private static void getMessage(long tweetId,
          -                               java.lang.String twitterMessage,
          -                               java.lang.String mediaUrl,
          -                               java.lang.String profileImageUrl)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertReceiver.html b/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertReceiver.html deleted file mode 100644 index 9b330bd..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertReceiver.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.tpl.atmAlert.ATMAlertReceiver (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.tpl.atmAlert.ATMAlertReceiver

    -
    -
    No usage of command.real.tpl.atmAlert.ATMAlertReceiver
    - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertStartCommand.html b/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertStartCommand.html deleted file mode 100644 index bbc56cb..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertStartCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.tpl.atmAlert.ATMAlertStartCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.tpl.atmAlert.ATMAlertStartCommand

    -
    -
    No usage of command.real.tpl.atmAlert.ATMAlertStartCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertStopCommand.html b/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertStopCommand.html deleted file mode 100644 index b6d0b09..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMAlertStopCommand.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.tpl.atmAlert.ATMAlertStopCommand (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.tpl.atmAlert.ATMAlertStopCommand

    -
    -
    No usage of command.real.tpl.atmAlert.ATMAlertStopCommand
    - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMRSSReader.html b/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMRSSReader.html deleted file mode 100644 index 0c29441..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/class-use/ATMRSSReader.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.tpl.atmAlert.ATMRSSReader (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.tpl.atmAlert.ATMRSSReader

    -
    -
    No usage of command.real.tpl.atmAlert.ATMRSSReader
    - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/class-use/AtmScheduler.html b/docs/page/javadoc/command/real/tpl/atmAlert/class-use/AtmScheduler.html deleted file mode 100644 index 7b50cc1..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/class-use/AtmScheduler.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class command.real.tpl.atmAlert.AtmScheduler (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    command.real.tpl.atmAlert.AtmScheduler

    -
    -
    No usage of command.real.tpl.atmAlert.AtmScheduler
    - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/package-frame.html b/docs/page/javadoc/command/real/tpl/atmAlert/package-frame.html deleted file mode 100644 index cd45a0d..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/package-frame.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -command.real.tpl.atmAlert (Documentazione TakaoBot) - - - - - -

    command.real.tpl.atmAlert

    - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/package-summary.html b/docs/page/javadoc/command/real/tpl/atmAlert/package-summary.html deleted file mode 100644 index bcddfb2..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/package-summary.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - -command.real.tpl.atmAlert (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package command.real.tpl.atmAlert

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/package-tree.html b/docs/page/javadoc/command/real/tpl/atmAlert/package-tree.html deleted file mode 100644 index 442f7eb..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/package-tree.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - -command.real.tpl.atmAlert Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package command.real.tpl.atmAlert

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    - -
    - - - - - - diff --git a/docs/page/javadoc/command/real/tpl/atmAlert/package-use.html b/docs/page/javadoc/command/real/tpl/atmAlert/package-use.html deleted file mode 100644 index bda940e..0000000 --- a/docs/page/javadoc/command/real/tpl/atmAlert/package-use.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Package command.real.tpl.atmAlert (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    command.real.tpl.atmAlert

    -
    -
    No usage of command.real.tpl.atmAlert
    - - - - - - diff --git a/docs/page/javadoc/constant-values.html b/docs/page/javadoc/constant-values.html deleted file mode 100644 index 90d9fbe..0000000 --- a/docs/page/javadoc/constant-values.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - -Constant Field Values (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    -

    Constant Field Values

    -

    Contents

    - -
    -
    - - -

    command.real.*

    -
      -
    • - - - - - - - - - - - - - - -
      command.real.sound.MusicManager 
      Modifier and TypeConstant FieldValue
      - -private static final intDEFAULT_VOLUME25
      -
    • -
    - - - -

    interfaces.*

    -
      -
    • - - - - - - - - - - - - - - - - - - - -
      interfaces.SQLiteInterfaces 
      Modifier and TypeConstant FieldValue
      - -private static final java.lang.StringRSS_LINK"RSSLink"
      - -private static final java.lang.StringSERVERS_DISCORD"ServersDiscord"
      -
    • -
    -
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/deprecated-list.html b/docs/page/javadoc/deprecated-list.html deleted file mode 100644 index 344ec3a..0000000 --- a/docs/page/javadoc/deprecated-list.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - -Deprecated List (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    -

    Deprecated API

    -

    Contents

    - -
    - - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/help-doc.html b/docs/page/javadoc/help-doc.html deleted file mode 100644 index 6be4fb4..0000000 --- a/docs/page/javadoc/help-doc.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - -API Help (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    -

    How This API Document Is Organized

    -
    This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
    -
    -
    -
      -
    • -

      Overview

      -

      The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.

      -
    • -
    • -

      Package

      -

      Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

      -
        -
      • Interfaces (italic)
      • -
      • Classes
      • -
      • Enums
      • -
      • Exceptions
      • -
      • Errors
      • -
      • Annotation Types
      • -
      -
    • -
    • -

      Class/Interface

      -

      Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

      -
        -
      • Class inheritance diagram
      • -
      • Direct Subclasses
      • -
      • All Known Subinterfaces
      • -
      • All Known Implementing Classes
      • -
      • Class/interface declaration
      • -
      • Class/interface description
      • -
      -
        -
      • Nested Class Summary
      • -
      • Field Summary
      • -
      • Constructor Summary
      • -
      • Method Summary
      • -
      -
        -
      • Field Detail
      • -
      • Constructor Detail
      • -
      • Method Detail
      • -
      -

      Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

      -
    • -
    • -

      Annotation Type

      -

      Each annotation type has its own separate page with the following sections:

      -
        -
      • Annotation Type declaration
      • -
      • Annotation Type description
      • -
      • Required Element Summary
      • -
      • Optional Element Summary
      • -
      • Element Detail
      • -
      -
    • -
    • -

      Enum

      -

      Each enum has its own separate page with the following sections:

      -
        -
      • Enum declaration
      • -
      • Enum description
      • -
      • Enum Constant Summary
      • -
      • Enum Constant Detail
      • -
      -
    • -
    • -

      Use

      -

      Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

      -
    • -
    • -

      Tree (Class Hierarchy)

      -

      There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

      -
        -
      • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
      • -
      • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
      • -
      -
    • -
    • -

      Deprecated API

      -

      The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

      -
    • -
    • -

      Index

      -

      The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

      -
    • -
    • -

      Prev/Next

      -

      These links take you to the next or previous class, interface, package, or related page.

      -
    • -
    • -

      Frames/No Frames

      -

      These links show and hide the HTML frames. All pages are available with or without frames.

      -
    • -
    • -

      All Classes

      -

      The All Classes link shows all classes and interfaces except non-static nested types.

      -
    • -
    • -

      Serialized Form

      -

      Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

      -
    • -
    • -

      Constant Field Values

      -

      The Constant Field Values page lists the static final fields and their values.

      -
    • -
    -This help file applies to API documentation generated using the standard doclet.
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-1.html b/docs/page/javadoc/index-files/index-1.html deleted file mode 100644 index faaa7f6..0000000 --- a/docs/page/javadoc/index-files/index-1.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - -A-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    A

    -
    -
    atmAlertIDChannel - Variable in class beans.ServersDiscord
    -
    -
    ID Canale per invio degli alert dell'ATM
    -
    -
    ATMAlertReceiver - Class in command.real.tpl.atmAlert
    -
     
    -
    ATMAlertReceiver() - Constructor for class command.real.tpl.atmAlert.ATMAlertReceiver
    -
     
    -
    ATMAlertStartCommand - Class in command.real.tpl.atmAlert
    -
    -
    Deprecated.
    -
    -
    ATMAlertStartCommand() - Constructor for class command.real.tpl.atmAlert.ATMAlertStartCommand
    -
    -
    Deprecated.
    -
    ATMAlertStopCommand - Class in command.real.tpl.atmAlert
    -
    -
    Deprecated.
    -
    -
    ATMAlertStopCommand() - Constructor for class command.real.tpl.atmAlert.ATMAlertStopCommand
    -
    -
    Deprecated.
    -
    ATMRSSReader - Class in command.real.tpl.atmAlert
    -
     
    -
    ATMRSSReader() - Constructor for class command.real.tpl.atmAlert.ATMRSSReader
    -
     
    -
    AtmScheduler - Class in command.real.tpl.atmAlert
    -
     
    -
    AtmScheduler() - Constructor for class command.real.tpl.atmAlert.AtmScheduler
    -
     
    -
    audioPlayer - Variable in class command.real.sound.AudioPlayerSendHandler
    -
     
    -
    AudioPlayerSendHandler - Class in command.real.sound
    -
    -
    This is a wrapper around AudioPlayer which makes it behave as an AudioSendHandler for JDA.
    -
    -
    AudioPlayerSendHandler(AudioPlayer) - Constructor for class command.real.sound.AudioPlayerSendHandler
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-10.html b/docs/page/javadoc/index-files/index-10.html deleted file mode 100644 index 129f217..0000000 --- a/docs/page/javadoc/index-files/index-10.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - -L-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    L

    -
    -
    lastAtmAlert - Variable in class beans.Rsslink
    -
    -
    Link ultimo feed di atm
    -
    -
    lastFrame - Variable in class command.real.sound.AudioPlayerSendHandler
    -
     
    -
    lastNewsBDO - Variable in class beans.Rsslink
    -
    -
    Lista link ultime news di BDO
    -
    -
    lastPatchBDO - Variable in class beans.Rsslink
    -
     
    -
    lastTrack - Variable in class command.real.sound.TrackScheduler
    -
     
    -
    leave(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per far uscire il bot dalla lobby, bloccherà la queue - e la svuoterà
    -
    -
    link - Variable in class beans.RSSMessage
    -
     
    -
    loadAndPlay(GuildMusicManager, MessageChannel, String, boolean) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per caricare una traccia o una playlist nella coda
    -
    -
    logDebug(String) - Static method in class interfaces.TakaoLog
    -
     
    -
    logError(String) - Static method in class interfaces.TakaoLog
    -
     
    -
    logger - Static variable in class interfaces.TakaoLog
    -
     
    -
    logInfo(String) - Static method in class interfaces.TakaoLog
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-11.html b/docs/page/javadoc/index-files/index-11.html deleted file mode 100644 index d6dd683..0000000 --- a/docs/page/javadoc/index-files/index-11.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - -M-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    M

    -
    -
    main(String[]) - Static method in class starter.Start
    -
     
    -
    manager - Static variable in class command.real.tpl.atmAlert.AtmScheduler
    -
     
    -
    MusicManager - Class in command.real.sound
    -
    -
    Classe per gestire il musicBot
    -
    -
    MusicManager() - Constructor for class command.real.sound.MusicManager
    -
     
    -
    musicManager - Variable in class command.real.sound.PlayerControlCommand
    -
     
    -
    musicManagers - Variable in class command.real.sound.MusicManager
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-12.html b/docs/page/javadoc/index-files/index-12.html deleted file mode 100644 index 980af5e..0000000 --- a/docs/page/javadoc/index-files/index-12.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - - -N-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    N

    -
    -
    nameServer - Variable in class beans.ServersDiscord
    -
    -
    Nome del server
    -
    -
    newServer(String, String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo che aggiunge nome e l'id del server che ha aggiunto il bot sul database.
    -
    -
    newServer(String, String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo che aggiunge nome e l'id del server che ha aggiunto il bot sul database.
    -
    -
    nextTrack() - Method in class command.real.sound.TrackScheduler
    -
    -
    Start the next track, stopping the current one if it is playing.
    -
    -
    nomeBoss - Variable in class beans.BDOBossBean.Boss
    -
    -
    Lista boss dell'ora
    -
    -
    nowPlay(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per ottenere la traccia attualmente in riproduzione
    -
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-13.html b/docs/page/javadoc/index-files/index-13.html deleted file mode 100644 index 7655d9a..0000000 --- a/docs/page/javadoc/index-files/index-13.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - -O-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    O

    -
    -
    onGuildJoin(GuildJoinEvent) - Method in class command.real.JoinListener
    -
     
    -
    onGuildLeave(GuildLeaveEvent) - Method in class command.real.JoinListener
    -
     
    -
    onGuildUpdateName(GuildUpdateNameEvent) - Method in class command.real.JoinListener
    -
     
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.BDO.BDOReceiver
    -
     
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.BDO.boss.BDOBossStartCommand
    -
    -
    Deprecated.
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.BDO.boss.BDOBossStopCommand
    -
    -
    Deprecated.
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.BDO.RSS.BDONewsStartCommand
    -
    -
    Deprecated.
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.BDO.RSS.BDONewsStopCommand
    -
    -
    Deprecated.
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.BDO.RSS.BDOPatchStartCommand
    -
    -
    Deprecated.
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.BDO.RSS.BDOPatchStopCommand
    -
    -
    Deprecated.
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.configuration.ConfigurationCommand
    -
    -
    Deprecated.
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.configuration.ConfigurationReceiver
    -
     
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.configuration.HelpCommand
    -
    -
    Deprecated.
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.configuration.InfoCommand
    -
    -
    Deprecated.
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.sound.PlayerControlCommand
    -
     
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.tpl.atmAlert.ATMAlertReceiver
    -
     
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.tpl.atmAlert.ATMAlertStartCommand
    -
    -
    Deprecated.
    -
    onMessageReceived(MessageReceivedEvent) - Method in class command.real.tpl.atmAlert.ATMAlertStopCommand
    -
    -
    Deprecated.
    -
    onTrackEnd(AudioPlayer, AudioTrack, AudioTrackEndReason) - Method in class command.real.sound.TrackScheduler
    -
     
    -
    ora - Variable in class beans.BDOBossBean.Boss
    -
    -
    Ora di spawn
    -
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-14.html b/docs/page/javadoc/index-files/index-14.html deleted file mode 100644 index 80624a2..0000000 --- a/docs/page/javadoc/index-files/index-14.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - - -P-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    P

    -
    -
    pauseResume(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per mettere in pausa o riprendere la traccia attualmente - in riproduzione
    -
    -
    play(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per riprodurre l'url audio passato come parametro
    -
    -
    player - Variable in class command.real.sound.GuildMusicManager
    -
    -
    Audio player for the guild.
    -
    -
    player - Variable in class command.real.sound.TrackScheduler
    -
     
    -
    PlayerControlCommand - Class in command.real.sound
    -
     
    -
    PlayerControlCommand() - Constructor for class command.real.sound.PlayerControlCommand
    -
     
    -
    playerManager - Variable in class command.real.sound.MusicManager
    -
     
    -
    playPlaylist(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per riprodurre una playlist dall'url passato come parametro
    -
    -
    PostgreSQLInterface - Class in interfaces
    -
     
    -
    PostgreSQLInterface() - Constructor for class interfaces.PostgreSQLInterface
    -
     
    -
    prepareRSStoEmbeddedMessage(RSSMessage) - Static method in class command.real.BDO.RSS.BDORSSReader
    -
    -
    Metodo per preparare il messaggio per discord in modalità da embedded
    -
    -
    prepareRSStoEmbeddedMessage(RSSMessage) - Static method in class command.real.tpl.atmAlert.ATMRSSReader
    -
     
    -
    procedurePublish(RSSMessage, ArrayList<String>, JDA) - Static method in class command.real.BDO.RSS.BDORSScheduler
    -
     
    -
    processHour(int, int, Giorno) - Static method in class command.real.BDO.boss.BossRetriver
    -
    -
    Processa l'ora per ottenere il boss
    -
    -
    processMinute0015(int, int, Giorno) - Static method in class command.real.BDO.boss.BossRetriver
    -
    -
    Metodo per ottenere il boss che spawna alle 15
    -
    -
    processMinute4500(int, int, Giorno) - Static method in class command.real.BDO.boss.BossRetriver
    -
    -
    Metodo per ottenere il boss che spawna alle 00
    -
    -
    PropertyInterfaces - Class in interfaces
    -
     
    -
    PropertyInterfaces() - Constructor for class interfaces.PropertyInterfaces
    -
     
    -
    provide20MsAudio() - Method in class command.real.sound.AudioPlayerSendHandler
    -
     
    -
    publish(String[], String) - Static method in class command.real.BDO.boss.BossRetriver
    -
    -
    Metoto per eseguire la pubblicazione dei messaggi
    -
    -
    publish(RSSMessage) - Static method in class command.real.tpl.atmAlert.AtmScheduler
    -
     
    -
    publishMessage(MessageEmbed, ArrayList<ServerToChannel>, JDA) - Static method in class command.real.BDO.RSS.BDORSScheduler
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-15.html b/docs/page/javadoc/index-files/index-15.html deleted file mode 100644 index 1af53b6..0000000 --- a/docs/page/javadoc/index-files/index-15.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - -Q-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    Q

    -
    -
    queue - Variable in class command.real.sound.TrackScheduler
    -
     
    -
    queue(AudioTrack) - Method in class command.real.sound.TrackScheduler
    -
    -
    Add the next track to queue or play right away if nothing is in the queue.
    -
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-16.html b/docs/page/javadoc/index-files/index-16.html deleted file mode 100644 index 1b333f1..0000000 --- a/docs/page/javadoc/index-files/index-16.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - -R-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    R

    -
    -
    readRSS(String) - Static method in class command.real.BDO.RSS.BDORSSReader
    -
    -
    Metodo per leggere un feed RSS
    -
    -
    readRSS(String) - Static method in class command.real.tpl.atmAlert.ATMRSSReader
    -
     
    -
    removeATMAlertChannel(String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per rimuovere il canale per gli alert di ATM
    -
    -
    removeATMAlertChannel(String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per rimuovere il canale per gli alert di ATM
    -
    -
    removeBDOBossChannel(String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per rimuovere il canale per i boss alert di BDO
    -
    -
    removeBDOBossChannel(String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per rimuovere il canale per i boss alert di BDO
    -
    -
    removeBDONewsChannel(String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per rimuovere il canale per le news su BDO
    -
    -
    removeBDONewsChannel(String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per rimuovere il canale per le news su BDO
    -
    -
    removeBDOPatchChannel(String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per rimuovere il canale per le patch di BDO
    -
    -
    removeBDOPatchChannel(String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per rimuovere il canale per le patch di BDO
    -
    -
    repeat(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per ripetere la traccia attualmente in riproduzione
    -
    -
    repeating - Variable in class command.real.sound.TrackScheduler
    -
     
    -
    reset(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per resettare il bot in caso di problemi.
    -
    -
    restart(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per riavviare la traccia attualmente in riproduzione
    -
    -
    RSS_DB_COLUMN() - Constructor for enum interfaces.SQLiteInterfaces.RSS_DB_COLUMN
    -
    -
    Deprecated.
    -
    RSS_LINK - Static variable in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Rsslink - Class in beans
    -
    -
    Tabella RSSLink
    -
    -
    Rsslink() - Constructor for class beans.Rsslink
    -
     
    -
    RSSMessage - Class in beans
    -
    -
    Classe contenitore per il titolo, il link e il body HTML - del feed RSS
    -
    -
    RSSMessage(String, String, Document) - Constructor for class beans.RSSMessage
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-17.html b/docs/page/javadoc/index-files/index-17.html deleted file mode 100644 index e99af8e..0000000 --- a/docs/page/javadoc/index-files/index-17.html +++ /dev/null @@ -1,339 +0,0 @@ - - - - - -S-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    S

    -
    -
    scheduler - Variable in class command.real.sound.GuildMusicManager
    -
    -
    Track scheduler for the player.
    -
    -
    SD_DB_COLUMN() - Constructor for enum interfaces.SQLiteInterfaces.SD_DB_COLUMN
    -
    -
    Deprecated.
    -
    sendHandler - Variable in class command.real.sound.GuildMusicManager
    -
    -
    Wrapper around AudioPlayer to use it as an AudioSendHandler.
    -
    -
    serverId - Variable in class beans.ServersDiscord
    -
    -
    Id del server
    -
    -
    serverID - Variable in class beans.ServerToChannel
    -
     
    -
    SERVERS_DISCORD - Static variable in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    ServersDiscord - Class in beans
    -
    -
    Tabella contenente tutti gli id dei canali per le funzionalità del bot
    -
    -
    ServersDiscord() - Constructor for class beans.ServersDiscord
    -
     
    -
    ServersDiscord(String, String) - Constructor for class beans.ServersDiscord
    -
     
    -
    ServerToChannel - Class in beans
    -
    -
    Classe di appoggio per ottenere serverID e channelID - per i publish del feed RSS
    -
    -
    ServerToChannel(String, String) - Constructor for class beans.ServerToChannel
    -
     
    -
    sessionFactory - Static variable in class interfaces.PostgreSQLInterface
    -
     
    -
    setATMAlertChannel(String, String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per settare il canale per gli alert dell'ATM
    -
    -
    setATMAlertChannel(String, String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per settare il canale per gli alert dell'ATM
    -
    -
    setAtmAlertIDChannel(String) - Method in class beans.ServersDiscord
    -
     
    -
    setBDOBossChannel(String, String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per settare il canale per i boss alert di BDO
    -
    -
    setBDOBossChannel(String, String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per settare il canale per i boss alert di BDO
    -
    -
    setBdoBossIDChannel(String) - Method in class beans.ServersDiscord
    -
     
    -
    setBDONewsChannel(String, String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per settare il canale per le news su BDO
    -
    -
    setBDONewsChannel(String, String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per settare il canale per le news su BDO
    -
    -
    setBdoNewsIDChannel(String) - Method in class beans.ServersDiscord
    -
     
    -
    setBDOPatchChannel(String, String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per settare il canale per le patch di BDO
    -
    -
    setBDOPatchChannel(String, String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per settare il canale per le patch di BDO
    -
    -
    setBdoPatchIDChannel(String) - Method in class beans.ServersDiscord
    -
     
    -
    setBosses(ArrayList<Boss>) - Method in class beans.BDOBossBean.Giorno
    -
     
    -
    setChannelID(String) - Method in class beans.ServerToChannel
    -
    -
    Metodo per impostare il channelID
    -
    -
    setDoc(Document) - Method in class beans.RSSMessage
    -
    -
    Metodo per impostare il body del feed RSS
    -
    -
    setGiorno(String) - Method in class beans.BDOBossBean.Giorno
    -
     
    -
    setId(long) - Method in class beans.Rsslink
    -
     
    -
    setLastAtmAlert(String) - Method in class beans.Rsslink
    -
     
    -
    setLastATMAlert(String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
    -
    -
    setLastATMAlert(String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
    -
    -
    setLastNewsBDO(String) - Method in class beans.Rsslink
    -
     
    -
    setLastPatchBDO(String) - Method in class beans.Rsslink
    -
     
    -
    setLastPatchBDO(String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
    -
    -
    setLastPatchBDO(String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
    -
    -
    setLink(String) - Method in class beans.RSSMessage
    -
    -
    Metodo per impostare il link del feed
    -
    -
    setNameServer(String) - Method in class beans.ServersDiscord
    -
     
    -
    setNewsBDO(ArrayList<String>) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Imposta la lista delle ultime notizie di bdo
    -
    -
    setNewsBDO(ArrayList<String>) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Imposta la lista delle ultime notizie di bdo
    -
    -
    setNomeBoss(String[]) - Method in class beans.BDOBossBean.Boss
    -
     
    -
    setOra(String) - Method in class beans.BDOBossBean.Boss
    -
     
    -
    setRepeating(boolean) - Method in class command.real.sound.TrackScheduler
    -
     
    -
    setServerId(String) - Method in class beans.ServersDiscord
    -
     
    -
    setServerID(String) - Method in class beans.ServerToChannel
    -
    -
    Metodo per impostare il serverID
    -
    -
    setSimbol(String, String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per configurare il simbolo di comando per il server
    -
    -
    setSimbol(String, String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per configurare il simbolo di comando per il server
    -
    -
    setSimbolCommand(String) - Method in class beans.ServersDiscord
    -
     
    -
    setTitle(String) - Method in class beans.RSSMessage
    -
    -
    Metodo per ottenre il titolo del feed
    -
    -
    setTwitterStreamFilter(FilterQuery) - Method in class interfaces.TwitterManager
    -
     
    -
    setTwitterStreamListener(StatusListener) - Method in class interfaces.TwitterManager
    -
     
    -
    shuffle() - Method in class command.real.sound.TrackScheduler
    -
     
    -
    shuffleQueue(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per randomizzare la coda
    -
    -
    simbolCommand - Variable in class beans.ServersDiscord
    -
    -
    Simbolo di comando
    -
    -
    skip(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per saltare la traccia attualmente in riproduzione
    -
    -
    SQLiteInterfaces - Class in interfaces
    -
    -
    Deprecated.
    -
    -
    SQLiteInterfaces() - Constructor for class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    SQLiteInterfaces.RSS_DB_COLUMN - Enum in interfaces
    -
    -
    Deprecated.
    -
    SQLiteInterfaces.SD_DB_COLUMN - Enum in interfaces
    -
    -
    Deprecated.
    -
    Nomi delle colonne sul db
    -
    -
    Start - Class in starter
    -
     
    -
    Start() - Constructor for class starter.Start
    -
     
    -
    startAtmTweetScheduler() - Static method in class command.real.tpl.atmAlert.AtmScheduler
    -
     
    -
    starter - package starter
    -
     
    -
    startScheduling(JDA) - Static method in class interfaces.DiscordScheduler
    -
     
    -
    stop(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per stoppare la riproduzione e pulire la coda
    -
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-18.html b/docs/page/javadoc/index-files/index-18.html deleted file mode 100644 index 965c2ba..0000000 --- a/docs/page/javadoc/index-files/index-18.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - -T-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    T

    -
    -
    TakaoLog - Class in interfaces
    -
     
    -
    TakaoLog() - Constructor for class interfaces.TakaoLog
    -
     
    -
    taskFeedRSSATM() - Static method in class command.real.tpl.atmAlert.AtmScheduler
    -
     
    -
    taskFeedRSSBDO(JDA) - Static method in class command.real.BDO.RSS.BDORSScheduler
    -
     
    -
    title - Variable in class beans.RSSMessage
    -
     
    -
    TrackScheduler - Class in command.real.sound
    -
    -
    This class schedules tracks for the audio player.
    -
    -
    TrackScheduler(AudioPlayer) - Constructor for class command.real.sound.TrackScheduler
    -
     
    -
    TwitterManager - Class in interfaces
    -
     
    -
    TwitterManager() - Constructor for class interfaces.TwitterManager
    -
     
    -
    twitterStream - Variable in class interfaces.TwitterManager
    -
     
    -
    twitterStreamFactory - Variable in class interfaces.TwitterManager
    -
     
    -
    twitterUrl - Static variable in class command.real.tpl.atmAlert.AtmScheduler
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-19.html b/docs/page/javadoc/index-files/index-19.html deleted file mode 100644 index 734ba56..0000000 --- a/docs/page/javadoc/index-files/index-19.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - - -U-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    U

    -
    -
    updateNameServer(String, String) - Static method in class interfaces.PostgreSQLInterface
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-2.html b/docs/page/javadoc/index-files/index-2.html deleted file mode 100644 index 74a5a80..0000000 --- a/docs/page/javadoc/index-files/index-2.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - -B-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    B

    -
    -
    bdoBossIDChannel - Variable in class beans.ServersDiscord
    -
    -
    ID Canale per invio alert boss di BDO
    -
    -
    BDOBossStartCommand - Class in command.real.BDO.boss
    -
    -
    Deprecated.
    -
    -
    BDOBossStartCommand() - Constructor for class command.real.BDO.boss.BDOBossStartCommand
    -
    -
    Deprecated.
    -
    BDOBossStopCommand - Class in command.real.BDO.boss
    -
    -
    Deprecated.
    -
    -
    BDOBossStopCommand() - Constructor for class command.real.BDO.boss.BDOBossStopCommand
    -
    -
    Deprecated.
    -
    bdoNewsIDChannel - Variable in class beans.ServersDiscord
    -
    -
    ID Canale per invio news di BDO
    -
    -
    BDONewsStartCommand - Class in command.real.BDO.RSS
    -
    -
    Deprecated.
    -
    -
    BDONewsStartCommand() - Constructor for class command.real.BDO.RSS.BDONewsStartCommand
    -
    -
    Deprecated.
    -
    BDONewsStopCommand - Class in command.real.BDO.RSS
    -
    -
    Deprecated.
    -
    -
    BDONewsStopCommand() - Constructor for class command.real.BDO.RSS.BDONewsStopCommand
    -
    -
    Deprecated.
    -
    bdoPatchIDChannel - Variable in class beans.ServersDiscord
    -
    -
    ID Canale per invio patch di BDO
    -
    -
    BDOPatchStartCommand - Class in command.real.BDO.RSS
    -
    -
    Deprecated.
    -
    -
    BDOPatchStartCommand() - Constructor for class command.real.BDO.RSS.BDOPatchStartCommand
    -
    -
    Deprecated.
    -
    BDOPatchStopCommand - Class in command.real.BDO.RSS
    -
    -
    Deprecated.
    -
    -
    BDOPatchStopCommand() - Constructor for class command.real.BDO.RSS.BDOPatchStopCommand
    -
    -
    Deprecated.
    -
    BDOReceiver - Class in command.real.BDO
    -
     
    -
    BDOReceiver() - Constructor for class command.real.BDO.BDOReceiver
    -
     
    -
    BDORSScheduler - Class in command.real.BDO.RSS
    -
     
    -
    BDORSScheduler() - Constructor for class command.real.BDO.RSS.BDORSScheduler
    -
     
    -
    BDORSSReader - Class in command.real.BDO.RSS
    -
     
    -
    BDORSSReader() - Constructor for class command.real.BDO.RSS.BDORSSReader
    -
     
    -
    beans - package beans
    -
     
    -
    beans.BDOBossBean - package beans.BDOBossBean
    -
     
    -
    Boss - Class in beans.BDOBossBean
    -
    -
    Rappresentazione dei boss
    -
    -
    Boss(String[], String) - Constructor for class beans.BDOBossBean.Boss
    -
     
    -
    bosses - Variable in class beans.BDOBossBean.Giorno
    -
     
    -
    BossJob - Class in command.real.BDO.boss
    -
    -
    Job per l'ottenimento dei boss
    -
    -
    BossJob() - Constructor for class command.real.BDO.boss.BossJob
    -
     
    -
    BossRetriver - Class in command.real.BDO.boss
    -
    -
    Classe per leggere il json dei boss
    -
    -
    BossRetriver() - Constructor for class command.real.BDO.boss.BossRetriver
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-20.html b/docs/page/javadoc/index-files/index-20.html deleted file mode 100644 index 87a1a88..0000000 --- a/docs/page/javadoc/index-files/index-20.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - -V-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    V

    -
    -
    valueOf(String) - Static method in enum interfaces.SQLiteInterfaces.RSS_DB_COLUMN
    -
    -
    Deprecated.
    -
    Returns the enum constant of this type with the specified name.
    -
    -
    valueOf(String) - Static method in enum interfaces.SQLiteInterfaces.SD_DB_COLUMN
    -
    -
    Deprecated.
    -
    Returns the enum constant of this type with the specified name.
    -
    -
    values() - Static method in enum interfaces.SQLiteInterfaces.RSS_DB_COLUMN
    -
    -
    Deprecated.
    -
    Returns an array containing the constants of this enum type, in -the order they are declared.
    -
    -
    values() - Static method in enum interfaces.SQLiteInterfaces.SD_DB_COLUMN
    -
    -
    Deprecated.
    -
    Returns an array containing the constants of this enum type, in -the order they are declared.
    -
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-3.html b/docs/page/javadoc/index-files/index-3.html deleted file mode 100644 index 8cc008d..0000000 --- a/docs/page/javadoc/index-files/index-3.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - -C-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    C

    -
    -
    canProvide() - Method in class command.real.sound.AudioPlayerSendHandler
    -
     
    -
    changeVolume(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per cambiare il volume, attualmente non in uso.
    -
    -
    channelID - Variable in class beans.ServerToChannel
    -
     
    -
    checkCommand(MessageReceivedEvent, String, String) - Static method in class command.pattern.ControlCommand
    -
    -
    Controllo del comando lanciato dalla chat se sia corretto con quelli attivi sul bot.
    -
    -
    clearQueue(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
     
    -
    command.pattern - package command.pattern
    -
     
    -
    command.real - package command.real
    -
     
    -
    command.real.BDO - package command.real.BDO
    -
     
    -
    command.real.BDO.boss - package command.real.BDO.boss
    -
     
    -
    command.real.BDO.RSS - package command.real.BDO.RSS
    -
     
    -
    command.real.configuration - package command.real.configuration
    -
     
    -
    command.real.sound - package command.real.sound
    -
     
    -
    command.real.tpl.atmAlert - package command.real.tpl.atmAlert
    -
     
    -
    configuration(MessageReceivedEvent) - Method in class command.real.configuration.ConfigurationCommand
    -
    -
    Deprecated.
    -
    configuration(MessageReceivedEvent) - Method in class command.real.configuration.ConfigurationReceiver
    -
     
    -
    ConfigurationCommand - Class in command.real.configuration
    -
    -
    Deprecated.
    -
    -
    ConfigurationCommand() - Constructor for class command.real.configuration.ConfigurationCommand
    -
    -
    Deprecated.
    -
    ConfigurationReceiver - Class in command.real.configuration
    -
     
    -
    ConfigurationReceiver() - Constructor for class command.real.configuration.ConfigurationReceiver
    -
     
    -
    connection - Static variable in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    ControlCommand - Class in command.pattern
    -
    -
    Classe per gestire i controlli tra i simbolo di comanndo e il comando stesso
    -
    -
    ControlCommand() - Constructor for class command.pattern.ControlCommand
    -
     
    -
    controlCommand(MessageReceivedEvent, String) - Static method in class command.pattern.ControlCommand
    -
    -
    Deprecated.
    -
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-4.html b/docs/page/javadoc/index-files/index-4.html deleted file mode 100644 index b2a8ba7..0000000 --- a/docs/page/javadoc/index-files/index-4.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - - -D-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    D

    -
    -
    DEFAULT_VOLUME - Static variable in class command.real.sound.MusicManager
    -
     
    -
    deleteServer(String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo che rimuove la riga del server che ha espulso il bot
    -
    -
    deleteServer(String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo che rimuove la riga del server che ha espulso il bot
    -
    -
    DiscordScheduler - Class in interfaces
    -
     
    -
    DiscordScheduler() - Constructor for class interfaces.DiscordScheduler
    -
     
    -
    DiscordTokenInterfaces - Class in interfaces
    -
    -
    Classe per caricare il token di discord da file
    -
    -
    DiscordTokenInterfaces() - Constructor for class interfaces.DiscordTokenInterfaces
    -
     
    -
    doc - Variable in class beans.RSSMessage
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-5.html b/docs/page/javadoc/index-files/index-5.html deleted file mode 100644 index 7d70569..0000000 --- a/docs/page/javadoc/index-files/index-5.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - -E-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    E

    -
    -
    equals(Object) - Method in class beans.ServerToChannel
    -
     
    -
    execute(JobExecutionContext) - Method in class command.real.BDO.boss.BossJob
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-6.html b/docs/page/javadoc/index-files/index-6.html deleted file mode 100644 index b65374e..0000000 --- a/docs/page/javadoc/index-files/index-6.html +++ /dev/null @@ -1,436 +0,0 @@ - - - - - -G-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    G

    -
    -
    getATMAlertChannel() - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per ottenere tutti i canali registrati agli alert di ATM
    -
    -
    getATMAlertChannel() - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per ottenere tutti i canali registrati agli alert di ATM
    -
    -
    getAtmAlertIDChannel() - Method in class beans.ServersDiscord
    -
     
    -
    getATMStartCommand() - Static method in class command.real.tpl.atmAlert.ATMAlertReceiver
    -
     
    -
    getATMStartCommandDescription() - Static method in class command.real.tpl.atmAlert.ATMAlertReceiver
    -
     
    -
    getATMStopCommand() - Static method in class command.real.tpl.atmAlert.ATMAlertReceiver
    -
     
    -
    getATMStopCommandDescription() - Static method in class command.real.tpl.atmAlert.ATMAlertReceiver
    -
     
    -
    getBDOBossChannel() - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per ottenere tutti i canali registrati agli alert dei boss di BDO
    -
    -
    getBDOBossChannel() - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    getBdoBossIDChannel() - Method in class beans.ServersDiscord
    -
     
    -
    getBDOBossStartCommand() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDOBossStartCommandDescription() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDOBossStopCommand() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDOBossStopCommandDescription() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDONewsChannel() - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per ottenere tutti i canali registrati alle news di BDO
    -
    -
    getBDONewsChannel() - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per ottenere tutti i canali registrati alle news di BDO
    -
    -
    getBdoNewsIDChannel() - Method in class beans.ServersDiscord
    -
     
    -
    getBDONewsStartCommand() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDONewsStartCommandDecription() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDONewsStopCommand() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDONewsStopCommandDecription() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDOPatchChannel() - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per ottenere tutti i canali registrati alle patch di BDO
    -
    -
    getBDOPatchChannel() - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per ottenere tutti i canali registrati alle patch di BDO
    -
    -
    getBdoPatchIDChannel() - Method in class beans.ServersDiscord
    -
     
    -
    getBDOPatchStartCommand() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDOPatchStartCommandDecription() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDOPatchStopCommand() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBDOPatchStopCommandDecription() - Static method in class command.real.BDO.BDOReceiver
    -
     
    -
    getBosses() - Method in class beans.BDOBossBean.Giorno
    -
     
    -
    getBossList() - Static method in class command.real.BDO.boss.BossRetriver
    -
    -
    Ottieni la lista dei boss da file
    -
    -
    getChannelID() - Method in class beans.ServerToChannel
    -
    -
    Metodo per ottenere il channelID
    -
    -
    getCommand() - Static method in class command.real.BDO.boss.BDOBossStartCommand
    -
    -
    Deprecated.
    -
    getCommand() - Static method in class command.real.BDO.boss.BDOBossStopCommand
    -
    -
    Deprecated.
    -
    getCommand() - Static method in class command.real.BDO.RSS.BDONewsStartCommand
    -
    -
    Deprecated.
    -
    getCommand() - Static method in class command.real.BDO.RSS.BDONewsStopCommand
    -
    -
    Deprecated.
    -
    getCommand() - Static method in class command.real.BDO.RSS.BDOPatchStartCommand
    -
    -
    Deprecated.
    -
    getCommand() - Static method in class command.real.BDO.RSS.BDOPatchStopCommand
    -
    -
    Deprecated.
    -
    getCommand() - Static method in class command.real.configuration.ConfigurationCommand
    -
    -
    Deprecated.
    -
    getCommand() - Method in class command.real.configuration.HelpCommand
    -
    -
    Deprecated.
    -
    getCommand() - Static method in class command.real.configuration.InfoCommand
    -
    -
    Deprecated.
    -
    getCommand() - Static method in class command.real.tpl.atmAlert.ATMAlertStartCommand
    -
    -
    Deprecated.
    -
    getCommand() - Static method in class command.real.tpl.atmAlert.ATMAlertStopCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Static method in class command.real.BDO.boss.BDOBossStartCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Static method in class command.real.BDO.boss.BDOBossStopCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Static method in class command.real.BDO.RSS.BDONewsStartCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Static method in class command.real.BDO.RSS.BDONewsStopCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Static method in class command.real.BDO.RSS.BDOPatchStartCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Static method in class command.real.BDO.RSS.BDOPatchStopCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Static method in class command.real.configuration.ConfigurationCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Method in class command.real.configuration.HelpCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Static method in class command.real.configuration.InfoCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Static method in class command.real.tpl.atmAlert.ATMAlertStartCommand
    -
    -
    Deprecated.
    -
    getCommandDescription() - Static method in class command.real.tpl.atmAlert.ATMAlertStopCommand
    -
    -
    Deprecated.
    -
    getConfigurationCommandCommand() - Static method in class command.real.configuration.ConfigurationReceiver
    -
     
    -
    getConfigurationCommandCommandDescription() - Static method in class command.real.configuration.ConfigurationReceiver
    -
     
    -
    getDayBosses(String, ArrayList<Giorno>) - Static method in class beans.BDOBossBean.Giorno
    -
     
    -
    getDoc() - Method in class beans.RSSMessage
    -
    -
    Metodo per ottenere il body del feed RSS
    -
    -
    getGiorno() - Method in class beans.BDOBossBean.Giorno
    -
     
    -
    getHelpCommand() - Method in class command.real.configuration.ConfigurationReceiver
    -
     
    -
    getHourBoss(int, int, ArrayList<Boss>) - Static method in class beans.BDOBossBean.Boss
    -
    -
    Metodo per ottenere i boss dell'ora
    -
    -
    getId() - Method in class beans.Rsslink
    -
     
    -
    getInfoCommand() - Static method in class command.real.configuration.ConfigurationReceiver
    -
     
    -
    getInfoCommandDescription() - Static method in class command.real.configuration.ConfigurationReceiver
    -
     
    -
    getLastAtmAlert() - Method in class beans.Rsslink
    -
     
    -
    getLastATMAlert() - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Ottiene il link dell'ultimo alert di atm
    -
    -
    getLastATMAlert() - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Ottiene il link dell'ultima patch di BDO
    -
    -
    getLastNewsBDO() - Method in class beans.Rsslink
    -
     
    -
    getLastPatchBDO() - Method in class beans.Rsslink
    -
     
    -
    getLastPatchBDO() - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Ottiene il link dell'ultima patch di BDO
    -
    -
    getLastPatchBDO() - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Ottiene il link dell'ultima patch di BDO
    -
    -
    getLink() - Method in class beans.RSSMessage
    -
    -
    Metodo per ottenere il link del feed
    -
    -
    getListNewsBDO() - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Ottiene la lista delle ultime notizie di BDO
    -
    -
    getListNewsBDO() - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Ottiene la lista delle ultime notizie di BDO
    -
    -
    getListQueue(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per ottenere la lista della coda
    -
    -
    getMessage(long, String, String, String) - Static method in class command.real.tpl.atmAlert.AtmScheduler
    -
     
    -
    getMusicManager(String) - Method in class command.real.sound.MusicManager
    -
     
    -
    getNameServer() - Method in class beans.ServersDiscord
    -
     
    -
    getNomeBoss() - Method in class beans.BDOBossBean.Boss
    -
    -
    Ottieni i nomi dei boss
    -
    -
    getOra() - Method in class beans.BDOBossBean.Boss
    -
     
    -
    getProp() - Static method in class interfaces.PropertyInterfaces
    -
     
    -
    getQueue() - Method in class command.real.sound.TrackScheduler
    -
     
    -
    getServerId() - Method in class beans.ServersDiscord
    -
     
    -
    getServerID() - Method in class beans.ServerToChannel
    -
    -
    Metodo per ottenere il serverID
    -
    -
    getSimbol(String) - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo che per ottenre il simbolo del server
    -
    -
    getSimbol(String) - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo che per ottenre il simbolo del server
    -
    -
    getSimbolCommand() - Method in class beans.ServersDiscord
    -
     
    -
    getSimbolCommand(String) - Static method in class command.pattern.ControlCommand
    -
    -
    Metodo per ottere il simbolo di comando del server
    -
    -
    getTimestamp(long) - Static method in class command.real.sound.MusicManager
    -
     
    -
    getTitle() - Method in class beans.RSSMessage
    -
    -
    Metodo per ottenre il titolo del feed
    -
    -
    getToken() - Static method in class interfaces.DiscordTokenInterfaces
    -
     
    -
    getTwitterManagerWithStream() - Method in class interfaces.TwitterManager
    -
     
    -
    getTwitterStream() - Method in class interfaces.TwitterManager
    -
     
    -
    getUrl(MessageReceivedEvent) - Static method in class command.real.sound.MusicManager
    -
    -
    Parsing del messaggio per ottenere l'url
    -
    -
    Giorno - Class in beans.BDOBossBean
    -
    -
    Rappresentazione del giorno di spawn dei boss di BDO
    -
    -
    Giorno(String, ArrayList<Boss>) - Constructor for class beans.BDOBossBean.Giorno
    -
     
    -
    giorno - Variable in class beans.BDOBossBean.Giorno
    -
     
    -
    gson - Static variable in class starter.Start
    -
     
    -
    GuildMusicManager - Class in command.real.sound
    -
    -
    Holder for both the player and a track scheduler for one guild.
    -
    -
    GuildMusicManager(AudioPlayerManager) - Constructor for class command.real.sound.GuildMusicManager
    -
    -
    Creates a player and a track scheduler.
    -
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-7.html b/docs/page/javadoc/index-files/index-7.html deleted file mode 100644 index 1a12ea0..0000000 --- a/docs/page/javadoc/index-files/index-7.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - -H-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    H

    -
    -
    HelpCommand - Class in command.real.configuration
    -
    -
    Deprecated.
    -
    -
    HelpCommand() - Constructor for class command.real.configuration.HelpCommand
    -
    -
    Deprecated.
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-8.html b/docs/page/javadoc/index-files/index-8.html deleted file mode 100644 index bef0d85..0000000 --- a/docs/page/javadoc/index-files/index-8.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - -I-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    I

    -
    -
    id - Variable in class beans.Rsslink
    -
     
    -
    InfoCommand - Class in command.real.configuration
    -
    -
    Deprecated.
    -
    -
    InfoCommand() - Constructor for class command.real.configuration.InfoCommand
    -
    -
    Deprecated.
    -
    initializeDB() - Static method in class interfaces.PostgreSQLInterface
    -
    -
    Metodo per inizializzare la connessione
    -
    -
    initializeDB() - Static method in class interfaces.SQLiteInterfaces
    -
    -
    Deprecated.
    -
    Metodo per inizializzare la connessione e/o il DB + la tabella - - PS: In caso sia il primo avvio del bot, accendere, spegnere e successivamente riaccendere il bot
    -
    -
    interfaces - package interfaces
    -
     
    -
    isOpus() - Method in class command.real.sound.AudioPlayerSendHandler
    -
     
    -
    isRepeating() - Method in class command.real.sound.TrackScheduler
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index-files/index-9.html b/docs/page/javadoc/index-files/index-9.html deleted file mode 100644 index 6519d0f..0000000 --- a/docs/page/javadoc/index-files/index-9.html +++ /dev/null @@ -1,137 +0,0 @@ - - - - - -J-Index (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    A B C D E G H I J L M N O P Q R S T U V  - - -

    J

    -
    -
    jda - Static variable in class starter.Start
    -
     
    -
    join(MessageReceivedEvent) - Method in class command.real.sound.MusicManager
    -
    -
    Metodo per eseguire il join nel canale
    -
    -
    JoinListener - Class in command.real
    -
     
    -
    JoinListener() - Constructor for class command.real.JoinListener
    -
     
    -
    -A B C D E G H I J L M N O P Q R S T U V 
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/index.html b/docs/page/javadoc/index.html deleted file mode 100644 index eab0b7e..0000000 --- a/docs/page/javadoc/index.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - -Documentazione TakaoBot - - - - - - - - - -<noscript> -<div>JavaScript is disabled on your browser.</div> -</noscript> -<h2>Frame Alert</h2> -<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="overview-summary.html">Non-frame version</a>.</p> - - - diff --git a/docs/page/javadoc/interfaces/DiscordScheduler.html b/docs/page/javadoc/interfaces/DiscordScheduler.html deleted file mode 100644 index ace2395..0000000 --- a/docs/page/javadoc/interfaces/DiscordScheduler.html +++ /dev/null @@ -1,271 +0,0 @@ - - - - - -DiscordScheduler (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    interfaces
    -

    Class DiscordScheduler

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • interfaces.DiscordScheduler
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class DiscordScheduler
      -extends java.lang.Object
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        DiscordScheduler() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static voidstartScheduling(net.dv8tion.jda.core.JDA jda) 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          DiscordScheduler

          -
          public DiscordScheduler()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          startScheduling

          -
          public static void startScheduling(net.dv8tion.jda.core.JDA jda)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/interfaces/DiscordTokenInterfaces.html b/docs/page/javadoc/interfaces/DiscordTokenInterfaces.html deleted file mode 100644 index 037cb25..0000000 --- a/docs/page/javadoc/interfaces/DiscordTokenInterfaces.html +++ /dev/null @@ -1,272 +0,0 @@ - - - - - -DiscordTokenInterfaces (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    interfaces
    -

    Class DiscordTokenInterfaces

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • interfaces.DiscordTokenInterfaces
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class DiscordTokenInterfaces
      -extends java.lang.Object
      -
      Classe per caricare il token di discord da file
      -
    • -
    -
    -
    -
      -
    • - - - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static java.lang.StringgetToken() 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          DiscordTokenInterfaces

          -
          public DiscordTokenInterfaces()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getToken

          -
          public static java.lang.String getToken()
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/interfaces/PostgreSQLInterface.html b/docs/page/javadoc/interfaces/PostgreSQLInterface.html deleted file mode 100644 index 2700764..0000000 --- a/docs/page/javadoc/interfaces/PostgreSQLInterface.html +++ /dev/null @@ -1,793 +0,0 @@ - - - - - -PostgreSQLInterface (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    interfaces
    -

    Class PostgreSQLInterface

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • interfaces.PostgreSQLInterface
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class PostgreSQLInterface
      -extends java.lang.Object
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        private static org.hibernate.SessionFactorysessionFactory 
        -
      • -
      - - - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static voiddeleteServer(java.lang.String serverID) -
        Metodo che rimuove la riga del server che ha espulso il bot
        -
        static java.util.ArrayList<ServerToChannel>getATMAlertChannel() -
        Metodo per ottenere tutti i canali registrati agli alert di ATM
        -
        static java.util.ArrayList<ServerToChannel>getBDOBossChannel() -
        Metodo per ottenere tutti i canali registrati agli alert dei boss di BDO
        -
        static java.util.ArrayList<ServerToChannel>getBDONewsChannel() -
        Metodo per ottenere tutti i canali registrati alle news di BDO
        -
        static java.util.ArrayList<ServerToChannel>getBDOPatchChannel() -
        Metodo per ottenere tutti i canali registrati alle patch di BDO
        -
        static java.lang.StringgetLastATMAlert() -
        Ottiene il link dell'ultimo alert di atm
        -
        static java.lang.StringgetLastPatchBDO() -
        Ottiene il link dell'ultima patch di BDO
        -
        static java.util.ArrayListgetListNewsBDO() -
        Ottiene la lista delle ultime notizie di BDO
        -
        static java.lang.StringgetSimbol(java.lang.String serverID) -
        Metodo che per ottenre il simbolo del server
        -
        static voidinitializeDB() -
        Metodo per inizializzare la connessione
        -
        static voidnewServer(java.lang.String nameServer, - java.lang.String serverID) -
        Metodo che aggiunge nome e l'id del server che ha aggiunto il bot sul database.
        -
        static voidremoveATMAlertChannel(java.lang.String serverID) -
        Metodo per rimuovere il canale per gli alert di ATM
        -
        static voidremoveBDOBossChannel(java.lang.String serverID) -
        Metodo per rimuovere il canale per i boss alert di BDO
        -
        static voidremoveBDONewsChannel(java.lang.String serverID) -
        Metodo per rimuovere il canale per le news su BDO
        -
        static voidremoveBDOPatchChannel(java.lang.String serverID) -
        Metodo per rimuovere il canale per le patch di BDO
        -
        static voidsetATMAlertChannel(java.lang.String serverID, - java.lang.String channelID) -
        Metodo per settare il canale per gli alert dell'ATM
        -
        static voidsetBDOBossChannel(java.lang.String serverID, - java.lang.String channelID) -
        Metodo per settare il canale per i boss alert di BDO
        -
        static voidsetBDONewsChannel(java.lang.String serverID, - java.lang.String channelID) -
        Metodo per settare il canale per le news su BDO
        -
        static voidsetBDOPatchChannel(java.lang.String serverID, - java.lang.String channelID) -
        Metodo per settare il canale per le patch di BDO
        -
        static voidsetLastATMAlert(java.lang.String url) -
        Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
        -
        static voidsetLastPatchBDO(java.lang.String url) -
        Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
        -
        static voidsetNewsBDO(java.util.ArrayList<java.lang.String> newsBDOList) -
        Imposta la lista delle ultime notizie di bdo
        -
        static voidsetSimbol(java.lang.String command, - java.lang.String serverID) -
        Metodo per configurare il simbolo di comando per il server
        -
        static voidupdateNameServer(java.lang.String serverID, - java.lang.String name) 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          sessionFactory

          -
          private static org.hibernate.SessionFactory sessionFactory
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          PostgreSQLInterface

          -
          public PostgreSQLInterface()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          initializeDB

          -
          public static void initializeDB()
          -
          Metodo per inizializzare la connessione
          -
        • -
        - - - -
          -
        • -

          newServer

          -
          public static void newServer(java.lang.String nameServer,
          -                             java.lang.String serverID)
          -
          Metodo che aggiunge nome e l'id del server che ha aggiunto il bot sul database.
          -
          -
          Parameters:
          -
          nameServer - Nome del server
          -
          serverID - ID del server Discord
          -
          -
        • -
        - - - -
          -
        • -

          deleteServer

          -
          public static void deleteServer(java.lang.String serverID)
          -
          Metodo che rimuove la riga del server che ha espulso il bot
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          -
        • -
        - - - -
          -
        • -

          updateNameServer

          -
          public static void updateNameServer(java.lang.String serverID,
          -                                    java.lang.String name)
          -
        • -
        - - - -
          -
        • -

          getSimbol

          -
          public static java.lang.String getSimbol(java.lang.String serverID)
          -
          Metodo che per ottenre il simbolo del server
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          Returns:
          -
          prefisso per comandi
          -
          -
        • -
        - - - -
          -
        • -

          setSimbol

          -
          public static void setSimbol(java.lang.String command,
          -                             java.lang.String serverID)
          -
          Metodo per configurare il simbolo di comando per il server
          -
          -
          Parameters:
          -
          command - Simbolo del comando nuovo
          -
          serverID - ID del server
          -
          -
        • -
        - - - -
          -
        • -

          setBDONewsChannel

          -
          public static void setBDONewsChannel(java.lang.String serverID,
          -                                     java.lang.String channelID)
          -
          Metodo per settare il canale per le news su BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          channelID - id del canale testuale
          -
          -
        • -
        - - - -
          -
        • -

          removeBDONewsChannel

          -
          public static void removeBDONewsChannel(java.lang.String serverID)
          -
          Metodo per rimuovere il canale per le news su BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          -
        • -
        - - - -
          -
        • -

          getBDONewsChannel

          -
          public static java.util.ArrayList<ServerToChannel> getBDONewsChannel()
          -
          Metodo per ottenere tutti i canali registrati alle news di BDO
          -
          -
          Returns:
          -
          Lista di coppie di serverID e channelID
          -
          See Also:
          -
          ServerToChannel
          -
          -
        • -
        - - - -
          -
        • -

          setBDOPatchChannel

          -
          public static void setBDOPatchChannel(java.lang.String serverID,
          -                                      java.lang.String channelID)
          -
          Metodo per settare il canale per le patch di BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          channelID - id del canale testuale
          -
          -
        • -
        - - - -
          -
        • -

          removeBDOPatchChannel

          -
          public static void removeBDOPatchChannel(java.lang.String serverID)
          -
          Metodo per rimuovere il canale per le patch di BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          -
        • -
        - - - -
          -
        • -

          setBDOBossChannel

          -
          public static void setBDOBossChannel(java.lang.String serverID,
          -                                     java.lang.String channelID)
          -
          Metodo per settare il canale per i boss alert di BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          channelID - id del canale testuale
          -
          -
        • -
        - - - -
          -
        • -

          removeBDOBossChannel

          -
          public static void removeBDOBossChannel(java.lang.String serverID)
          -
          Metodo per rimuovere il canale per i boss alert di BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          -
        • -
        - - - -
          -
        • -

          getBDOBossChannel

          -
          public static java.util.ArrayList<ServerToChannel> getBDOBossChannel()
          -
          Metodo per ottenere tutti i canali registrati agli alert dei boss di BDO
          -
          -
          Returns:
          -
          Lista di coppie di serverID e channelID
          -
          See Also:
          -
          ServerToChannel
          -
          -
        • -
        - - - -
          -
        • -

          getBDOPatchChannel

          -
          public static java.util.ArrayList<ServerToChannel> getBDOPatchChannel()
          -
          Metodo per ottenere tutti i canali registrati alle patch di BDO
          -
          -
          Returns:
          -
          lista dei server e dei relativi canali che si sono registrati
          -
          See Also:
          -
          ServerToChannel
          -
          -
        • -
        - - - -
          -
        • -

          getListNewsBDO

          -
          public static java.util.ArrayList getListNewsBDO()
          -
          Ottiene la lista delle ultime notizie di BDO
          -
          -
          Returns:
          -
          ArrayList lista delle ultime notizie
          -
          -
        • -
        - - - -
          -
        • -

          setNewsBDO

          -
          public static void setNewsBDO(java.util.ArrayList<java.lang.String> newsBDOList)
          -
          Imposta la lista delle ultime notizie di bdo
          -
          -
          Parameters:
          -
          newsBDOList - Lista delle ultime notizie di BDO
          -
          -
        • -
        - - - -
          -
        • -

          getLastPatchBDO

          -
          public static java.lang.String getLastPatchBDO()
          -
          Ottiene il link dell'ultima patch di BDO
          -
          -
          Returns:
          -
          String link url dell'ultima patch
          -
          -
        • -
        - - - -
          -
        • -

          setLastPatchBDO

          -
          public static void setLastPatchBDO(java.lang.String url)
          -
          Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
          -
          -
          Parameters:
          -
          url - url dell'ultimo feed rss aggiornato
          -
          -
        • -
        - - - -
          -
        • -

          setATMAlertChannel

          -
          public static void setATMAlertChannel(java.lang.String serverID,
          -                                      java.lang.String channelID)
          -
          Metodo per settare il canale per gli alert dell'ATM
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          channelID - id del canale testuale
          -
          -
        • -
        - - - -
          -
        • -

          getATMAlertChannel

          -
          public static java.util.ArrayList<ServerToChannel> getATMAlertChannel()
          -
          Metodo per ottenere tutti i canali registrati agli alert di ATM
          -
          -
          Returns:
          -
          lista dei server e dei relativi canali che si sono registrati
          -
          See Also:
          -
          ServerToChannel
          -
          -
        • -
        - - - -
          -
        • -

          removeATMAlertChannel

          -
          public static void removeATMAlertChannel(java.lang.String serverID)
          -
          Metodo per rimuovere il canale per gli alert di ATM
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          -
        • -
        - - - -
          -
        • -

          getLastATMAlert

          -
          public static java.lang.String getLastATMAlert()
          -
          Ottiene il link dell'ultimo alert di atm
          -
          -
          Returns:
          -
          String link url dell'ultimo alert di atm
          -
          -
        • -
        - - - -
          -
        • -

          setLastATMAlert

          -
          public static void setLastATMAlert(java.lang.String url)
          -
          Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
          -
          -
          Parameters:
          -
          url - url dell'ultimo feed rss aggiornato
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/interfaces/PropertyInterfaces.html b/docs/page/javadoc/interfaces/PropertyInterfaces.html deleted file mode 100644 index beda5c0..0000000 --- a/docs/page/javadoc/interfaces/PropertyInterfaces.html +++ /dev/null @@ -1,271 +0,0 @@ - - - - - -PropertyInterfaces (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    interfaces
    -

    Class PropertyInterfaces

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • interfaces.PropertyInterfaces
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class PropertyInterfaces
      -extends java.lang.Object
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        PropertyInterfaces() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static voidgetProp() 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          PropertyInterfaces

          -
          public PropertyInterfaces()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getProp

          -
          public static void getProp()
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/interfaces/SQLiteInterfaces.RSS_DB_COLUMN.html b/docs/page/javadoc/interfaces/SQLiteInterfaces.RSS_DB_COLUMN.html deleted file mode 100644 index 7a13beb..0000000 --- a/docs/page/javadoc/interfaces/SQLiteInterfaces.RSS_DB_COLUMN.html +++ /dev/null @@ -1,369 +0,0 @@ - - - - - -SQLiteInterfaces.RSS_DB_COLUMN (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    interfaces
    -

    Enum SQLiteInterfaces.RSS_DB_COLUMN

    -
    -
    - -
    - -
    -
    -
      -
    • - - - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static SQLiteInterfaces.RSS_DB_COLUMNvalueOf(java.lang.String name) -
        Returns the enum constant of this type with the specified name.
        -
        static SQLiteInterfaces.RSS_DB_COLUMN[]values() -
        Returns an array containing the constants of this enum type, in -the order they are declared.
        -
        -
          -
        • - - -

          Methods inherited from class java.lang.Enum

          -clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
        • -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -getClass, notify, notifyAll, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - - - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          values

          -
          public static SQLiteInterfaces.RSS_DB_COLUMN[] values()
          -
          Returns an array containing the constants of this enum type, in -the order they are declared. This method may be used to iterate -over the constants as follows: -
          -for (SQLiteInterfaces.RSS_DB_COLUMN c : SQLiteInterfaces.RSS_DB_COLUMN.values())
          -    System.out.println(c);
          -
          -
          -
          Returns:
          -
          an array containing the constants of this enum type, in the order they are declared
          -
          -
        • -
        - - - -
          -
        • -

          valueOf

          -
          public static SQLiteInterfaces.RSS_DB_COLUMN valueOf(java.lang.String name)
          -
          Returns the enum constant of this type with the specified name. -The string must match exactly an identifier used to declare an -enum constant in this type. (Extraneous whitespace characters are -not permitted.)
          -
          -
          Parameters:
          -
          name - the name of the enum constant to be returned.
          -
          Returns:
          -
          the enum constant with the specified name
          -
          Throws:
          -
          java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
          -
          java.lang.NullPointerException - if the argument is null
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/interfaces/SQLiteInterfaces.SD_DB_COLUMN.html b/docs/page/javadoc/interfaces/SQLiteInterfaces.SD_DB_COLUMN.html deleted file mode 100644 index 7615c62..0000000 --- a/docs/page/javadoc/interfaces/SQLiteInterfaces.SD_DB_COLUMN.html +++ /dev/null @@ -1,406 +0,0 @@ - - - - - -SQLiteInterfaces.SD_DB_COLUMN (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    interfaces
    -

    Enum SQLiteInterfaces.SD_DB_COLUMN

    -
    -
    - -
    - -
    -
    - -
    -
    -
      -
    • - - - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          values

          -
          public static SQLiteInterfaces.SD_DB_COLUMN[] values()
          -
          Returns an array containing the constants of this enum type, in -the order they are declared. This method may be used to iterate -over the constants as follows: -
          -for (SQLiteInterfaces.SD_DB_COLUMN c : SQLiteInterfaces.SD_DB_COLUMN.values())
          -    System.out.println(c);
          -
          -
          -
          Returns:
          -
          an array containing the constants of this enum type, in the order they are declared
          -
          -
        • -
        - - - -
          -
        • -

          valueOf

          -
          public static SQLiteInterfaces.SD_DB_COLUMN valueOf(java.lang.String name)
          -
          Returns the enum constant of this type with the specified name. -The string must match exactly an identifier used to declare an -enum constant in this type. (Extraneous whitespace characters are -not permitted.)
          -
          -
          Parameters:
          -
          name - the name of the enum constant to be returned.
          -
          Returns:
          -
          the enum constant with the specified name
          -
          Throws:
          -
          java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
          -
          java.lang.NullPointerException - if the argument is null
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/interfaces/SQLiteInterfaces.html b/docs/page/javadoc/interfaces/SQLiteInterfaces.html deleted file mode 100644 index 4f5610c..0000000 --- a/docs/page/javadoc/interfaces/SQLiteInterfaces.html +++ /dev/null @@ -1,896 +0,0 @@ - - - - - -SQLiteInterfaces (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    interfaces
    -

    Class SQLiteInterfaces

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • interfaces.SQLiteInterfaces
      • -
      -
    • -
    -
    -
      -
    • -
      -
      Deprecated.
      -
      -
      @Deprecated
      -public class SQLiteInterfaces
      -extends java.lang.Object
      -
    • -
    -
    -
    -
      -
    • - - - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        private static java.sql.Connectionconnection -
        Deprecated. 
        private static java.lang.StringRSS_LINK -
        Deprecated. 
        private static java.lang.StringSERVERS_DISCORD -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        SQLiteInterfaces() -
        Deprecated. 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Concrete Methods Deprecated Methods 
        Modifier and TypeMethod and Description
        static voiddeleteServer(java.lang.String serverID) -
        Deprecated. 
        -
        Metodo che rimuove la riga del server che ha espulso il bot
        -
        static java.util.ArrayList<ServerToChannel>getATMAlertChannel() -
        Deprecated. 
        -
        Metodo per ottenere tutti i canali registrati agli alert di ATM
        -
        static java.util.ArrayList<ServerToChannel>getBDOBossChannel() -
        Deprecated. 
        static java.util.ArrayList<ServerToChannel>getBDONewsChannel() -
        Deprecated. 
        -
        Metodo per ottenere tutti i canali registrati alle news di BDO
        -
        static java.util.ArrayList<ServerToChannel>getBDOPatchChannel() -
        Deprecated. 
        -
        Metodo per ottenere tutti i canali registrati alle patch di BDO
        -
        static java.lang.StringgetLastATMAlert() -
        Deprecated. 
        -
        Ottiene il link dell'ultima patch di BDO
        -
        static java.lang.StringgetLastPatchBDO() -
        Deprecated. 
        -
        Ottiene il link dell'ultima patch di BDO
        -
        static java.util.ArrayListgetListNewsBDO() -
        Deprecated. 
        -
        Ottiene la lista delle ultime notizie di BDO
        -
        static java.lang.StringgetSimbol(java.lang.String serverID) -
        Deprecated. 
        -
        Metodo che per ottenre il simbolo del server
        -
        static voidinitializeDB() -
        Deprecated. 
        -
        Metodo per inizializzare la connessione e/o il DB + la tabella - - PS: In caso sia il primo avvio del bot, accendere, spegnere e successivamente riaccendere il bot
        -
        static voidnewServer(java.lang.String nameServe, - java.lang.String serverID) -
        Deprecated. 
        -
        Metodo che aggiunge nome e l'id del server che ha aggiunto il bot sul database.
        -
        static voidremoveATMAlertChannel(java.lang.String serverID) -
        Deprecated. 
        -
        Metodo per rimuovere il canale per gli alert di ATM
        -
        static voidremoveBDOBossChannel(java.lang.String serverID) -
        Deprecated. 
        -
        Metodo per rimuovere il canale per i boss alert di BDO
        -
        static voidremoveBDONewsChannel(java.lang.String serverID) -
        Deprecated. 
        -
        Metodo per rimuovere il canale per le news su BDO
        -
        static voidremoveBDOPatchChannel(java.lang.String serverID) -
        Deprecated. 
        -
        Metodo per rimuovere il canale per le patch di BDO
        -
        static voidsetATMAlertChannel(java.lang.String serverID, - java.lang.String channelID) -
        Deprecated. 
        -
        Metodo per settare il canale per gli alert dell'ATM
        -
        static voidsetBDOBossChannel(java.lang.String serverID, - java.lang.String channelID) -
        Deprecated. 
        -
        Metodo per settare il canale per i boss alert di BDO
        -
        static voidsetBDONewsChannel(java.lang.String serverID, - java.lang.String channelID) -
        Deprecated. 
        -
        Metodo per settare il canale per le news su BDO
        -
        static voidsetBDOPatchChannel(java.lang.String serverID, - java.lang.String channelID) -
        Deprecated. 
        -
        Metodo per settare il canale per le patch di BDO
        -
        static voidsetLastATMAlert(java.lang.String url) -
        Deprecated. 
        -
        Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
        -
        static voidsetLastPatchBDO(java.lang.String url) -
        Deprecated. 
        -
        Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
        -
        static voidsetNewsBDO(java.util.ArrayList<java.lang.String> newsBDOList) -
        Deprecated. 
        -
        Imposta la lista delle ultime notizie di bdo
        -
        static voidsetSimbol(java.lang.String command, - java.lang.String serverID) -
        Deprecated. 
        -
        Metodo per configurare il simbolo di comando per il server
        -
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          SERVERS_DISCORD

          -
          private static final java.lang.String SERVERS_DISCORD
          -
          Deprecated. 
          -
          -
          See Also:
          -
          Constant Field Values
          -
          -
        • -
        - - - -
          -
        • -

          RSS_LINK

          -
          private static final java.lang.String RSS_LINK
          -
          Deprecated. 
          -
          -
          See Also:
          -
          Constant Field Values
          -
          -
        • -
        - - - -
          -
        • -

          connection

          -
          private static java.sql.Connection connection
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          SQLiteInterfaces

          -
          public SQLiteInterfaces()
          -
          Deprecated. 
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          initializeDB

          -
          public static void initializeDB()
          -
          Deprecated. 
          -
          Metodo per inizializzare la connessione e/o il DB + la tabella -

          - PS: In caso sia il primo avvio del bot, accendere, spegnere e successivamente riaccendere il bot

          -
        • -
        - - - -
          -
        • -

          newServer

          -
          public static void newServer(java.lang.String nameServe,
          -                             java.lang.String serverID)
          -
          Deprecated. 
          -
          Metodo che aggiunge nome e l'id del server che ha aggiunto il bot sul database.
          -
          -
          Parameters:
          -
          nameServe - Nome del server
          -
          serverID - ID del server Discord
          -
          -
        • -
        - - - -
          -
        • -

          deleteServer

          -
          public static void deleteServer(java.lang.String serverID)
          -
          Deprecated. 
          -
          Metodo che rimuove la riga del server che ha espulso il bot
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          -
        • -
        - - - -
          -
        • -

          getSimbol

          -
          public static java.lang.String getSimbol(java.lang.String serverID)
          -
          Deprecated. 
          -
          Metodo che per ottenre il simbolo del server
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          Returns:
          -
          prefisso per comandi
          -
          -
        • -
        - - - -
          -
        • -

          setSimbol

          -
          public static void setSimbol(java.lang.String command,
          -                             java.lang.String serverID)
          -
          Deprecated. 
          -
          Metodo per configurare il simbolo di comando per il server
          -
          -
          Parameters:
          -
          command - Simbolo del comando nuovo
          -
          serverID - ID del server
          -
          -
        • -
        - - - -
          -
        • -

          setBDONewsChannel

          -
          public static void setBDONewsChannel(java.lang.String serverID,
          -                                     java.lang.String channelID)
          -
          Deprecated. 
          -
          Metodo per settare il canale per le news su BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          channelID - id del canale testuale
          -
          -
        • -
        - - - -
          -
        • -

          removeBDONewsChannel

          -
          public static void removeBDONewsChannel(java.lang.String serverID)
          -
          Deprecated. 
          -
          Metodo per rimuovere il canale per le news su BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          -
        • -
        - - - -
          -
        • -

          getBDONewsChannel

          -
          public static java.util.ArrayList<ServerToChannel> getBDONewsChannel()
          -
          Deprecated. 
          -
          Metodo per ottenere tutti i canali registrati alle news di BDO
          -
          -
          Returns:
          -
          Lista di coppie di serverID e channelID
          -
          See Also:
          -
          ServerToChannel
          -
          -
        • -
        - - - -
          -
        • -

          setBDOPatchChannel

          -
          public static void setBDOPatchChannel(java.lang.String serverID,
          -                                      java.lang.String channelID)
          -
          Deprecated. 
          -
          Metodo per settare il canale per le patch di BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          channelID - id del canale testuale
          -
          -
        • -
        - - - -
          -
        • -

          removeBDOPatchChannel

          -
          public static void removeBDOPatchChannel(java.lang.String serverID)
          -
          Deprecated. 
          -
          Metodo per rimuovere il canale per le patch di BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          -
        • -
        - - - -
          -
        • -

          setBDOBossChannel

          -
          public static void setBDOBossChannel(java.lang.String serverID,
          -                                     java.lang.String channelID)
          -
          Deprecated. 
          -
          Metodo per settare il canale per i boss alert di BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          channelID - id del canale testuale
          -
          -
        • -
        - - - -
          -
        • -

          removeBDOBossChannel

          -
          public static void removeBDOBossChannel(java.lang.String serverID)
          -
          Deprecated. 
          -
          Metodo per rimuovere il canale per i boss alert di BDO
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          -
        • -
        - - - -
          -
        • -

          getBDOBossChannel

          -
          public static java.util.ArrayList<ServerToChannel> getBDOBossChannel()
          -
          Deprecated. 
          -
        • -
        - - - -
          -
        • -

          getBDOPatchChannel

          -
          public static java.util.ArrayList<ServerToChannel> getBDOPatchChannel()
          -
          Deprecated. 
          -
          Metodo per ottenere tutti i canali registrati alle patch di BDO
          -
          -
          Returns:
          -
          lista dei server e dei relativi canali che si sono registrati
          -
          See Also:
          -
          ServerToChannel
          -
          -
        • -
        - - - -
          -
        • -

          getListNewsBDO

          -
          public static java.util.ArrayList getListNewsBDO()
          -
          Deprecated. 
          -
          Ottiene la lista delle ultime notizie di BDO
          -
          -
          Returns:
          -
          ArrayList lista delle ultime notizie
          -
          -
        • -
        - - - -
          -
        • -

          setNewsBDO

          -
          public static void setNewsBDO(java.util.ArrayList<java.lang.String> newsBDOList)
          -
          Deprecated. 
          -
          Imposta la lista delle ultime notizie di bdo
          -
          -
          Parameters:
          -
          newsBDOList - Lista delle ultime notizie di BDO
          -
          -
        • -
        - - - -
          -
        • -

          getLastPatchBDO

          -
          public static java.lang.String getLastPatchBDO()
          -
          Deprecated. 
          -
          Ottiene il link dell'ultima patch di BDO
          -
          -
          Returns:
          -
          String link url dell'ultima patch
          -
          -
        • -
        - - - -
          -
        • -

          setLastPatchBDO

          -
          public static void setLastPatchBDO(java.lang.String url)
          -
          Deprecated. 
          -
          Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
          -
          -
          Parameters:
          -
          url - url dell'ultimo feed rss aggiornato
          -
          -
        • -
        - - - -
          -
        • -

          setATMAlertChannel

          -
          public static void setATMAlertChannel(java.lang.String serverID,
          -                                      java.lang.String channelID)
          -
          Deprecated. 
          -
          Metodo per settare il canale per gli alert dell'ATM
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          channelID - id del canale testuale
          -
          -
        • -
        - - - -
          -
        • -

          getATMAlertChannel

          -
          public static java.util.ArrayList<ServerToChannel> getATMAlertChannel()
          -
          Deprecated. 
          -
          Metodo per ottenere tutti i canali registrati agli alert di ATM
          -
          -
          Returns:
          -
          lista dei server e dei relativi canali che si sono registrati
          -
          See Also:
          -
          ServerToChannel
          -
          -
        • -
        - - - -
          -
        • -

          removeATMAlertChannel

          -
          public static void removeATMAlertChannel(java.lang.String serverID)
          -
          Deprecated. 
          -
          Metodo per rimuovere il canale per gli alert di ATM
          -
          -
          Parameters:
          -
          serverID - id del server
          -
          -
        • -
        - - - -
          -
        • -

          getLastATMAlert

          -
          public static java.lang.String getLastATMAlert()
          -
          Deprecated. 
          -
          Ottiene il link dell'ultima patch di BDO
          -
          -
          Returns:
          -
          String link url dell'ultima patch
          -
          -
        • -
        - - - -
          -
        • -

          setLastATMAlert

          -
          public static void setLastATMAlert(java.lang.String url)
          -
          Deprecated. 
          -
          Imposta l'ultima patch di BDO, se esiste l'aggiorna, altrimenti inserisce la riga.
          -
          -
          Parameters:
          -
          url - url dell'ultimo feed rss aggiornato
          -
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/interfaces/TakaoLog.html b/docs/page/javadoc/interfaces/TakaoLog.html deleted file mode 100644 index 5bfe968..0000000 --- a/docs/page/javadoc/interfaces/TakaoLog.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - -TakaoLog (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    interfaces
    -

    Class TakaoLog

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • interfaces.TakaoLog
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class TakaoLog
      -extends java.lang.Object
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        private static org.slf4j.Loggerlogger 
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        TakaoLog() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static voidlogDebug(java.lang.String message) 
        static voidlogError(java.lang.String message) 
        static voidlogInfo(java.lang.String message) 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          logger

          -
          private static org.slf4j.Logger logger
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          TakaoLog

          -
          public TakaoLog()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          logInfo

          -
          public static void logInfo(java.lang.String message)
          -
        • -
        - - - -
          -
        • -

          logDebug

          -
          public static void logDebug(java.lang.String message)
          -
        • -
        - - - -
          -
        • -

          logError

          -
          public static void logError(java.lang.String message)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/interfaces/TwitterManager.html b/docs/page/javadoc/interfaces/TwitterManager.html deleted file mode 100644 index ab24df5..0000000 --- a/docs/page/javadoc/interfaces/TwitterManager.html +++ /dev/null @@ -1,359 +0,0 @@ - - - - - -TwitterManager (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    interfaces
    -

    Class TwitterManager

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • interfaces.TwitterManager
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class TwitterManager
      -extends java.lang.Object
      -
    • -
    -
    -
    - -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          twitterStreamFactory

          -
          private twitter4j.TwitterStreamFactory twitterStreamFactory
          -
        • -
        - - - -
          -
        • -

          twitterStream

          -
          private twitter4j.TwitterStream twitterStream
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          TwitterManager

          -
          public TwitterManager()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          getTwitterManagerWithStream

          -
          public TwitterManager getTwitterManagerWithStream()
          -
        • -
        - - - -
          -
        • -

          setTwitterStreamListener

          -
          public TwitterManager setTwitterStreamListener(twitter4j.StatusListener listener)
          -
        • -
        - - - -
          -
        • -

          setTwitterStreamFilter

          -
          public TwitterManager setTwitterStreamFilter(twitter4j.FilterQuery filterQuery)
          -
        • -
        - - - -
          -
        • -

          getTwitterStream

          -
          public twitter4j.TwitterStream getTwitterStream()
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/interfaces/class-use/DiscordScheduler.html b/docs/page/javadoc/interfaces/class-use/DiscordScheduler.html deleted file mode 100644 index 8d4b1e4..0000000 --- a/docs/page/javadoc/interfaces/class-use/DiscordScheduler.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class interfaces.DiscordScheduler (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    interfaces.DiscordScheduler

    -
    -
    No usage of interfaces.DiscordScheduler
    - - - - - - diff --git a/docs/page/javadoc/interfaces/class-use/DiscordTokenInterfaces.html b/docs/page/javadoc/interfaces/class-use/DiscordTokenInterfaces.html deleted file mode 100644 index ec92327..0000000 --- a/docs/page/javadoc/interfaces/class-use/DiscordTokenInterfaces.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class interfaces.DiscordTokenInterfaces (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    interfaces.DiscordTokenInterfaces

    -
    -
    No usage of interfaces.DiscordTokenInterfaces
    - - - - - - diff --git a/docs/page/javadoc/interfaces/class-use/PostgreSQLInterface.html b/docs/page/javadoc/interfaces/class-use/PostgreSQLInterface.html deleted file mode 100644 index 558e255..0000000 --- a/docs/page/javadoc/interfaces/class-use/PostgreSQLInterface.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class interfaces.PostgreSQLInterface (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    interfaces.PostgreSQLInterface

    -
    -
    No usage of interfaces.PostgreSQLInterface
    - - - - - - diff --git a/docs/page/javadoc/interfaces/class-use/PropertyInterfaces.html b/docs/page/javadoc/interfaces/class-use/PropertyInterfaces.html deleted file mode 100644 index a01e33a..0000000 --- a/docs/page/javadoc/interfaces/class-use/PropertyInterfaces.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class interfaces.PropertyInterfaces (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    interfaces.PropertyInterfaces

    -
    -
    No usage of interfaces.PropertyInterfaces
    - - - - - - diff --git a/docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.RSS_DB_COLUMN.html b/docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.RSS_DB_COLUMN.html deleted file mode 100644 index abdca45..0000000 --- a/docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.RSS_DB_COLUMN.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - - -Uses of Class interfaces.SQLiteInterfaces.RSS_DB_COLUMN (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    interfaces.SQLiteInterfaces.RSS_DB_COLUMN

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.SD_DB_COLUMN.html b/docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.SD_DB_COLUMN.html deleted file mode 100644 index ca72176..0000000 --- a/docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.SD_DB_COLUMN.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - - -Uses of Class interfaces.SQLiteInterfaces.SD_DB_COLUMN (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    interfaces.SQLiteInterfaces.SD_DB_COLUMN

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.html b/docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.html deleted file mode 100644 index fe50b30..0000000 --- a/docs/page/javadoc/interfaces/class-use/SQLiteInterfaces.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class interfaces.SQLiteInterfaces (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    interfaces.SQLiteInterfaces

    -
    -
    No usage of interfaces.SQLiteInterfaces
    - - - - - - diff --git a/docs/page/javadoc/interfaces/class-use/TakaoLog.html b/docs/page/javadoc/interfaces/class-use/TakaoLog.html deleted file mode 100644 index f24e7fb..0000000 --- a/docs/page/javadoc/interfaces/class-use/TakaoLog.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class interfaces.TakaoLog (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    interfaces.TakaoLog

    -
    -
    No usage of interfaces.TakaoLog
    - - - - - - diff --git a/docs/page/javadoc/interfaces/class-use/TwitterManager.html b/docs/page/javadoc/interfaces/class-use/TwitterManager.html deleted file mode 100644 index b954f55..0000000 --- a/docs/page/javadoc/interfaces/class-use/TwitterManager.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - -Uses of Class interfaces.TwitterManager (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    interfaces.TwitterManager

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/interfaces/package-frame.html b/docs/page/javadoc/interfaces/package-frame.html deleted file mode 100644 index 37144dd..0000000 --- a/docs/page/javadoc/interfaces/package-frame.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - -interfaces (Documentazione TakaoBot) - - - - - -

    interfaces

    - - - diff --git a/docs/page/javadoc/interfaces/package-summary.html b/docs/page/javadoc/interfaces/package-summary.html deleted file mode 100644 index 08ac624..0000000 --- a/docs/page/javadoc/interfaces/package-summary.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - -interfaces (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package interfaces

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/interfaces/package-tree.html b/docs/page/javadoc/interfaces/package-tree.html deleted file mode 100644 index ba7dc83..0000000 --- a/docs/page/javadoc/interfaces/package-tree.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - -interfaces Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package interfaces

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    - -

    Enum Hierarchy

    - -
    - - - - - - diff --git a/docs/page/javadoc/interfaces/package-use.html b/docs/page/javadoc/interfaces/package-use.html deleted file mode 100644 index 21a03ac..0000000 --- a/docs/page/javadoc/interfaces/package-use.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - -Uses of Package interfaces (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    interfaces

    -
    -
    - -
    - - - - - - diff --git a/docs/page/javadoc/overview-frame.html b/docs/page/javadoc/overview-frame.html deleted file mode 100644 index f98379a..0000000 --- a/docs/page/javadoc/overview-frame.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - -Overview List (Documentazione TakaoBot) - - - - - - - -

     

    - - diff --git a/docs/page/javadoc/overview-summary.html b/docs/page/javadoc/overview-summary.html deleted file mode 100644 index 1460103..0000000 --- a/docs/page/javadoc/overview-summary.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - -Overview (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - -
    -

    Documentazione TakaoBot

    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Packages 
    PackageDescription
    beans 
    beans.BDOBossBean 
    command.pattern 
    command.real 
    command.real.BDO 
    command.real.BDO.boss 
    command.real.BDO.RSS 
    command.real.configuration 
    command.real.sound 
    command.real.tpl.atmAlert 
    interfaces 
    starter 
    -
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/overview-tree.html b/docs/page/javadoc/overview-tree.html deleted file mode 100644 index b52516b..0000000 --- a/docs/page/javadoc/overview-tree.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - -Class Hierarchy (Documentazione TakaoBot) - - - - - - - - -
    - - - - - - - -
    - - - -
    -

    Class Hierarchy

    - -

    Enum Hierarchy

    - -
    - -
    - - - - - - - -
    - - - - diff --git a/docs/page/javadoc/package-list b/docs/page/javadoc/package-list deleted file mode 100644 index 5633548..0000000 --- a/docs/page/javadoc/package-list +++ /dev/null @@ -1,12 +0,0 @@ -beans -beans.BDOBossBean -command.pattern -command.real -command.real.BDO -command.real.BDO.RSS -command.real.BDO.boss -command.real.configuration -command.real.sound -command.real.tpl.atmAlert -interfaces -starter diff --git a/docs/page/javadoc/script.js b/docs/page/javadoc/script.js deleted file mode 100644 index b346356..0000000 --- a/docs/page/javadoc/script.js +++ /dev/null @@ -1,30 +0,0 @@ -function show(type) -{ - count = 0; - for (var key in methods) { - var row = document.getElementById(key); - if ((methods[key] & type) != 0) { - row.style.display = ''; - row.className = (count++ % 2) ? rowColor : altColor; - } - else - row.style.display = 'none'; - } - updateTabs(type); -} - -function updateTabs(type) -{ - for (var value in tabs) { - var sNode = document.getElementById(tabs[value][0]); - var spanNode = sNode.firstChild; - if (value == type) { - sNode.className = activeTableTab; - spanNode.innerHTML = tabs[value][1]; - } - else { - sNode.className = tableTab; - spanNode.innerHTML = "" + tabs[value][1] + ""; - } - } -} diff --git a/docs/page/javadoc/starter/Start.html b/docs/page/javadoc/starter/Start.html deleted file mode 100644 index 3db588c..0000000 --- a/docs/page/javadoc/starter/Start.html +++ /dev/null @@ -1,320 +0,0 @@ - - - - - -Start (Documentazione TakaoBot) - - - - - - - - - - - - -
    -
    starter
    -

    Class Start

    -
    -
    -
      -
    • java.lang.Object
    • -
    • -
        -
      • starter.Start
      • -
      -
    • -
    -
    -
      -
    • -
      -
      -
      public class Start
      -extends java.lang.Object
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Summary

        - - - - - - - - - - - - - - -
        Fields 
        Modifier and TypeField and Description
        static com.google.gson.Gsongson 
        static net.dv8tion.jda.core.JDAjda 
        -
      • -
      - -
        -
      • - - -

        Constructor Summary

        - - - - - - - - -
        Constructors 
        Constructor and Description
        Start() 
        -
      • -
      - -
        -
      • - - -

        Method Summary

        - - - - - - - - - - -
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static voidmain(java.lang.String[] args) 
        -
          -
        • - - -

          Methods inherited from class java.lang.Object

          -clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        • -
        -
      • -
      -
    • -
    -
    -
    -
      -
    • - -
        -
      • - - -

        Field Detail

        - - - -
          -
        • -

          gson

          -
          public static com.google.gson.Gson gson
          -
        • -
        - - - -
          -
        • -

          jda

          -
          public static net.dv8tion.jda.core.JDA jda
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Constructor Detail

        - - - -
          -
        • -

          Start

          -
          public Start()
          -
        • -
        -
      • -
      - -
        -
      • - - -

        Method Detail

        - - - -
          -
        • -

          main

          -
          public static void main(java.lang.String[] args)
          -
        • -
        -
      • -
      -
    • -
    -
    -
    - - - - - - - diff --git a/docs/page/javadoc/starter/class-use/Start.html b/docs/page/javadoc/starter/class-use/Start.html deleted file mode 100644 index bce868c..0000000 --- a/docs/page/javadoc/starter/class-use/Start.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Class starter.Start (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Class
    starter.Start

    -
    -
    No usage of starter.Start
    - - - - - - diff --git a/docs/page/javadoc/starter/package-frame.html b/docs/page/javadoc/starter/package-frame.html deleted file mode 100644 index 50177d8..0000000 --- a/docs/page/javadoc/starter/package-frame.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - -starter (Documentazione TakaoBot) - - - - - -

    starter

    -
    -

    Classes

    - -
    - - diff --git a/docs/page/javadoc/starter/package-summary.html b/docs/page/javadoc/starter/package-summary.html deleted file mode 100644 index df7401b..0000000 --- a/docs/page/javadoc/starter/package-summary.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - -starter (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Package starter

    -
    -
    -
      -
    • - - - - - - - - - - - - -
      Class Summary 
      ClassDescription
      Start 
      -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/starter/package-tree.html b/docs/page/javadoc/starter/package-tree.html deleted file mode 100644 index eecc29a..0000000 --- a/docs/page/javadoc/starter/package-tree.html +++ /dev/null @@ -1,137 +0,0 @@ - - - - - -starter Class Hierarchy (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Hierarchy For Package starter

    -Package Hierarchies: - -
    -
    -

    Class Hierarchy

    -
      -
    • java.lang.Object - -
    • -
    -
    - - - - - - diff --git a/docs/page/javadoc/starter/package-use.html b/docs/page/javadoc/starter/package-use.html deleted file mode 100644 index b9d5b70..0000000 --- a/docs/page/javadoc/starter/package-use.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -Uses of Package starter (Documentazione TakaoBot) - - - - - - - - - - - -
    -

    Uses of Package
    starter

    -
    -
    No usage of starter
    - - - - - - diff --git a/docs/page/javadoc/stylesheet.css b/docs/page/javadoc/stylesheet.css deleted file mode 100644 index 98055b2..0000000 --- a/docs/page/javadoc/stylesheet.css +++ /dev/null @@ -1,574 +0,0 @@ -/* Javadoc style sheet */ -/* -Overall document style -*/ - -@import url('resources/fonts/dejavu.css'); - -body { - background-color:#ffffff; - color:#353833; - font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; - font-size:14px; - margin:0; -} -a:link, a:visited { - text-decoration:none; - color:#4A6782; -} -a:hover, a:focus { - text-decoration:none; - color:#bb7a2a; -} -a:active { - text-decoration:none; - color:#4A6782; -} -a[name] { - color:#353833; -} -a[name]:hover { - text-decoration:none; - color:#353833; -} -pre { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; -} -h1 { - font-size:20px; -} -h2 { - font-size:18px; -} -h3 { - font-size:16px; - font-style:italic; -} -h4 { - font-size:13px; -} -h5 { - font-size:12px; -} -h6 { - font-size:11px; -} -ul { - list-style-type:disc; -} -code, tt { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; - padding-top:4px; - margin-top:8px; - line-height:1.4em; -} -dt code { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; - padding-top:4px; -} -table tr td dt code { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; - vertical-align:top; - padding-top:4px; -} -sup { - font-size:8px; -} -/* -Document title and Copyright styles -*/ -.clear { - clear:both; - height:0px; - overflow:hidden; -} -.aboutLanguage { - float:right; - padding:0px 21px; - font-size:11px; - z-index:200; - margin-top:-9px; -} -.legalCopy { - margin-left:.5em; -} -.bar a, .bar a:link, .bar a:visited, .bar a:active { - color:#FFFFFF; - text-decoration:none; -} -.bar a:hover, .bar a:focus { - color:#bb7a2a; -} -.tab { - background-color:#0066FF; - color:#ffffff; - padding:8px; - width:5em; - font-weight:bold; -} -/* -Navigation bar styles -*/ -.bar { - background-color:#4D7A97; - color:#FFFFFF; - padding:.8em .5em .4em .8em; - height:auto;/*height:1.8em;*/ - font-size:11px; - margin:0; -} -.topNav { - background-color:#4D7A97; - color:#FFFFFF; - float:left; - padding:0; - width:100%; - clear:right; - height:2.8em; - padding-top:10px; - overflow:hidden; - font-size:12px; -} -.bottomNav { - margin-top:10px; - background-color:#4D7A97; - color:#FFFFFF; - float:left; - padding:0; - width:100%; - clear:right; - height:2.8em; - padding-top:10px; - overflow:hidden; - font-size:12px; -} -.subNav { - background-color:#dee3e9; - float:left; - width:100%; - overflow:hidden; - font-size:12px; -} -.subNav div { - clear:left; - float:left; - padding:0 0 5px 6px; - text-transform:uppercase; -} -ul.navList, ul.subNavList { - float:left; - margin:0 25px 0 0; - padding:0; -} -ul.navList li{ - list-style:none; - float:left; - padding: 5px 6px; - text-transform:uppercase; -} -ul.subNavList li{ - list-style:none; - float:left; -} -.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { - color:#FFFFFF; - text-decoration:none; - text-transform:uppercase; -} -.topNav a:hover, .bottomNav a:hover { - text-decoration:none; - color:#bb7a2a; - text-transform:uppercase; -} -.navBarCell1Rev { - background-color:#F8981D; - color:#253441; - margin: auto 5px; -} -.skipNav { - position:absolute; - top:auto; - left:-9999px; - overflow:hidden; -} -/* -Page header and footer styles -*/ -.header, .footer { - clear:both; - margin:0 20px; - padding:5px 0 0 0; -} -.indexHeader { - margin:10px; - position:relative; -} -.indexHeader span{ - margin-right:15px; -} -.indexHeader h1 { - font-size:13px; -} -.title { - color:#2c4557; - margin:10px 0; -} -.subTitle { - margin:5px 0 0 0; -} -.header ul { - margin:0 0 15px 0; - padding:0; -} -.footer ul { - margin:20px 0 5px 0; -} -.header ul li, .footer ul li { - list-style:none; - font-size:13px; -} -/* -Heading styles -*/ -div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { - background-color:#dee3e9; - border:1px solid #d0d9e0; - margin:0 0 6px -8px; - padding:7px 5px; -} -ul.blockList ul.blockList ul.blockList li.blockList h3 { - background-color:#dee3e9; - border:1px solid #d0d9e0; - margin:0 0 6px -8px; - padding:7px 5px; -} -ul.blockList ul.blockList li.blockList h3 { - padding:0; - margin:15px 0; -} -ul.blockList li.blockList h2 { - padding:0px 0 20px 0; -} -/* -Page layout container styles -*/ -.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { - clear:both; - padding:10px 20px; - position:relative; -} -.indexContainer { - margin:10px; - position:relative; - font-size:12px; -} -.indexContainer h2 { - font-size:13px; - padding:0 0 3px 0; -} -.indexContainer ul { - margin:0; - padding:0; -} -.indexContainer ul li { - list-style:none; - padding-top:2px; -} -.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { - font-size:12px; - font-weight:bold; - margin:10px 0 0 0; - color:#4E4E4E; -} -.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { - margin:5px 0 10px 0px; - font-size:14px; - font-family:'DejaVu Sans Mono',monospace; -} -.serializedFormContainer dl.nameValue dt { - margin-left:1px; - font-size:1.1em; - display:inline; - font-weight:bold; -} -.serializedFormContainer dl.nameValue dd { - margin:0 0 0 1px; - font-size:1.1em; - display:inline; -} -/* -List styles -*/ -ul.horizontal li { - display:inline; - font-size:0.9em; -} -ul.inheritance { - margin:0; - padding:0; -} -ul.inheritance li { - display:inline; - list-style:none; -} -ul.inheritance li ul.inheritance { - margin-left:15px; - padding-left:15px; - padding-top:1px; -} -ul.blockList, ul.blockListLast { - margin:10px 0 10px 0; - padding:0; -} -ul.blockList li.blockList, ul.blockListLast li.blockList { - list-style:none; - margin-bottom:15px; - line-height:1.4; -} -ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { - padding:0px 20px 5px 10px; - border:1px solid #ededed; - background-color:#f8f8f8; -} -ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { - padding:0 0 5px 8px; - background-color:#ffffff; - border:none; -} -ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { - margin-left:0; - padding-left:0; - padding-bottom:15px; - border:none; -} -ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { - list-style:none; - border-bottom:none; - padding-bottom:0; -} -table tr td dl, table tr td dl dt, table tr td dl dd { - margin-top:0; - margin-bottom:1px; -} -/* -Table styles -*/ -.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { - width:100%; - border-left:1px solid #EEE; - border-right:1px solid #EEE; - border-bottom:1px solid #EEE; -} -.overviewSummary, .memberSummary { - padding:0px; -} -.overviewSummary caption, .memberSummary caption, .typeSummary caption, -.useSummary caption, .constantsSummary caption, .deprecatedSummary caption { - position:relative; - text-align:left; - background-repeat:no-repeat; - color:#253441; - font-weight:bold; - clear:none; - overflow:hidden; - padding:0px; - padding-top:10px; - padding-left:1px; - margin:0px; - white-space:pre; -} -.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, -.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, -.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, -.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, -.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, -.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, -.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, -.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { - color:#FFFFFF; -} -.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, -.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { - white-space:nowrap; - padding-top:5px; - padding-left:12px; - padding-right:12px; - padding-bottom:7px; - display:inline-block; - float:left; - background-color:#F8981D; - border: none; - height:16px; -} -.memberSummary caption span.activeTableTab span { - white-space:nowrap; - padding-top:5px; - padding-left:12px; - padding-right:12px; - margin-right:3px; - display:inline-block; - float:left; - background-color:#F8981D; - height:16px; -} -.memberSummary caption span.tableTab span { - white-space:nowrap; - padding-top:5px; - padding-left:12px; - padding-right:12px; - margin-right:3px; - display:inline-block; - float:left; - background-color:#4D7A97; - height:16px; -} -.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { - padding-top:0px; - padding-left:0px; - padding-right:0px; - background-image:none; - float:none; - display:inline; -} -.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, -.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { - display:none; - width:5px; - position:relative; - float:left; - background-color:#F8981D; -} -.memberSummary .activeTableTab .tabEnd { - display:none; - width:5px; - margin-right:3px; - position:relative; - float:left; - background-color:#F8981D; -} -.memberSummary .tableTab .tabEnd { - display:none; - width:5px; - margin-right:3px; - position:relative; - background-color:#4D7A97; - float:left; - -} -.overviewSummary td, .memberSummary td, .typeSummary td, -.useSummary td, .constantsSummary td, .deprecatedSummary td { - text-align:left; - padding:0px 0px 12px 10px; -} -th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, -td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ - vertical-align:top; - padding-right:0px; - padding-top:8px; - padding-bottom:3px; -} -th.colFirst, th.colLast, th.colOne, .constantsSummary th { - background:#dee3e9; - text-align:left; - padding:8px 3px 3px 7px; -} -td.colFirst, th.colFirst { - white-space:nowrap; - font-size:13px; -} -td.colLast, th.colLast { - font-size:13px; -} -td.colOne, th.colOne { - font-size:13px; -} -.overviewSummary td.colFirst, .overviewSummary th.colFirst, -.useSummary td.colFirst, .useSummary th.colFirst, -.overviewSummary td.colOne, .overviewSummary th.colOne, -.memberSummary td.colFirst, .memberSummary th.colFirst, -.memberSummary td.colOne, .memberSummary th.colOne, -.typeSummary td.colFirst{ - width:25%; - vertical-align:top; -} -td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { - font-weight:bold; -} -.tableSubHeadingColor { - background-color:#EEEEFF; -} -.altColor { - background-color:#FFFFFF; -} -.rowColor { - background-color:#EEEEEF; -} -/* -Content styles -*/ -.description pre { - margin-top:0; -} -.deprecatedContent { - margin:0; - padding:10px 0; -} -.docSummary { - padding:0; -} - -ul.blockList ul.blockList ul.blockList li.blockList h3 { - font-style:normal; -} - -div.block { - font-size:14px; - font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; -} - -td.colLast div { - padding-top:0px; -} - - -td.colLast a { - padding-bottom:3px; -} -/* -Formatting effect styles -*/ -.sourceLineNo { - color:green; - padding:0 30px 0 0; -} -h1.hidden { - visibility:hidden; - overflow:hidden; - font-size:10px; -} -.block { - display:block; - margin:3px 10px 2px 0px; - color:#474747; -} -.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, -.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, -.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { - font-weight:bold; -} -.deprecationComment, .emphasizedPhrase, .interfaceName { - font-style:italic; -} - -div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, -div.block div.block span.interfaceName { - font-style:normal; -} - -div.contentContainer ul.blockList li.blockList h2{ - padding-bottom:0px; -} diff --git a/docs/page/kotlindoc/alltypes/index.html b/docs/page/kotlindoc/alltypes/index.html new file mode 100644 index 0000000..12342f3 --- /dev/null +++ b/docs/page/kotlindoc/alltypes/index.html @@ -0,0 +1,266 @@ + + + +alltypes - + + + +

    All Types

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +it.discordbot.command.tpl.atmAlert.ATMCommand +

    Per i comandi dell'ATM

    +
    +it.discordbot.database.filter.ATMInterface +

    Classe di interfacciamento al db per le funzioni di ATM

    +
    +it.discordbot.command.tpl.atmAlert.ATMRSSReader +

    Classe per leggere il feed RSS di atm

    +
    +it.discordbot.command.tpl.atmAlert.ATMRSSScheduler +

    Classe per la schedulaziooe dei messaggi RSS di ATM

    +
    +it.discordbot.command.tpl.atmAlert.ATMTwitterScheduler +

    Classe per la schedulaziooe dei messaggi Twitter di ATM

    +
    +it.discordbot.command.music.config.AudioPlayerSendHandler +
    +it.discordbot.database.filter.BDOBossInterface +

    Classe di interfacciamento al db per le funzioni di BDO Boss

    +
    +it.discordbot.command.BDO.boss.BDOBossScheduler +

    Classe per la schedulazione dei boss

    +
    +it.discordbot.command.BDO.BDOCommand +

    Listener per contenere i comandi di BDO

    +
    +it.discordbot.database.filter.BDONewsInterface +

    Classe di interfacciamento al db per le funzioni di BDO News

    +
    +it.discordbot.command.BDO.RSS.BDONewsRSSScheduler +

    Classe per la schedulaziooe dei messaggi di news di BDO

    +
    +it.discordbot.database.filter.BDOPatchInterface +

    Classe di interfacciamento al db per le funzioni di BDO Patch

    +
    +it.discordbot.command.BDO.RSS.BDOPatchRSSScheduler +
    +it.discordbot.command.BDO.RSS.BDORSSReader +

    Classe per leggere gli RSS di BDO

    +
    +it.discordbot.beans.boss.Boss +

    Classe contenitore dei boss in una determinata ora

    +
    +it.discordbot.command.BDO.boss.BossUtil +

    Classe per processare i boss e ricavare il boss da notificare

    +
    +it.discordbot.command.generalCommand.GeneralCommand +

    Listener per contenere comandi di uso generale e di configurazione del bot

    +
    +it.discordbot.beans.boss.Giorno +

    Classe contenitore dei boss del giorno

    +
    +it.discordbot.command.music.config.GuildMusicManager +
    +it.discordbot.core.JDAController +

    Classe principale di avviamento del Bot Discord

    +
    +it.discordbot.command.generalCommand.JoinListener +

    Listener per contenere quando il bot entra o esce +da un server Discord

    +
    +it.discordbot.command.music.MusicCommand +
    +it.discordbot.command.music.config.MusicManager +
    +it.discordbot.beans.RSSLink +

    Entità che rappresenta la tabella contenitore dei link RSS

    +
    +it.discordbot.database.repository.RSSLinkRepository +
    +it.discordbot.beans.RSSMessage +

    Classe che contiene le informazioni utili dei messaggi RSS

    +
    +it.discordbot.command.pattern.RSSReader +

    Interfaccia per la lettura e la conversione +dei messaggi RSS a MessageEmbed

    +
    +it.discordbot.command.pattern.RSSScheduler +

    Interfaccia base per i metodi di pubblicazione dei messaggi RSS

    +
    +it.discordbot.beans.ServerDiscord +

    Entità che rappresenta la tabella dei Server Discord

    +
    +it.discordbot.database.repository.ServerDiscordRepository +
    +it.discordbot.database.filter.ServerManagementInterface +

    Classe di interfacciamento al db per le funzioni base del BOT

    +
    +it.discordbot.beans.ServerToChannel +

    Classe contenitore degli id dei server e relativi canali per +le pubblicazioni schedulate

    +
    +it.discordbot.StartBot +
    +it.discordbot.core.TakaoLog +

    Logger Unico per il bot

    +
    +it.discordbot.TestCommand +
    +it.discordbot.command.music.config.TrackScheduler +
    +it.discordbot.core.TwitterManager +

    Classe che si occupa di collegarsi ai sistemi di twitter

    +
    + + diff --git a/docs/page/kotlindoc/index-outline.html b/docs/page/kotlindoc/index-outline.html new file mode 100644 index 0000000..926625d --- /dev/null +++ b/docs/page/kotlindoc/index-outline.html @@ -0,0 +1,1597 @@ + + + +Module Contents + + + +
    + + + diff --git a/docs/page/kotlindoc/index.html b/docs/page/kotlindoc/index.html new file mode 100644 index 0000000..df705a8 --- /dev/null +++ b/docs/page/kotlindoc/index.html @@ -0,0 +1,121 @@ + + + + + + + +

    Packages

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    it.discordbot

    +
    +
    +

    it.discordbot.beans

    +
    +
    +

    it.discordbot.beans.boss

    +
    +
    +

    it.discordbot.command

    +
    +
    +

    it.discordbot.command.BDO

    +
    +
    +

    it.discordbot.command.BDO.boss

    +
    +
    +

    it.discordbot.command.BDO.RSS

    +
    +
    +

    it.discordbot.command.generalCommand

    +
    +
    +

    it.discordbot.command.music

    +
    +
    +

    it.discordbot.command.music.config

    +
    +
    +

    it.discordbot.command.pattern

    +
    +
    +

    it.discordbot.command.tpl.atmAlert

    +
    +
    +

    it.discordbot.core

    +
    +
    +

    it.discordbot.database.filter

    +
    +
    +

    it.discordbot.database.repository

    +
    +
    +

    Index

    +All Types + + diff --git a/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/-init-.html b/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/-init-.html new file mode 100644 index 0000000..d20cbb7 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/-init-.html @@ -0,0 +1,16 @@ + + + +Boss.<init> - + + + +it.discordbot.beans.boss / Boss / <init>
    +
    +

    <init>

    + +Boss(ora: String, nomeBoss: Array<String>) +

    Constructor
    +

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/index.html b/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/index.html new file mode 100644 index 0000000..b9749de --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/index.html @@ -0,0 +1,49 @@ + + + +Boss - + + + +it.discordbot.beans.boss / Boss
    +
    +

    Boss

    +data class Boss +

    Classe contenitore dei boss in una determinata ora

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +Boss(ora: String, nomeBoss: Array<String>)
    +

    Properties

    + + + + + + + + + + + +
    +

    nomeBoss

    +
    +val nomeBoss: Array<String> +

    Array nome o nomi dei boss

    +
    +

    ora

    +
    +val ora: String +

    String ora di spawn del boss

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/nome-boss.html b/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/nome-boss.html new file mode 100644 index 0000000..936a202 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/nome-boss.html @@ -0,0 +1,18 @@ + + + +Boss.nomeBoss - + + + +it.discordbot.beans.boss / Boss / nomeBoss
    +
    +

    nomeBoss

    + +val nomeBoss: Array<String> +

    Array nome o nomi dei boss

    +

    Property

    +

    +nomeBoss - Array nome o nomi dei boss

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/ora.html b/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/ora.html new file mode 100644 index 0000000..011bbe0 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans.boss/-boss/ora.html @@ -0,0 +1,18 @@ + + + +Boss.ora - + + + +it.discordbot.beans.boss / Boss / ora
    +
    +

    ora

    + +val ora: String +

    String ora di spawn del boss

    +

    Property

    +

    +ora - String ora di spawn del boss

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/-init-.html b/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/-init-.html new file mode 100644 index 0000000..6bb95d9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/-init-.html @@ -0,0 +1,16 @@ + + + +Giorno.<init> - + + + +it.discordbot.beans.boss / Giorno / <init>
    +
    +

    <init>

    + +Giorno(giorno: String, bosses: ArrayList<Boss>) +

    Constructor
    +

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/bosses.html b/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/bosses.html new file mode 100644 index 0000000..c3ada54 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/bosses.html @@ -0,0 +1,18 @@ + + + +Giorno.bosses - + + + +it.discordbot.beans.boss / Giorno / bosses
    +
    +

    bosses

    + +val bosses: ArrayList<Boss> +

    ArrayList lista dei boss del giorno

    +

    Property

    +

    +bosses - ArrayList lista dei boss del giorno

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/giorno.html b/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/giorno.html new file mode 100644 index 0000000..bb511b1 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/giorno.html @@ -0,0 +1,18 @@ + + + +Giorno.giorno - + + + +it.discordbot.beans.boss / Giorno / giorno
    +
    +

    giorno

    + +val giorno: String +

    String nome del giorno espesso in inglese e in maiuscolo

    +

    Property

    +

    +giorno - String nome del giorno espesso in inglese e in maiuscolo

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/index.html b/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/index.html new file mode 100644 index 0000000..db2fcae --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans.boss/-giorno/index.html @@ -0,0 +1,49 @@ + + + +Giorno - + + + +it.discordbot.beans.boss / Giorno
    +
    +

    Giorno

    +data class Giorno +

    Classe contenitore dei boss del giorno

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +Giorno(giorno: String, bosses: ArrayList<Boss>)
    +

    Properties

    + + + + + + + + + + + +
    +

    bosses

    +
    +val bosses: ArrayList<Boss> +

    ArrayList lista dei boss del giorno

    +
    +

    giorno

    +
    +val giorno: String +

    String nome del giorno espesso in inglese e in maiuscolo

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans.boss/index.html b/docs/page/kotlindoc/it.discordbot.beans.boss/index.html new file mode 100644 index 0000000..fe2f872 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans.boss/index.html @@ -0,0 +1,35 @@ + + + +it.discordbot.beans.boss - + + + +it.discordbot.beans.boss
    +
    +

    Package it.discordbot.beans.boss

    +

    Types

    + + + + + + + + + + + +
    +

    Boss

    +
    +data class Boss +

    Classe contenitore dei boss in una determinata ora

    +
    +

    Giorno

    +
    +data class Giorno +

    Classe contenitore dei boss del giorno

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/-init-.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/-init-.html new file mode 100644 index 0000000..c412488 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/-init-.html @@ -0,0 +1,15 @@ + + + +RSSLink.<init> - + + + +it.discordbot.beans / RSSLink / <init>
    +
    +

    <init>

    + +RSSLink() +

    Entità che rappresenta la tabella contenitore dei link RSS

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/id.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/id.html new file mode 100644 index 0000000..1af0d54 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/id.html @@ -0,0 +1,18 @@ + + + +RSSLink.id - + + + +it.discordbot.beans / RSSLink / id
    +
    +

    id

    + +var id: Long +

    Long id riga

    +

    Property

    +

    +id - Long id riga

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/index.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/index.html new file mode 100644 index 0000000..84c8725 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/index.html @@ -0,0 +1,69 @@ + + + +RSSLink - + + + +it.discordbot.beans / RSSLink
    +
    +

    RSSLink

    +@Entity class RSSLink +

    Entità che rappresenta la tabella contenitore dei link RSS

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +RSSLink() +

    Entità che rappresenta la tabella contenitore dei link RSS

    +
    +

    Properties

    + + + + + + + + + + + + + + + + + + + +
    +

    id

    +
    +var id: Long +

    Long id riga

    +
    +

    lastAtmAlert

    +
    +var lastAtmAlert: String? +

    Link ultimo feed di atm

    +
    +

    lastNewsBDO

    +
    +var lastNewsBDO: String? +

    Lista link ultime news di BDO

    +
    +

    lastPatchBDO

    +
    +var lastPatchBDO: String? +

    Link ultima patch di BDO

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-atm-alert.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-atm-alert.html new file mode 100644 index 0000000..3a2c9d3 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-atm-alert.html @@ -0,0 +1,15 @@ + + + +RSSLink.lastAtmAlert - + + + +it.discordbot.beans / RSSLink / lastAtmAlert
    +
    +

    lastAtmAlert

    + +var lastAtmAlert: String? +

    Link ultimo feed di atm

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-news-b-d-o.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-news-b-d-o.html new file mode 100644 index 0000000..b297d50 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-news-b-d-o.html @@ -0,0 +1,15 @@ + + + +RSSLink.lastNewsBDO - + + + +it.discordbot.beans / RSSLink / lastNewsBDO
    +
    +

    lastNewsBDO

    + +var lastNewsBDO: String? +

    Lista link ultime news di BDO

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-patch-b-d-o.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-patch-b-d-o.html new file mode 100644 index 0000000..d01e519 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-link/last-patch-b-d-o.html @@ -0,0 +1,15 @@ + + + +RSSLink.lastPatchBDO - + + + +it.discordbot.beans / RSSLink / lastPatchBDO
    +
    +

    lastPatchBDO

    + +var lastPatchBDO: String? +

    Link ultima patch di BDO

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/-init-.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/-init-.html new file mode 100644 index 0000000..1db74d7 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/-init-.html @@ -0,0 +1,16 @@ + + + +RSSMessage.<init> - + + + +it.discordbot.beans / RSSMessage / <init>
    +
    +

    <init>

    + +RSSMessage(title: String, link: String, doc: Document) +

    Constructor
    +

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/doc.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/doc.html new file mode 100644 index 0000000..ee6b12a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/doc.html @@ -0,0 +1,18 @@ + + + +RSSMessage.doc - + + + +it.discordbot.beans / RSSMessage / doc
    +
    +

    doc

    + +val doc: Document +

    Document Contenuto del messaggio

    +

    Property

    +

    +doc - Document Contenuto del messaggio

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/index.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/index.html new file mode 100644 index 0000000..bea9dc8 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/index.html @@ -0,0 +1,58 @@ + + + +RSSMessage - + + + +it.discordbot.beans / RSSMessage
    +
    +

    RSSMessage

    +data class RSSMessage +

    Classe che contiene le informazioni utili dei messaggi RSS

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +RSSMessage(title: String, link: String, doc: Document)
    +

    Properties

    + + + + + + + + + + + + + + + +
    +

    doc

    +
    +val doc: Document +

    Document Contenuto del messaggio

    +
    +

    link

    +
    +val link: String +

    String Link del messaggio per il titolo

    +
    +

    title

    +
    +val title: String +

    String Titolo del messaggio

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/link.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/link.html new file mode 100644 index 0000000..59b0711 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/link.html @@ -0,0 +1,18 @@ + + + +RSSMessage.link - + + + +it.discordbot.beans / RSSMessage / link
    +
    +

    link

    + +val link: String +

    String Link del messaggio per il titolo

    +

    Property

    +

    +link - String Link del messaggio per il titolo

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/title.html b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/title.html new file mode 100644 index 0000000..854933b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-r-s-s-message/title.html @@ -0,0 +1,18 @@ + + + +RSSMessage.title - + + + +it.discordbot.beans / RSSMessage / title
    +
    +

    title

    + +val title: String +

    String Titolo del messaggio

    +

    Property

    +

    +title - String Titolo del messaggio

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-discord/-init-.html b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/-init-.html new file mode 100644 index 0000000..c62073f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/-init-.html @@ -0,0 +1,15 @@ + + + +ServerDiscord.<init> - + + + +it.discordbot.beans / ServerDiscord / <init>
    +
    +

    <init>

    + +ServerDiscord() +

    Entità che rappresenta la tabella dei Server Discord

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-discord/atm-alert-i-d-channel.html b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/atm-alert-i-d-channel.html new file mode 100644 index 0000000..391ce8a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/atm-alert-i-d-channel.html @@ -0,0 +1,15 @@ + + + +ServerDiscord.atmAlertIDChannel - + + + +it.discordbot.beans / ServerDiscord / atmAlertIDChannel
    +
    +

    atmAlertIDChannel

    + +var atmAlertIDChannel: String? +

    ID Canale per invio degli alert dell'ATM

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-boss-i-d-channel.html b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-boss-i-d-channel.html new file mode 100644 index 0000000..11d5bf8 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-boss-i-d-channel.html @@ -0,0 +1,15 @@ + + + +ServerDiscord.bdoBossIDChannel - + + + +it.discordbot.beans / ServerDiscord / bdoBossIDChannel
    +
    +

    bdoBossIDChannel

    + +var bdoBossIDChannel: String? +

    ID Canale per invio alert boss di BDO

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-news-i-d-channel.html b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-news-i-d-channel.html new file mode 100644 index 0000000..dd35453 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-news-i-d-channel.html @@ -0,0 +1,15 @@ + + + +ServerDiscord.bdoNewsIDChannel - + + + +it.discordbot.beans / ServerDiscord / bdoNewsIDChannel
    +
    +

    bdoNewsIDChannel

    + +var bdoNewsIDChannel: String? +

    ID Canale per invio news di BDO

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-patch-i-d-channel.html b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-patch-i-d-channel.html new file mode 100644 index 0000000..92c1ff5 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/bdo-patch-i-d-channel.html @@ -0,0 +1,15 @@ + + + +ServerDiscord.bdoPatchIDChannel - + + + +it.discordbot.beans / ServerDiscord / bdoPatchIDChannel
    +
    +

    bdoPatchIDChannel

    + +var bdoPatchIDChannel: String? +

    ID Canale per invio patch di BDO

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-discord/index.html b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/index.html new file mode 100644 index 0000000..906f894 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/index.html @@ -0,0 +1,96 @@ + + + +ServerDiscord - + + + +it.discordbot.beans / ServerDiscord
    +
    +

    ServerDiscord

    +@Entity class ServerDiscord +

    Entità che rappresenta la tabella dei Server Discord

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +ServerDiscord() +

    Entità che rappresenta la tabella dei Server Discord

    +
    +

    Properties

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    atmAlertIDChannel

    +
    +var atmAlertIDChannel: String? +

    ID Canale per invio degli alert dell'ATM

    +
    +

    bdoBossIDChannel

    +
    +var bdoBossIDChannel: String? +

    ID Canale per invio alert boss di BDO

    +
    +

    bdoNewsIDChannel

    +
    +var bdoNewsIDChannel: String? +

    ID Canale per invio news di BDO

    +
    +

    bdoPatchIDChannel

    +
    +var bdoPatchIDChannel: String? +

    ID Canale per invio patch di BDO

    +
    +

    nameServer

    +
    +var nameServer: String? +

    Nome del server

    +
    +

    serverId

    +
    +var serverId: String? +

    Id del server

    +
    +

    simbolCommand

    +
    +var simbolCommand: String? +

    Simbolo di comando

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-discord/name-server.html b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/name-server.html new file mode 100644 index 0000000..a32895a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/name-server.html @@ -0,0 +1,15 @@ + + + +ServerDiscord.nameServer - + + + +it.discordbot.beans / ServerDiscord / nameServer
    +
    +

    nameServer

    + +var nameServer: String? +

    Nome del server

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-discord/server-id.html b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/server-id.html new file mode 100644 index 0000000..bddfb6f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/server-id.html @@ -0,0 +1,15 @@ + + + +ServerDiscord.serverId - + + + +it.discordbot.beans / ServerDiscord / serverId
    +
    +

    serverId

    + +var serverId: String? +

    Id del server

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-discord/simbol-command.html b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/simbol-command.html new file mode 100644 index 0000000..a2a2d5a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-discord/simbol-command.html @@ -0,0 +1,15 @@ + + + +ServerDiscord.simbolCommand - + + + +it.discordbot.beans / ServerDiscord / simbolCommand
    +
    +

    simbolCommand

    + +var simbolCommand: String? +

    Simbolo di comando

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/-init-.html b/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/-init-.html new file mode 100644 index 0000000..3cd3a11 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/-init-.html @@ -0,0 +1,16 @@ + + + +ServerToChannel.<init> - + + + +it.discordbot.beans / ServerToChannel / <init>
    +
    +

    <init>

    + +ServerToChannel(serverID: String, channelID: String) +

    Constructor
    +

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/channel-i-d.html b/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/channel-i-d.html new file mode 100644 index 0000000..ab3ecb0 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/channel-i-d.html @@ -0,0 +1,18 @@ + + + +ServerToChannel.channelID - + + + +it.discordbot.beans / ServerToChannel / channelID
    +
    +

    channelID

    + +val channelID: String +

    String id del canale

    +

    Property

    +

    +channelID - String id del canale

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/equals.html b/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/equals.html new file mode 100644 index 0000000..73a3612 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/equals.html @@ -0,0 +1,14 @@ + + + +ServerToChannel.equals - + + + +it.discordbot.beans / ServerToChannel / equals
    +
    +

    equals

    + +fun equals(other: Any?): Boolean + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/index.html b/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/index.html new file mode 100644 index 0000000..e428374 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/index.html @@ -0,0 +1,62 @@ + + + +ServerToChannel - + + + +it.discordbot.beans / ServerToChannel
    +
    +

    ServerToChannel

    +data class ServerToChannel +

    Classe contenitore degli id dei server e relativi canali per +le pubblicazioni schedulate

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +ServerToChannel(serverID: String, channelID: String)
    +

    Properties

    + + + + + + + + + + + +
    +

    channelID

    +
    +val channelID: String +

    String id del canale

    +
    +

    serverID

    +
    +val serverID: String +

    String id del server

    +
    +

    Functions

    + + + + + + + +
    +

    equals

    +
    +fun equals(other: Any?): Boolean
    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/server-i-d.html b/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/server-i-d.html new file mode 100644 index 0000000..4997304 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/-server-to-channel/server-i-d.html @@ -0,0 +1,18 @@ + + + +ServerToChannel.serverID - + + + +it.discordbot.beans / ServerToChannel / serverID
    +
    +

    serverID

    + +val serverID: String +

    String id del server

    +

    Property

    +

    +serverID - String id del server

    + + diff --git a/docs/page/kotlindoc/it.discordbot.beans/index.html b/docs/page/kotlindoc/it.discordbot.beans/index.html new file mode 100644 index 0000000..5eec5d6 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.beans/index.html @@ -0,0 +1,54 @@ + + + +it.discordbot.beans - + + + +it.discordbot.beans
    +
    +

    Package it.discordbot.beans

    +

    Types

    + + + + + + + + + + + + + + + + + + + +
    +

    RSSLink

    +
    +class RSSLink +

    Entità che rappresenta la tabella contenitore dei link RSS

    +
    +

    RSSMessage

    +
    +data class RSSMessage +

    Classe che contiene le informazioni utili dei messaggi RSS

    +
    +

    ServerDiscord

    +
    +class ServerDiscord +

    Entità che rappresenta la tabella dei Server Discord

    +
    +

    ServerToChannel

    +
    +data class ServerToChannel +

    Classe contenitore degli id dei server e relativi canali per +le pubblicazioni schedulate

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/-init-.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/-init-.html new file mode 100644 index 0000000..833689c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/-init-.html @@ -0,0 +1,15 @@ + + + +BDONewsRSSScheduler.<init> - + + + +it.discordbot.command.BDO.RSS / BDONewsRSSScheduler / <init>
    +
    +

    <init>

    + +BDONewsRSSScheduler() +

    Classe per la schedulaziooe dei messaggi di news di BDO

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/bdo-news-interface.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/bdo-news-interface.html new file mode 100644 index 0000000..598d71c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/bdo-news-interface.html @@ -0,0 +1,18 @@ + + + +BDONewsRSSScheduler.bdoNewsInterface - + + + +it.discordbot.command.BDO.RSS / BDONewsRSSScheduler / bdoNewsInterface
    +
    +

    bdoNewsInterface

    + +lateinit var bdoNewsInterface: BDONewsInterface +

    BDONewsInterface

    +

    Property

    +

    +bdoNewsInterface - BDONewsInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/bdorss-reader.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/bdorss-reader.html new file mode 100644 index 0000000..1a4293d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/bdorss-reader.html @@ -0,0 +1,18 @@ + + + +BDONewsRSSScheduler.bdorssReader - + + + +it.discordbot.command.BDO.RSS / BDONewsRSSScheduler / bdorssReader
    +
    +

    bdorssReader

    + +lateinit var bdorssReader: BDORSSReader +

    BDORSSReader

    +

    Property

    +

    +bdorssReader - BDORSSReader

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/index.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/index.html new file mode 100644 index 0000000..8e13f0b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/index.html @@ -0,0 +1,84 @@ + + + +BDONewsRSSScheduler - + + + +it.discordbot.command.BDO.RSS / BDONewsRSSScheduler
    +
    +

    BDONewsRSSScheduler

    +@Service class BDONewsRSSScheduler : RSSScheduler +

    Classe per la schedulaziooe dei messaggi di news di BDO

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +BDONewsRSSScheduler() +

    Classe per la schedulaziooe dei messaggi di news di BDO

    +
    +

    Properties

    + + + + + + + + + + + +
    +

    bdoNewsInterface

    +
    +lateinit var bdoNewsInterface: BDONewsInterface +

    BDONewsInterface

    +
    +

    bdorssReader

    +
    +lateinit var bdorssReader: BDORSSReader +

    BDORSSReader

    +
    +

    Functions

    + + + + + + + + + + + + + + + +
    +

    procedurePublish

    +
    +fun procedurePublish(rssMessage: RSSMessage): Unit +

    Metodo per la preparazione alla pubblicazione dei messaggi RSS

    +
    +

    publishMessage

    +
    +fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList<ServerToChannel>): Unit +

    Metodo per la pubblicazione dei messaggi

    +
    +

    taskFeedRSSBDONews

    +
    +fun taskFeedRSSBDONews(): Unit +

    Task per schedulare il controllo e la pubblicazione di una +nuova news di BDO.

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/procedure-publish.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/procedure-publish.html new file mode 100644 index 0000000..bc00db9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/procedure-publish.html @@ -0,0 +1,19 @@ + + + +BDONewsRSSScheduler.procedurePublish - + + + +it.discordbot.command.BDO.RSS / BDONewsRSSScheduler / procedurePublish
    +
    +

    procedurePublish

    + +fun procedurePublish(rssMessage: RSSMessage): Unit +

    Overrides RSSScheduler.procedurePublish

    +

    Metodo per la preparazione alla pubblicazione dei messaggi RSS

    +

    Parameters

    +

    +rssMessage - RSSMessage messaggio RSS

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/publish-message.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/publish-message.html new file mode 100644 index 0000000..665c538 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/publish-message.html @@ -0,0 +1,21 @@ + + + +BDONewsRSSScheduler.publishMessage - + + + +it.discordbot.command.BDO.RSS / BDONewsRSSScheduler / publishMessage
    +
    +

    publishMessage

    + +fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList<ServerToChannel>): Unit +

    Overrides RSSScheduler.publishMessage

    +

    Metodo per la pubblicazione dei messaggi

    +

    Parameters

    +

    +message - MessageEmbed Messaggio

    +

    +serversToChannel - ArrayList Lista server e canali

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/task-feed-r-s-s-b-d-o-news.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/task-feed-r-s-s-b-d-o-news.html new file mode 100644 index 0000000..b943579 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-news-r-s-s-scheduler/task-feed-r-s-s-b-d-o-news.html @@ -0,0 +1,17 @@ + + + +BDONewsRSSScheduler.taskFeedRSSBDONews - + + + +it.discordbot.command.BDO.RSS / BDONewsRSSScheduler / taskFeedRSSBDONews
    +
    +

    taskFeedRSSBDONews

    + +@Scheduled(1800000, 1800000) fun taskFeedRSSBDONews(): Unit +

    Task per schedulare il controllo e la pubblicazione di una +nuova news di BDO.

    +

    Il controllo è fatto ogni 30 minuti.

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/-init-.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/-init-.html new file mode 100644 index 0000000..3f956ac --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/-init-.html @@ -0,0 +1,14 @@ + + + +BDOPatchRSSScheduler.<init> - + + + +it.discordbot.command.BDO.RSS / BDOPatchRSSScheduler / <init>
    +
    +

    <init>

    + +BDOPatchRSSScheduler() + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/bdo-patch-interface.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/bdo-patch-interface.html new file mode 100644 index 0000000..68faf9c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/bdo-patch-interface.html @@ -0,0 +1,14 @@ + + + +BDOPatchRSSScheduler.bdoPatchInterface - + + + +it.discordbot.command.BDO.RSS / BDOPatchRSSScheduler / bdoPatchInterface
    +
    +

    bdoPatchInterface

    + +lateinit var bdoPatchInterface: BDOPatchInterface + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/bdorss-reader.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/bdorss-reader.html new file mode 100644 index 0000000..54b35eb --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/bdorss-reader.html @@ -0,0 +1,14 @@ + + + +BDOPatchRSSScheduler.bdorssReader - + + + +it.discordbot.command.BDO.RSS / BDOPatchRSSScheduler / bdorssReader
    +
    +

    bdorssReader

    + +lateinit var bdorssReader: BDORSSReader + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/index.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/index.html new file mode 100644 index 0000000..2bb5d7c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/index.html @@ -0,0 +1,74 @@ + + + +BDOPatchRSSScheduler - + + + +it.discordbot.command.BDO.RSS / BDOPatchRSSScheduler
    +
    +

    BDOPatchRSSScheduler

    +@Service class BDOPatchRSSScheduler : RSSScheduler +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +BDOPatchRSSScheduler()
    +

    Properties

    + + + + + + + + + + + +
    +

    bdoPatchInterface

    +
    +lateinit var bdoPatchInterface: BDOPatchInterface
    +

    bdorssReader

    +
    +lateinit var bdorssReader: BDORSSReader
    +

    Functions

    + + + + + + + + + + + + + + + +
    +

    procedurePublish

    +
    +fun procedurePublish(rssMessage: RSSMessage): Unit +

    Metodo per la preparazione alla pubblicazione dei messaggi RSS

    +
    +

    publishMessage

    +
    +fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList<ServerToChannel>): Unit +

    Metodo per la pubblicazione dei messaggi

    +
    +

    taskFeedRSSBDOPatch

    +
    +fun taskFeedRSSBDOPatch(): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/procedure-publish.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/procedure-publish.html new file mode 100644 index 0000000..3408671 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/procedure-publish.html @@ -0,0 +1,19 @@ + + + +BDOPatchRSSScheduler.procedurePublish - + + + +it.discordbot.command.BDO.RSS / BDOPatchRSSScheduler / procedurePublish
    +
    +

    procedurePublish

    + +fun procedurePublish(rssMessage: RSSMessage): Unit +

    Overrides RSSScheduler.procedurePublish

    +

    Metodo per la preparazione alla pubblicazione dei messaggi RSS

    +

    Parameters

    +

    +rssMessage - RSSMessage messaggio RSS

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/publish-message.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/publish-message.html new file mode 100644 index 0000000..9da8056 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/publish-message.html @@ -0,0 +1,21 @@ + + + +BDOPatchRSSScheduler.publishMessage - + + + +it.discordbot.command.BDO.RSS / BDOPatchRSSScheduler / publishMessage
    +
    +

    publishMessage

    + +fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList<ServerToChannel>): Unit +

    Overrides RSSScheduler.publishMessage

    +

    Metodo per la pubblicazione dei messaggi

    +

    Parameters

    +

    +message - MessageEmbed Messaggio

    +

    +serversToChannel - ArrayList Lista server e canali

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/task-feed-r-s-s-b-d-o-patch.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/task-feed-r-s-s-b-d-o-patch.html new file mode 100644 index 0000000..4e69493 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-patch-r-s-s-scheduler/task-feed-r-s-s-b-d-o-patch.html @@ -0,0 +1,14 @@ + + + +BDOPatchRSSScheduler.taskFeedRSSBDOPatch - + + + +it.discordbot.command.BDO.RSS / BDOPatchRSSScheduler / taskFeedRSSBDOPatch
    +
    +

    taskFeedRSSBDOPatch

    + +@Scheduled(1800000, 1800000) fun taskFeedRSSBDOPatch(): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/-init-.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/-init-.html new file mode 100644 index 0000000..f54ea6d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/-init-.html @@ -0,0 +1,15 @@ + + + +BDORSSReader.<init> - + + + +it.discordbot.command.BDO.RSS / BDORSSReader / <init>
    +
    +

    <init>

    + +BDORSSReader() +

    Classe per leggere gli RSS di BDO

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/index.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/index.html new file mode 100644 index 0000000..c9ebd03 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/index.html @@ -0,0 +1,66 @@ + + + +BDORSSReader - + + + +it.discordbot.command.BDO.RSS / BDORSSReader
    +
    +

    BDORSSReader

    +@Scope("singleton") @Component class BDORSSReader : RSSReader +

    Classe per leggere gli RSS di BDO

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +BDORSSReader() +

    Classe per leggere gli RSS di BDO

    +
    +

    Functions

    + + + + + + + + + + + + + + + + + + + +
    +

    isNew

    +
    +fun isNew(linkRSS: String, linkDB: String): Boolean +

    Metodo per confrontare se una news o una patch di BDO è nuova +rispetto all'ultima pubblicata dal bot

    +
    +

    linkNumberParser

    +
    +fun linkNumberParser(link: String): Int
    +

    prepareRSStoMessageEmbed

    +
    +fun prepareRSStoMessageEmbed(message: RSSMessage): MessageEmbed
    +

    readRSS

    +
    +fun readRSS(url: String): RSSMessage +

    Metodo per leggere un feed RSS

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/is-new.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/is-new.html new file mode 100644 index 0000000..7c8ed83 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/is-new.html @@ -0,0 +1,23 @@ + + + +BDORSSReader.isNew - + + + +it.discordbot.command.BDO.RSS / BDORSSReader / isNew
    +
    +

    isNew

    + +fun isNew(linkRSS: String, linkDB: String): Boolean +

    Metodo per confrontare se una news o una patch di BDO è nuova +rispetto all'ultima pubblicata dal bot

    +

    Parameters

    +

    +linkRSS - String

    +

    +linkDB - String

    +

    Return
    +Boolean

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/link-number-parser.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/link-number-parser.html new file mode 100644 index 0000000..1405d80 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/link-number-parser.html @@ -0,0 +1,14 @@ + + + +BDORSSReader.linkNumberParser - + + + +it.discordbot.command.BDO.RSS / BDORSSReader / linkNumberParser
    +
    +

    linkNumberParser

    + +private fun linkNumberParser(link: String): Int + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/prepare-r-s-sto-message-embed.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/prepare-r-s-sto-message-embed.html new file mode 100644 index 0000000..06c6db0 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/prepare-r-s-sto-message-embed.html @@ -0,0 +1,15 @@ + + + +BDORSSReader.prepareRSStoMessageEmbed - + + + +it.discordbot.command.BDO.RSS / BDORSSReader / prepareRSStoMessageEmbed
    +
    +

    prepareRSStoMessageEmbed

    + +fun prepareRSStoMessageEmbed(message: RSSMessage): MessageEmbed +

    Overrides RSSReader.prepareRSStoMessageEmbed

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/read-r-s-s.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/read-r-s-s.html new file mode 100644 index 0000000..6b05fca --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/-b-d-o-r-s-s-reader/read-r-s-s.html @@ -0,0 +1,21 @@ + + + +BDORSSReader.readRSS - + + + +it.discordbot.command.BDO.RSS / BDORSSReader / readRSS
    +
    +

    readRSS

    + +fun readRSS(url: String): RSSMessage +

    Overrides RSSReader.readRSS

    +

    Metodo per leggere un feed RSS

    +

    Parameters

    +

    +url - Url da cui bisogna leggere il feed

    +

    Return
    +Ultimo feed registrato

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/index.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/index.html new file mode 100644 index 0000000..04ac653 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.-r-s-s/index.html @@ -0,0 +1,42 @@ + + + +it.discordbot.command.BDO.RSS - + + + +it.discordbot.command.BDO.RSS
    +
    +

    Package it.discordbot.command.BDO.RSS

    +

    Types

    + + + + + + + + + + + + + + + +
    +

    BDONewsRSSScheduler

    +
    +class BDONewsRSSScheduler : RSSScheduler +

    Classe per la schedulaziooe dei messaggi di news di BDO

    +
    +

    BDOPatchRSSScheduler

    +
    +class BDOPatchRSSScheduler : RSSScheduler
    +

    BDORSSReader

    +
    +class BDORSSReader : RSSReader +

    Classe per leggere gli RSS di BDO

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/-init-.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/-init-.html new file mode 100644 index 0000000..c94b4a5 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/-init-.html @@ -0,0 +1,15 @@ + + + +BDOBossScheduler.<init> - + + + +it.discordbot.command.BDO.boss / BDOBossScheduler / <init>
    +
    +

    <init>

    + +BDOBossScheduler() +

    Classe per la schedulazione dei boss

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/bdo-boss-interface.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/bdo-boss-interface.html new file mode 100644 index 0000000..feae5a7 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/bdo-boss-interface.html @@ -0,0 +1,18 @@ + + + +BDOBossScheduler.bdoBossInterface - + + + +it.discordbot.command.BDO.boss / BDOBossScheduler / bdoBossInterface
    +
    +

    bdoBossInterface

    + +lateinit var bdoBossInterface: BDOBossInterface +

    BDOBossInterface

    +

    Property

    +

    +bdoBossInterface - BDOBossInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/boss-job.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/boss-job.html new file mode 100644 index 0000000..74fdcb4 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/boss-job.html @@ -0,0 +1,15 @@ + + + +BDOBossScheduler.bossJob - + + + +it.discordbot.command.BDO.boss / BDOBossScheduler / bossJob
    +
    +

    bossJob

    + +@Scheduled("0 0/5 * * * *") fun bossJob(): Unit +

    Job per la schedulazione dei boss

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/boss-util.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/boss-util.html new file mode 100644 index 0000000..c78e5be --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/boss-util.html @@ -0,0 +1,18 @@ + + + +BDOBossScheduler.bossUtil - + + + +it.discordbot.command.BDO.boss / BDOBossScheduler / bossUtil
    +
    +

    bossUtil

    + +lateinit var bossUtil: BossUtil +

    BossUtil

    +

    Property

    +

    +bossUtil - BossUtil

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/index.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/index.html new file mode 100644 index 0000000..54341ba --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-b-d-o-boss-scheduler/index.html @@ -0,0 +1,65 @@ + + + +BDOBossScheduler - + + + +it.discordbot.command.BDO.boss / BDOBossScheduler
    +
    +

    BDOBossScheduler

    +@Scope("singleton") @Service class BDOBossScheduler +

    Classe per la schedulazione dei boss

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +BDOBossScheduler() +

    Classe per la schedulazione dei boss

    +
    +

    Properties

    + + + + + + + + + + + +
    +

    bdoBossInterface

    +
    +lateinit var bdoBossInterface: BDOBossInterface +

    BDOBossInterface

    +
    +

    bossUtil

    +
    +lateinit var bossUtil: BossUtil +

    BossUtil

    +
    +

    Functions

    + + + + + + + +
    +

    bossJob

    +
    +fun bossJob(): Unit +

    Job per la schedulazione dei boss

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/-init-.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/-init-.html new file mode 100644 index 0000000..cf6ddea --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/-init-.html @@ -0,0 +1,15 @@ + + + +BossUtil.<init> - + + + +it.discordbot.command.BDO.boss / BossUtil / <init>
    +
    +

    <init>

    + +BossUtil() +

    Classe per processare i boss e ricavare il boss da notificare

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/bdo-boss-interface.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/bdo-boss-interface.html new file mode 100644 index 0000000..be086c9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/bdo-boss-interface.html @@ -0,0 +1,18 @@ + + + +BossUtil.bdoBossInterface - + + + +it.discordbot.command.BDO.boss / BossUtil / bdoBossInterface
    +
    +

    bdoBossInterface

    + +lateinit var bdoBossInterface: BDOBossInterface +

    BDOBossInterface

    +

    Property

    +

    +bdoBossInterface - BDOBossInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/get-day-bosses.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/get-day-bosses.html new file mode 100644 index 0000000..3844918 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/get-day-bosses.html @@ -0,0 +1,22 @@ + + + +BossUtil.getDayBosses - + + + +it.discordbot.command.BDO.boss / BossUtil / getDayBosses
    +
    +

    getDayBosses

    + +fun getDayBosses(giorno: String, list: ArrayList<Giorno>): Giorno? +

    Metodo per ottenere il Giorno

    +

    Parameters

    +

    +giorno - String nome della giornata corrente in inglese e maiuscolo

    +

    +list - ArrayList lista dei Giorno

    +

    Return
    +Giorno? Giorno attuale

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/get-hour-boss.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/get-hour-boss.html new file mode 100644 index 0000000..0e45150 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/get-hour-boss.html @@ -0,0 +1,24 @@ + + + +BossUtil.getHourBoss - + + + +it.discordbot.command.BDO.boss / BossUtil / getHourBoss
    +
    +

    getHourBoss

    + +private fun getHourBoss(ora: Int, minuto: Int, list: ArrayList<Boss>?): Boss? +

    Metodo per ottenere Boss

    +

    Parameters

    +

    +ora - Int ora per ricavare il boss

    +

    +minuto - Int minuti per ricavare il boss

    +

    +list - ArrayList? lista dei Boss di giornata

    +

    Return
    +Boss? Boss prossimo allo spawn

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/index.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/index.html new file mode 100644 index 0000000..6599716 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/index.html @@ -0,0 +1,101 @@ + + + +BossUtil - + + + +it.discordbot.command.BDO.boss / BossUtil
    +
    +

    BossUtil

    +@Scope("singleton") @Component class BossUtil +

    Classe per processare i boss e ricavare il boss da notificare

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +BossUtil() +

    Classe per processare i boss e ricavare il boss da notificare

    +
    +

    Properties

    + + + + + + + +
    +

    bdoBossInterface

    +
    +lateinit var bdoBossInterface: BDOBossInterface +

    BDOBossInterface

    +
    +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    getDayBosses

    +
    +fun getDayBosses(giorno: String, list: ArrayList<Giorno>): Giorno? +

    Metodo per ottenere il Giorno

    +
    +

    getHourBoss

    +
    +fun getHourBoss(ora: Int, minuto: Int, list: ArrayList<Boss>?): Boss? +

    Metodo per ottenere Boss

    +
    +

    processMinute0015

    +
    +fun processMinute0015(ora: Int, minuto: Int, giorno: Giorno?): Unit +

    Metodo per schedulare i boss che spawnano alle 15 dell'ora

    +
    +

    processMinute4500

    +
    +fun processMinute4500(ora: Int, minuto: Int, giorno: Giorno?): Unit +

    Metodo per schedulare i boss che spawnano alle 00 dell'ora successiva

    +
    +

    publish

    +
    +fun publish(bosses: Array<String>?, orarioMancante: String): Unit +

    Metodo per la pubblicazione effettiva del messaggio

    +
    +

    publishBoss

    +
    +fun publishBoss(ora: Int, minuto: Int, giorno: Giorno?): Unit +

    Metodo per iniziare la pubblicazione del boss

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-hour.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-hour.html new file mode 100644 index 0000000..42fb204 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-hour.html @@ -0,0 +1,14 @@ + + + +BossUtil.processHour - + + + +it.discordbot.command.BDO.boss / BossUtil / processHour
    +
    +

    processHour

    + +fun processHour(ora: Int, minuto: Int, giorno: Giorno?): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-minute0015.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-minute0015.html new file mode 100644 index 0000000..d0277b8 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-minute0015.html @@ -0,0 +1,22 @@ + + + +BossUtil.processMinute0015 - + + + +it.discordbot.command.BDO.boss / BossUtil / processMinute0015
    +
    +

    processMinute0015

    + +private fun processMinute0015(ora: Int, minuto: Int, giorno: Giorno?): Unit +

    Metodo per schedulare i boss che spawnano alle 15 dell'ora

    +

    Parameters

    +

    +ora - Int ora attuale

    +

    +minuto - Int minuti attuali

    +

    +giorno - Giorno? Giorno attuale

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-minute4500.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-minute4500.html new file mode 100644 index 0000000..27236e1 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/process-minute4500.html @@ -0,0 +1,22 @@ + + + +BossUtil.processMinute4500 - + + + +it.discordbot.command.BDO.boss / BossUtil / processMinute4500
    +
    +

    processMinute4500

    + +private fun processMinute4500(ora: Int, minuto: Int, giorno: Giorno?): Unit +

    Metodo per schedulare i boss che spawnano alle 00 dell'ora successiva

    +

    Parameters

    +

    +ora - Int ora attuale

    +

    +minuto - Int minuti attuali

    +

    +giorno - Giorno? Giorno attuale

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/publish-boss.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/publish-boss.html new file mode 100644 index 0000000..547b0c8 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/publish-boss.html @@ -0,0 +1,22 @@ + + + +BossUtil.publishBoss - + + + +it.discordbot.command.BDO.boss / BossUtil / publishBoss
    +
    +

    publishBoss

    + +fun publishBoss(ora: Int, minuto: Int, giorno: Giorno?): Unit +

    Metodo per iniziare la pubblicazione del boss

    +

    Parameters

    +

    +ora - Int ora attuale

    +

    +minuto - Int minuti attuali

    +

    +giorno - Giorno? Giorno attuale

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/publish.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/publish.html new file mode 100644 index 0000000..ca762ef --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/-boss-util/publish.html @@ -0,0 +1,20 @@ + + + +BossUtil.publish - + + + +it.discordbot.command.BDO.boss / BossUtil / publish
    +
    +

    publish

    + +private fun publish(bosses: Array<String>?, orarioMancante: String): Unit +

    Metodo per la pubblicazione effettiva del messaggio

    +

    Parameters

    +

    +bosses - Array? lista nomi dei boss

    +

    +orarioMancante - String tempo mancante allo spawn del boss

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/index.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/index.html new file mode 100644 index 0000000..45ec27e --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o.boss/index.html @@ -0,0 +1,35 @@ + + + +it.discordbot.command.BDO.boss - + + + +it.discordbot.command.BDO.boss
    +
    +

    Package it.discordbot.command.BDO.boss

    +

    Types

    + + + + + + + + + + + +
    +

    BDOBossScheduler

    +
    +class BDOBossScheduler +

    Classe per la schedulazione dei boss

    +
    +

    BossUtil

    +
    +class BossUtil +

    Classe per processare i boss e ricavare il boss da notificare

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-a-r-t_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-a-r-t_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..d42ea1f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-a-r-t_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_BOSS_START_COMMAND - + + + +it.discordbot.command.BDO / BDOCommand / BDO_BOSS_START_COMMAND
    +
    +

    BDO_BOSS_START_COMMAND

    + +const val BDO_BOSS_START_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html new file mode 100644 index 0000000..70cd246 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_BOSS_START_COMMAND_DESCRIPTION - + + + +it.discordbot.command.BDO / BDOCommand / BDO_BOSS_START_COMMAND_DESCRIPTION
    +
    +

    BDO_BOSS_START_COMMAND_DESCRIPTION

    + +const val BDO_BOSS_START_COMMAND_DESCRIPTION: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-o-p_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-o-p_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..95e0253 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-o-p_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_BOSS_STOP_COMMAND - + + + +it.discordbot.command.BDO / BDOCommand / BDO_BOSS_STOP_COMMAND
    +
    +

    BDO_BOSS_STOP_COMMAND

    + +const val BDO_BOSS_STOP_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html new file mode 100644 index 0000000..bf459f4 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-b-o-s-s_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_BOSS_STOP_COMMAND_DESCRIPTION - + + + +it.discordbot.command.BDO / BDOCommand / BDO_BOSS_STOP_COMMAND_DESCRIPTION
    +
    +

    BDO_BOSS_STOP_COMMAND_DESCRIPTION

    + +const val BDO_BOSS_STOP_COMMAND_DESCRIPTION: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-a-r-t_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-a-r-t_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..7f853da --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-a-r-t_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_NEWS_START_COMMAND - + + + +it.discordbot.command.BDO / BDOCommand / BDO_NEWS_START_COMMAND
    +
    +

    BDO_NEWS_START_COMMAND

    + +const val BDO_NEWS_START_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html new file mode 100644 index 0000000..2950c57 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_NEWS_START_COMMAND_DESCRIPTION - + + + +it.discordbot.command.BDO / BDOCommand / BDO_NEWS_START_COMMAND_DESCRIPTION
    +
    +

    BDO_NEWS_START_COMMAND_DESCRIPTION

    + +const val BDO_NEWS_START_COMMAND_DESCRIPTION: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-o-p_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-o-p_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..68b0251 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-o-p_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_NEWS_STOP_COMMAND - + + + +it.discordbot.command.BDO / BDOCommand / BDO_NEWS_STOP_COMMAND
    +
    +

    BDO_NEWS_STOP_COMMAND

    + +const val BDO_NEWS_STOP_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html new file mode 100644 index 0000000..d945a25 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-n-e-w-s_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_NEWS_STOP_COMMAND_DESCRIPTION - + + + +it.discordbot.command.BDO / BDOCommand / BDO_NEWS_STOP_COMMAND_DESCRIPTION
    +
    +

    BDO_NEWS_STOP_COMMAND_DESCRIPTION

    + +const val BDO_NEWS_STOP_COMMAND_DESCRIPTION: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-a-r-t_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-a-r-t_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..f22d79e --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-a-r-t_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_PATCH_START_COMMAND - + + + +it.discordbot.command.BDO / BDOCommand / BDO_PATCH_START_COMMAND
    +
    +

    BDO_PATCH_START_COMMAND

    + +const val BDO_PATCH_START_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html new file mode 100644 index 0000000..c43d14c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_PATCH_START_COMMAND_DESCRIPTION - + + + +it.discordbot.command.BDO / BDOCommand / BDO_PATCH_START_COMMAND_DESCRIPTION
    +
    +

    BDO_PATCH_START_COMMAND_DESCRIPTION

    + +const val BDO_PATCH_START_COMMAND_DESCRIPTION: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-o-p_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-o-p_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..3b14744 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-o-p_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_PATCH_STOP_COMMAND - + + + +it.discordbot.command.BDO / BDOCommand / BDO_PATCH_STOP_COMMAND
    +
    +

    BDO_PATCH_STOP_COMMAND

    + +const val BDO_PATCH_STOP_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html new file mode 100644 index 0000000..8f7a0f7 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-b-d-o_-p-a-t-c-h_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html @@ -0,0 +1,14 @@ + + + +BDOCommand.BDO_PATCH_STOP_COMMAND_DESCRIPTION - + + + +it.discordbot.command.BDO / BDOCommand / BDO_PATCH_STOP_COMMAND_DESCRIPTION
    +
    +

    BDO_PATCH_STOP_COMMAND_DESCRIPTION

    + +const val BDO_PATCH_STOP_COMMAND_DESCRIPTION: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-init-.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-init-.html new file mode 100644 index 0000000..aa752c7 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/-init-.html @@ -0,0 +1,15 @@ + + + +BDOCommand.<init> - + + + +it.discordbot.command.BDO / BDOCommand / <init>
    +
    +

    <init>

    + +BDOCommand() +

    Listener per contenere i comandi di BDO

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-boss-interface.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-boss-interface.html new file mode 100644 index 0000000..6f8842d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-boss-interface.html @@ -0,0 +1,18 @@ + + + +BDOCommand.bdoBossInterface - + + + +it.discordbot.command.BDO / BDOCommand / bdoBossInterface
    +
    +

    bdoBossInterface

    + +lateinit var bdoBossInterface: BDOBossInterface +

    BDOBossInterface

    +

    Property

    +

    +bdoBossInterface - BDOBossInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-news-interface.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-news-interface.html new file mode 100644 index 0000000..e47955b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-news-interface.html @@ -0,0 +1,18 @@ + + + +BDOCommand.bdoNewsInterface - + + + +it.discordbot.command.BDO / BDOCommand / bdoNewsInterface
    +
    +

    bdoNewsInterface

    + +lateinit var bdoNewsInterface: BDONewsInterface +

    BDONewsInterface

    +

    Property

    +

    +bdoNewsInterface - BDONewsInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-patch-interface.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-patch-interface.html new file mode 100644 index 0000000..98aba96 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/bdo-patch-interface.html @@ -0,0 +1,18 @@ + + + +BDOCommand.bdoPatchInterface - + + + +it.discordbot.command.BDO / BDOCommand / bdoPatchInterface
    +
    +

    bdoPatchInterface

    + +lateinit var bdoPatchInterface: BDOPatchInterface +

    BDOPatchInterface

    +

    Property

    +

    +bdoPatchInterface - BDOPatchInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/index.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/index.html new file mode 100644 index 0000000..60041b7 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/index.html @@ -0,0 +1,184 @@ + + + +BDOCommand - + + + +it.discordbot.command.BDO / BDOCommand
    +
    +

    BDOCommand

    +@Scope("singleton") @Service class BDOCommand : ListenerAdapter +

    Listener per contenere i comandi di BDO

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +BDOCommand() +

    Listener per contenere i comandi di BDO

    +
    +

    Properties

    + + + + + + + + + + + + + + + + + + + +
    +

    bdoBossInterface

    +
    +lateinit var bdoBossInterface: BDOBossInterface +

    BDOBossInterface

    +
    +

    bdoNewsInterface

    +
    +lateinit var bdoNewsInterface: BDONewsInterface +

    BDONewsInterface

    +
    +

    bdoPatchInterface

    +
    +lateinit var bdoPatchInterface: BDOPatchInterface +

    BDOPatchInterface

    +
    +

    serverManagementInterface

    +
    +lateinit var serverManagementInterface: ServerManagementInterface +

    ServerManagementInterface

    +
    +

    Functions

    + + + + + + + + + + + + + + + +
    +

    onMessageReceived

    +
    +fun onMessageReceived(event: MessageReceivedEvent?): Unit
    +

    sendMessageAddChannel

    +
    +fun sendMessageAddChannel(event: MessageReceivedEvent, message: String): Unit
    +

    sendMessageRemoveChannel

    +
    +fun sendMessageRemoveChannel(event: MessageReceivedEvent, message: String, channelID: String): Unit
    +

    Companion Object Properties

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    BDO_BOSS_START_COMMAND

    +
    +const val BDO_BOSS_START_COMMAND: String
    +

    BDO_BOSS_START_COMMAND_DESCRIPTION

    +
    +const val BDO_BOSS_START_COMMAND_DESCRIPTION: String
    +

    BDO_BOSS_STOP_COMMAND

    +
    +const val BDO_BOSS_STOP_COMMAND: String
    +

    BDO_BOSS_STOP_COMMAND_DESCRIPTION

    +
    +const val BDO_BOSS_STOP_COMMAND_DESCRIPTION: String
    +

    BDO_NEWS_START_COMMAND

    +
    +const val BDO_NEWS_START_COMMAND: String
    +

    BDO_NEWS_START_COMMAND_DESCRIPTION

    +
    +const val BDO_NEWS_START_COMMAND_DESCRIPTION: String
    +

    BDO_NEWS_STOP_COMMAND

    +
    +const val BDO_NEWS_STOP_COMMAND: String
    +

    BDO_NEWS_STOP_COMMAND_DESCRIPTION

    +
    +const val BDO_NEWS_STOP_COMMAND_DESCRIPTION: String
    +

    BDO_PATCH_START_COMMAND

    +
    +const val BDO_PATCH_START_COMMAND: String
    +

    BDO_PATCH_START_COMMAND_DESCRIPTION

    +
    +const val BDO_PATCH_START_COMMAND_DESCRIPTION: String
    +

    BDO_PATCH_STOP_COMMAND

    +
    +const val BDO_PATCH_STOP_COMMAND: String
    +

    BDO_PATCH_STOP_COMMAND_DESCRIPTION

    +
    +const val BDO_PATCH_STOP_COMMAND_DESCRIPTION: String
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/on-message-received.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/on-message-received.html new file mode 100644 index 0000000..668bd32 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/on-message-received.html @@ -0,0 +1,14 @@ + + + +BDOCommand.onMessageReceived - + + + +it.discordbot.command.BDO / BDOCommand / onMessageReceived
    +
    +

    onMessageReceived

    + +fun onMessageReceived(event: MessageReceivedEvent?): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/send-message-add-channel.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/send-message-add-channel.html new file mode 100644 index 0000000..f780a0b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/send-message-add-channel.html @@ -0,0 +1,14 @@ + + + +BDOCommand.sendMessageAddChannel - + + + +it.discordbot.command.BDO / BDOCommand / sendMessageAddChannel
    +
    +

    sendMessageAddChannel

    + +private fun sendMessageAddChannel(event: MessageReceivedEvent, message: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/send-message-remove-channel.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/send-message-remove-channel.html new file mode 100644 index 0000000..7417738 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/send-message-remove-channel.html @@ -0,0 +1,14 @@ + + + +BDOCommand.sendMessageRemoveChannel - + + + +it.discordbot.command.BDO / BDOCommand / sendMessageRemoveChannel
    +
    +

    sendMessageRemoveChannel

    + +private fun sendMessageRemoveChannel(event: MessageReceivedEvent, message: String, channelID: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/server-management-interface.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/server-management-interface.html new file mode 100644 index 0000000..2023bfb --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/-b-d-o-command/server-management-interface.html @@ -0,0 +1,18 @@ + + + +BDOCommand.serverManagementInterface - + + + +it.discordbot.command.BDO / BDOCommand / serverManagementInterface
    +
    +

    serverManagementInterface

    + +lateinit var serverManagementInterface: ServerManagementInterface +

    ServerManagementInterface

    +

    Property

    +

    +serverManagementInterface - ServerManagementInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.-b-d-o/index.html b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/index.html new file mode 100644 index 0000000..85650bb --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.-b-d-o/index.html @@ -0,0 +1,26 @@ + + + +it.discordbot.command.BDO - + + + +it.discordbot.command.BDO
    +
    +

    Package it.discordbot.command.BDO

    +

    Types

    + + + + + + + +
    +

    BDOCommand

    +
    +class BDOCommand : ListenerAdapter +

    Listener per contenere i comandi di BDO

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-c-o-n-f-i-g-u-r-a-t-i-o-n_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-c-o-n-f-i-g-u-r-a-t-i-o-n_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..ec31a9d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-c-o-n-f-i-g-u-r-a-t-i-o-n_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.CONFIGURATION_COMMAND - + + + +it.discordbot.command.generalCommand / GeneralCommand / CONFIGURATION_COMMAND
    +
    +

    CONFIGURATION_COMMAND

    + +const val CONFIGURATION_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-c-o-n-f-i-g-u-r-a-t-i-o-n_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-c-o-n-f-i-g-u-r-a-t-i-o-n_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html new file mode 100644 index 0000000..a0d0ba9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-c-o-n-f-i-g-u-r-a-t-i-o-n_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.CONFIGURATION_COMMAND_DESCRIPTION - + + + +it.discordbot.command.generalCommand / GeneralCommand / CONFIGURATION_COMMAND_DESCRIPTION
    +
    +

    CONFIGURATION_COMMAND_DESCRIPTION

    + +const val CONFIGURATION_COMMAND_DESCRIPTION: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-h-e-l-p_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-h-e-l-p_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..5306269 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-h-e-l-p_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.HELP_COMMAND - + + + +it.discordbot.command.generalCommand / GeneralCommand / HELP_COMMAND
    +
    +

    HELP_COMMAND

    + +const val HELP_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-h-e-l-p_-c-o-m-m-a-n-d2.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-h-e-l-p_-c-o-m-m-a-n-d2.html new file mode 100644 index 0000000..2172127 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-h-e-l-p_-c-o-m-m-a-n-d2.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.HELP_COMMAND2 - + + + +it.discordbot.command.generalCommand / GeneralCommand / HELP_COMMAND2
    +
    +

    HELP_COMMAND2

    + +const val HELP_COMMAND2: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-i-n-f-o_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-i-n-f-o_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..074b3e2 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-i-n-f-o_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.INFO_COMMAND - + + + +it.discordbot.command.generalCommand / GeneralCommand / INFO_COMMAND
    +
    +

    INFO_COMMAND

    + +const val INFO_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-i-n-f-o_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-i-n-f-o_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html new file mode 100644 index 0000000..4c74734 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-i-n-f-o_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.INFO_COMMAND_DESCRIPTION - + + + +it.discordbot.command.generalCommand / GeneralCommand / INFO_COMMAND_DESCRIPTION
    +
    +

    INFO_COMMAND_DESCRIPTION

    + +const val INFO_COMMAND_DESCRIPTION: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-init-.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-init-.html new file mode 100644 index 0000000..3949fd0 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/-init-.html @@ -0,0 +1,15 @@ + + + +GeneralCommand.<init> - + + + +it.discordbot.command.generalCommand / GeneralCommand / <init>
    +
    +

    <init>

    + +GeneralCommand() +

    Listener per contenere comandi di uso generale e di configurazione del bot

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/configure-symbol.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/configure-symbol.html new file mode 100644 index 0000000..6acd907 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/configure-symbol.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.configureSymbol - + + + +it.discordbot.command.generalCommand / GeneralCommand / configureSymbol
    +
    +

    configureSymbol

    + +private fun configureSymbol(event: MessageReceivedEvent): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-configuration-command.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-configuration-command.html new file mode 100644 index 0000000..57c38ca --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-configuration-command.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.getConfigurationCommand - + + + +it.discordbot.command.generalCommand / GeneralCommand / getConfigurationCommand
    +
    +

    getConfigurationCommand

    + +private fun getConfigurationCommand(event: MessageReceivedEvent): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-help.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-help.html new file mode 100644 index 0000000..b625840 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-help.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.getHelp - + + + +it.discordbot.command.generalCommand / GeneralCommand / getHelp
    +
    +

    getHelp

    + +private fun getHelp(serverID: String): MessageEmbed + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-info.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-info.html new file mode 100644 index 0000000..37bbff4 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/get-info.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.getInfo - + + + +it.discordbot.command.generalCommand / GeneralCommand / getInfo
    +
    +

    getInfo

    + +private fun getInfo(): MessageEmbed + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/index.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/index.html new file mode 100644 index 0000000..314625c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/index.html @@ -0,0 +1,129 @@ + + + +GeneralCommand - + + + +it.discordbot.command.generalCommand / GeneralCommand
    +
    +

    GeneralCommand

    +@Scope("singleton") @Service class GeneralCommand : ListenerAdapter +

    Listener per contenere comandi di uso generale e di configurazione del bot

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +GeneralCommand() +

    Listener per contenere comandi di uso generale e di configurazione del bot

    +
    +

    Properties

    + + + + + + + +
    +

    serverManagementInterface

    +
    +lateinit var serverManagementInterface: ServerManagementInterface +

    ServerManagementInterface

    +
    +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + +
    +

    configureSymbol

    +
    +fun configureSymbol(event: MessageReceivedEvent): Unit
    +

    getConfigurationCommand

    +
    +fun getConfigurationCommand(event: MessageReceivedEvent): Unit
    +

    getHelp

    +
    +fun getHelp(serverID: String): MessageEmbed
    +

    getInfo

    +
    +fun getInfo(): MessageEmbed
    +

    onMessageReceived

    +
    +fun onMessageReceived(event: MessageReceivedEvent?): Unit
    +

    Companion Object Properties

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    CONFIGURATION_COMMAND

    +
    +const val CONFIGURATION_COMMAND: String
    +

    CONFIGURATION_COMMAND_DESCRIPTION

    +
    +const val CONFIGURATION_COMMAND_DESCRIPTION: String
    +

    HELP_COMMAND

    +
    +const val HELP_COMMAND: String
    +

    HELP_COMMAND2

    +
    +const val HELP_COMMAND2: String
    +

    INFO_COMMAND

    +
    +const val INFO_COMMAND: String
    +

    INFO_COMMAND_DESCRIPTION

    +
    +const val INFO_COMMAND_DESCRIPTION: String
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/on-message-received.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/on-message-received.html new file mode 100644 index 0000000..adc1d65 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/on-message-received.html @@ -0,0 +1,14 @@ + + + +GeneralCommand.onMessageReceived - + + + +it.discordbot.command.generalCommand / GeneralCommand / onMessageReceived
    +
    +

    onMessageReceived

    + +fun onMessageReceived(event: MessageReceivedEvent?): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/server-management-interface.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/server-management-interface.html new file mode 100644 index 0000000..eb990f2 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-general-command/server-management-interface.html @@ -0,0 +1,18 @@ + + + +GeneralCommand.serverManagementInterface - + + + +it.discordbot.command.generalCommand / GeneralCommand / serverManagementInterface
    +
    +

    serverManagementInterface

    + +lateinit var serverManagementInterface: ServerManagementInterface +

    ServerManagementInterface

    +

    Property

    +

    +serverManagementInterface - ServerManagementInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/-init-.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/-init-.html new file mode 100644 index 0000000..59dbdb5 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/-init-.html @@ -0,0 +1,16 @@ + + + +JoinListener.<init> - + + + +it.discordbot.command.generalCommand / JoinListener / <init>
    +
    +

    <init>

    + +JoinListener() +

    Listener per contenere quando il bot entra o esce +da un server Discord

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/index.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/index.html new file mode 100644 index 0000000..a74bcfc --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/index.html @@ -0,0 +1,70 @@ + + + +JoinListener - + + + +it.discordbot.command.generalCommand / JoinListener
    +
    +

    JoinListener

    +@Scope("singleton") @Service class JoinListener : ListenerAdapter +

    Listener per contenere quando il bot entra o esce +da un server Discord

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +JoinListener() +

    Listener per contenere quando il bot entra o esce +da un server Discord

    +
    +

    Properties

    + + + + + + + +
    +

    serverManagementInterface

    +
    +lateinit var serverManagementInterface: ServerManagementInterface +

    ServerManagementInterface

    +
    +

    Functions

    + + + + + + + + + + + + + + + +
    +

    onGuildJoin

    +
    +fun onGuildJoin(event: GuildJoinEvent?): Unit
    +

    onGuildLeave

    +
    +fun onGuildLeave(event: GuildLeaveEvent?): Unit
    +

    onGuildUpdateName

    +
    +fun onGuildUpdateName(event: GuildUpdateNameEvent): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-join.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-join.html new file mode 100644 index 0000000..62a962b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-join.html @@ -0,0 +1,14 @@ + + + +JoinListener.onGuildJoin - + + + +it.discordbot.command.generalCommand / JoinListener / onGuildJoin
    +
    +

    onGuildJoin

    + +fun onGuildJoin(event: GuildJoinEvent?): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-leave.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-leave.html new file mode 100644 index 0000000..8535ca1 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-leave.html @@ -0,0 +1,14 @@ + + + +JoinListener.onGuildLeave - + + + +it.discordbot.command.generalCommand / JoinListener / onGuildLeave
    +
    +

    onGuildLeave

    + +fun onGuildLeave(event: GuildLeaveEvent?): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-update-name.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-update-name.html new file mode 100644 index 0000000..d2c4ff9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/on-guild-update-name.html @@ -0,0 +1,14 @@ + + + +JoinListener.onGuildUpdateName - + + + +it.discordbot.command.generalCommand / JoinListener / onGuildUpdateName
    +
    +

    onGuildUpdateName

    + +fun onGuildUpdateName(event: GuildUpdateNameEvent): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/server-management-interface.html b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/server-management-interface.html new file mode 100644 index 0000000..d0890a3 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/-join-listener/server-management-interface.html @@ -0,0 +1,18 @@ + + + +JoinListener.serverManagementInterface - + + + +it.discordbot.command.generalCommand / JoinListener / serverManagementInterface
    +
    +

    serverManagementInterface

    + +lateinit var serverManagementInterface: ServerManagementInterface +

    ServerManagementInterface

    +

    Property

    +

    +serverManagementInterface - ServerManagementInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.general-command/index.html b/docs/page/kotlindoc/it.discordbot.command.general-command/index.html new file mode 100644 index 0000000..cd3fb3d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.general-command/index.html @@ -0,0 +1,36 @@ + + + +it.discordbot.command.generalCommand - + + + +it.discordbot.command.generalCommand
    +
    +

    Package it.discordbot.command.generalCommand

    +

    Types

    + + + + + + + + + + + +
    +

    GeneralCommand

    +
    +class GeneralCommand : ListenerAdapter +

    Listener per contenere comandi di uso generale e di configurazione del bot

    +
    +

    JoinListener

    +
    +class JoinListener : ListenerAdapter +

    Listener per contenere quando il bot entra o esce +da un server Discord

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/-init-.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/-init-.html new file mode 100644 index 0000000..eb4374f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/-init-.html @@ -0,0 +1,14 @@ + + + +AudioPlayerSendHandler.<init> - + + + +it.discordbot.command.music.config / AudioPlayerSendHandler / <init>
    +
    +

    <init>

    + +AudioPlayerSendHandler(audioPlayer: AudioPlayer) + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/audio-player.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/audio-player.html new file mode 100644 index 0000000..eea6476 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/audio-player.html @@ -0,0 +1,14 @@ + + + +AudioPlayerSendHandler.audioPlayer - + + + +it.discordbot.command.music.config / AudioPlayerSendHandler / audioPlayer
    +
    +

    audioPlayer

    + +val audioPlayer: AudioPlayer + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/can-provide.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/can-provide.html new file mode 100644 index 0000000..b11c77b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/can-provide.html @@ -0,0 +1,14 @@ + + + +AudioPlayerSendHandler.canProvide - + + + +it.discordbot.command.music.config / AudioPlayerSendHandler / canProvide
    +
    +

    canProvide

    + +fun canProvide(): Boolean + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/index.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/index.html new file mode 100644 index 0000000..1414424 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/index.html @@ -0,0 +1,70 @@ + + + +AudioPlayerSendHandler - + + + +it.discordbot.command.music.config / AudioPlayerSendHandler
    +
    +

    AudioPlayerSendHandler

    +class AudioPlayerSendHandler : AudioSendHandler +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +AudioPlayerSendHandler(audioPlayer: AudioPlayer)
    +

    Properties

    + + + + + + + + + + + +
    +

    audioPlayer

    +
    +val audioPlayer: AudioPlayer
    +

    lastFrame

    +
    +var lastFrame: AudioFrame?
    +

    Functions

    + + + + + + + + + + + + + + + +
    +

    canProvide

    +
    +fun canProvide(): Boolean
    +

    isOpus

    +
    +fun isOpus(): Boolean
    +

    provide20MsAudio

    +
    +fun provide20MsAudio(): ByteArray?
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/is-opus.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/is-opus.html new file mode 100644 index 0000000..321aa00 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/is-opus.html @@ -0,0 +1,14 @@ + + + +AudioPlayerSendHandler.isOpus - + + + +it.discordbot.command.music.config / AudioPlayerSendHandler / isOpus
    +
    +

    isOpus

    + +fun isOpus(): Boolean + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/last-frame.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/last-frame.html new file mode 100644 index 0000000..3363abe --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/last-frame.html @@ -0,0 +1,14 @@ + + + +AudioPlayerSendHandler.lastFrame - + + + +it.discordbot.command.music.config / AudioPlayerSendHandler / lastFrame
    +
    +

    lastFrame

    + +private var lastFrame: AudioFrame? + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/provide20-ms-audio.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/provide20-ms-audio.html new file mode 100644 index 0000000..a870608 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-audio-player-send-handler/provide20-ms-audio.html @@ -0,0 +1,14 @@ + + + +AudioPlayerSendHandler.provide20MsAudio - + + + +it.discordbot.command.music.config / AudioPlayerSendHandler / provide20MsAudio
    +
    +

    provide20MsAudio

    + +fun provide20MsAudio(): ByteArray? + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/-init-.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/-init-.html new file mode 100644 index 0000000..29103c9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/-init-.html @@ -0,0 +1,14 @@ + + + +GuildMusicManager.<init> - + + + +it.discordbot.command.music.config / GuildMusicManager / <init>
    +
    +

    <init>

    + +GuildMusicManager(manager: AudioPlayerManager) + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/index.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/index.html new file mode 100644 index 0000000..ae04d9c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/index.html @@ -0,0 +1,58 @@ + + + +GuildMusicManager - + + + +it.discordbot.command.music.config / GuildMusicManager
    +
    +

    GuildMusicManager

    +class GuildMusicManager +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +GuildMusicManager(manager: AudioPlayerManager)
    +

    Properties

    + + + + + + + + + + + + + + + + + + + +
    +

    manager

    +
    +val manager: AudioPlayerManager
    +

    player

    +
    +var player: AudioPlayer
    +

    scheduler

    +
    +var scheduler: TrackScheduler
    +

    sendHandler

    +
    +var sendHandler: AudioPlayerSendHandler
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/manager.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/manager.html new file mode 100644 index 0000000..4f0a07c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/manager.html @@ -0,0 +1,14 @@ + + + +GuildMusicManager.manager - + + + +it.discordbot.command.music.config / GuildMusicManager / manager
    +
    +

    manager

    + +val manager: AudioPlayerManager + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/player.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/player.html new file mode 100644 index 0000000..37baec6 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/player.html @@ -0,0 +1,14 @@ + + + +GuildMusicManager.player - + + + +it.discordbot.command.music.config / GuildMusicManager / player
    +
    +

    player

    + +var player: AudioPlayer + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/scheduler.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/scheduler.html new file mode 100644 index 0000000..f2fba0b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/scheduler.html @@ -0,0 +1,14 @@ + + + +GuildMusicManager.scheduler - + + + +it.discordbot.command.music.config / GuildMusicManager / scheduler
    +
    +

    scheduler

    + +var scheduler: TrackScheduler + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/send-handler.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/send-handler.html new file mode 100644 index 0000000..f7680a2 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-guild-music-manager/send-handler.html @@ -0,0 +1,14 @@ + + + +GuildMusicManager.sendHandler - + + + +it.discordbot.command.music.config / GuildMusicManager / sendHandler
    +
    +

    sendHandler

    + +var sendHandler: AudioPlayerSendHandler + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/-d-e-f-a-u-l-t_-v-o-l-u-m-e.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/-d-e-f-a-u-l-t_-v-o-l-u-m-e.html new file mode 100644 index 0000000..b9c2cd0 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/-d-e-f-a-u-l-t_-v-o-l-u-m-e.html @@ -0,0 +1,14 @@ + + + +MusicManager.DEFAULT_VOLUME - + + + +it.discordbot.command.music.config / MusicManager / DEFAULT_VOLUME
    +
    +

    DEFAULT_VOLUME

    + +private val DEFAULT_VOLUME: Int + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/-init-.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/-init-.html new file mode 100644 index 0000000..63802d2 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/-init-.html @@ -0,0 +1,14 @@ + + + +MusicManager.<init> - + + + +it.discordbot.command.music.config / MusicManager / <init>
    +
    +

    <init>

    + +MusicManager() + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/change-volume.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/change-volume.html new file mode 100644 index 0000000..f570acf --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/change-volume.html @@ -0,0 +1,19 @@ + + + +MusicManager.changeVolume - + + + +it.discordbot.command.music.config / MusicManager / changeVolume
    +
    +

    changeVolume

    + +private fun changeVolume(event: MessageReceivedEvent): Unit +

    Metodo per cambiare il volume, attualmente non in uso. +Bisogno di calcolo computazionale extra per il cambio del volume.

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/clear-queue.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/clear-queue.html new file mode 100644 index 0000000..b612afd --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/clear-queue.html @@ -0,0 +1,14 @@ + + + +MusicManager.clearQueue - + + + +it.discordbot.command.music.config / MusicManager / clearQueue
    +
    +

    clearQueue

    + +internal fun clearQueue(event: MessageReceivedEvent): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-list-queue.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-list-queue.html new file mode 100644 index 0000000..1d3b817 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-list-queue.html @@ -0,0 +1,18 @@ + + + +MusicManager.getListQueue - + + + +it.discordbot.command.music.config / MusicManager / getListQueue
    +
    +

    getListQueue

    + +internal fun getListQueue(event: MessageReceivedEvent): Unit +

    Metodo per ottenere la lista della coda

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-music-manager.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-music-manager.html new file mode 100644 index 0000000..d950dc1 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-music-manager.html @@ -0,0 +1,14 @@ + + + +MusicManager.getMusicManager - + + + +it.discordbot.command.music.config / MusicManager / getMusicManager
    +
    +

    getMusicManager

    + +private fun getMusicManager(guildId: String): GuildMusicManager + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-timestamp.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-timestamp.html new file mode 100644 index 0000000..cf7357d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-timestamp.html @@ -0,0 +1,14 @@ + + + +MusicManager.getTimestamp - + + + +it.discordbot.command.music.config / MusicManager / getTimestamp
    +
    +

    getTimestamp

    + +private fun getTimestamp(milliseconds: Long): String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-url.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-url.html new file mode 100644 index 0000000..afc32e2 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/get-url.html @@ -0,0 +1,20 @@ + + + +MusicManager.getUrl - + + + +it.discordbot.command.music.config / MusicManager / getUrl
    +
    +

    getUrl

    + +private fun getUrl(event: MessageReceivedEvent): String +

    Parsing del messaggio per ottenere l'url

    +

    Parameters

    +

    +event -

    +

    Return
    +String url della canzone

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/index.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/index.html new file mode 100644 index 0000000..2c472b6 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/index.html @@ -0,0 +1,225 @@ + + + +MusicManager - + + + +it.discordbot.command.music.config / MusicManager
    +
    +

    MusicManager

    +@Scope("singleton") @Component class MusicManager +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +MusicManager()
    +

    Properties

    + + + + + + + + + + + + + + + +
    +

    DEFAULT_VOLUME

    +
    +val DEFAULT_VOLUME: Int
    +

    musicManagers

    +
    +val musicManagers: MutableMap<String, GuildMusicManager>
    +

    playerManager

    +
    +val playerManager: AudioPlayerManager
    +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    changeVolume

    +
    +fun changeVolume(event: MessageReceivedEvent): Unit +

    Metodo per cambiare il volume, attualmente non in uso. +Bisogno di calcolo computazionale extra per il cambio del volume.

    +
    +

    clearQueue

    +
    +fun clearQueue(event: MessageReceivedEvent): Unit
    +

    getListQueue

    +
    +fun getListQueue(event: MessageReceivedEvent): Unit +

    Metodo per ottenere la lista della coda

    +
    +

    getMusicManager

    +
    +fun getMusicManager(guildId: String): GuildMusicManager
    +

    getTimestamp

    +
    +fun getTimestamp(milliseconds: Long): String
    +

    getUrl

    +
    +fun getUrl(event: MessageReceivedEvent): String +

    Parsing del messaggio per ottenere l'url

    +
    +

    join

    +
    +fun join(event: MessageReceivedEvent): Unit +

    Metodo per eseguire il join nel canale

    +
    +

    leave

    +
    +fun leave(event: MessageReceivedEvent): Unit +

    Metodo per far uscire il bot dalla lobby, bloccherà la queue +e la svuoterà

    +
    +

    loadAndPlay

    +
    +fun loadAndPlay(mng: GuildMusicManager, channel: MessageChannel, url: String, addPlaylist: Boolean): Unit +

    Metodo per caricare una traccia o una playlist nella coda

    +
    +

    nowPlay

    +
    +fun nowPlay(event: MessageReceivedEvent): Unit +

    Metodo per ottenere la traccia attualmente in riproduzione

    +
    +

    pauseResume

    +
    +fun pauseResume(event: MessageReceivedEvent): Unit +

    Metodo per mettere in pausa o riprendere la traccia attualmente +in riproduzione

    +
    +

    play

    +
    +fun play(event: MessageReceivedEvent): Unit +

    Metodo per riprodurre l'url audio passato come parametro

    +
    +

    playPlaylist

    +
    +fun playPlaylist(event: MessageReceivedEvent): Unit +

    Metodo per riprodurre una playlist dall'url passato come parametro

    +
    +

    repeat

    +
    +fun repeat(event: MessageReceivedEvent): Unit +

    Metodo per ripetere la traccia attualmente in riproduzione

    +
    +

    reset

    +
    +fun reset(event: MessageReceivedEvent): Unit +

    Metodo per resettare il bot in caso di problemi. +Pulisce la coda, e resetta i canali audio

    +
    +

    restart

    +
    +fun restart(event: MessageReceivedEvent): Unit +

    Metodo per riavviare la traccia attualmente in riproduzione

    +
    +

    shuffleQueue

    +
    +fun shuffleQueue(event: MessageReceivedEvent): Unit +

    Metodo per randomizzare la coda

    +
    +

    skip

    +
    +fun skip(event: MessageReceivedEvent): Unit +

    Metodo per saltare la traccia attualmente in riproduzione

    +
    +

    stop

    +
    +fun stop(event: MessageReceivedEvent): Unit +

    Metodo per stoppare la riproduzione e pulire la coda

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/join.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/join.html new file mode 100644 index 0000000..47721db --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/join.html @@ -0,0 +1,18 @@ + + + +MusicManager.join - + + + +it.discordbot.command.music.config / MusicManager / join
    +
    +

    join

    + +private fun join(event: MessageReceivedEvent): Unit +

    Metodo per eseguire il join nel canale

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/leave.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/leave.html new file mode 100644 index 0000000..fdeebdd --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/leave.html @@ -0,0 +1,19 @@ + + + +MusicManager.leave - + + + +it.discordbot.command.music.config / MusicManager / leave
    +
    +

    leave

    + +internal fun leave(event: MessageReceivedEvent): Unit +

    Metodo per far uscire il bot dalla lobby, bloccherà la queue +e la svuoterà

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/load-and-play.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/load-and-play.html new file mode 100644 index 0000000..a84a7fa --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/load-and-play.html @@ -0,0 +1,24 @@ + + + +MusicManager.loadAndPlay - + + + +it.discordbot.command.music.config / MusicManager / loadAndPlay
    +
    +

    loadAndPlay

    + +private fun loadAndPlay(mng: GuildMusicManager, channel: MessageChannel, url: String, addPlaylist: Boolean): Unit +

    Metodo per caricare una traccia o una playlist nella coda

    +

    Parameters

    +

    +mng -

    +

    +channel -

    +

    +url -

    +

    +addPlaylist -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/music-managers.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/music-managers.html new file mode 100644 index 0000000..8dc4759 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/music-managers.html @@ -0,0 +1,14 @@ + + + +MusicManager.musicManagers - + + + +it.discordbot.command.music.config / MusicManager / musicManagers
    +
    +

    musicManagers

    + +private val musicManagers: MutableMap<String, GuildMusicManager> + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/now-play.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/now-play.html new file mode 100644 index 0000000..2c98566 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/now-play.html @@ -0,0 +1,18 @@ + + + +MusicManager.nowPlay - + + + +it.discordbot.command.music.config / MusicManager / nowPlay
    +
    +

    nowPlay

    + +internal fun nowPlay(event: MessageReceivedEvent): Unit +

    Metodo per ottenere la traccia attualmente in riproduzione

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/pause-resume.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/pause-resume.html new file mode 100644 index 0000000..9a3134e --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/pause-resume.html @@ -0,0 +1,19 @@ + + + +MusicManager.pauseResume - + + + +it.discordbot.command.music.config / MusicManager / pauseResume
    +
    +

    pauseResume

    + +internal fun pauseResume(event: MessageReceivedEvent): Unit +

    Metodo per mettere in pausa o riprendere la traccia attualmente +in riproduzione

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/play-playlist.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/play-playlist.html new file mode 100644 index 0000000..45fcb68 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/play-playlist.html @@ -0,0 +1,18 @@ + + + +MusicManager.playPlaylist - + + + +it.discordbot.command.music.config / MusicManager / playPlaylist
    +
    +

    playPlaylist

    + +internal fun playPlaylist(event: MessageReceivedEvent): Unit +

    Metodo per riprodurre una playlist dall'url passato come parametro

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/play.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/play.html new file mode 100644 index 0000000..7c2107e --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/play.html @@ -0,0 +1,18 @@ + + + +MusicManager.play - + + + +it.discordbot.command.music.config / MusicManager / play
    +
    +

    play

    + +internal fun play(event: MessageReceivedEvent): Unit +

    Metodo per riprodurre l'url audio passato come parametro

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/player-manager.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/player-manager.html new file mode 100644 index 0000000..cff06f9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/player-manager.html @@ -0,0 +1,14 @@ + + + +MusicManager.playerManager - + + + +it.discordbot.command.music.config / MusicManager / playerManager
    +
    +

    playerManager

    + +private val playerManager: AudioPlayerManager + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/repeat.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/repeat.html new file mode 100644 index 0000000..79148db --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/repeat.html @@ -0,0 +1,18 @@ + + + +MusicManager.repeat - + + + +it.discordbot.command.music.config / MusicManager / repeat
    +
    +

    repeat

    + +internal fun repeat(event: MessageReceivedEvent): Unit +

    Metodo per ripetere la traccia attualmente in riproduzione

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/reset.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/reset.html new file mode 100644 index 0000000..337f1b5 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/reset.html @@ -0,0 +1,19 @@ + + + +MusicManager.reset - + + + +it.discordbot.command.music.config / MusicManager / reset
    +
    +

    reset

    + +internal fun reset(event: MessageReceivedEvent): Unit +

    Metodo per resettare il bot in caso di problemi. +Pulisce la coda, e resetta i canali audio

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/restart.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/restart.html new file mode 100644 index 0000000..0380976 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/restart.html @@ -0,0 +1,18 @@ + + + +MusicManager.restart - + + + +it.discordbot.command.music.config / MusicManager / restart
    +
    +

    restart

    + +internal fun restart(event: MessageReceivedEvent): Unit +

    Metodo per riavviare la traccia attualmente in riproduzione

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/shuffle-queue.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/shuffle-queue.html new file mode 100644 index 0000000..72a7262 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/shuffle-queue.html @@ -0,0 +1,18 @@ + + + +MusicManager.shuffleQueue - + + + +it.discordbot.command.music.config / MusicManager / shuffleQueue
    +
    +

    shuffleQueue

    + +internal fun shuffleQueue(event: MessageReceivedEvent): Unit +

    Metodo per randomizzare la coda

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/skip.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/skip.html new file mode 100644 index 0000000..643256b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/skip.html @@ -0,0 +1,18 @@ + + + +MusicManager.skip - + + + +it.discordbot.command.music.config / MusicManager / skip
    +
    +

    skip

    + +internal fun skip(event: MessageReceivedEvent): Unit +

    Metodo per saltare la traccia attualmente in riproduzione

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/stop.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/stop.html new file mode 100644 index 0000000..2bb95b3 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-music-manager/stop.html @@ -0,0 +1,18 @@ + + + +MusicManager.stop - + + + +it.discordbot.command.music.config / MusicManager / stop
    +
    +

    stop

    + +internal fun stop(event: MessageReceivedEvent): Unit +

    Metodo per stoppare la riproduzione e pulire la coda

    +

    Parameters

    +

    +event -

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/-init-.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/-init-.html new file mode 100644 index 0000000..a597aab --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/-init-.html @@ -0,0 +1,14 @@ + + + +TrackScheduler.<init> - + + + +it.discordbot.command.music.config / TrackScheduler / <init>
    +
    +

    <init>

    + +TrackScheduler(player: AudioPlayer) + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/index.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/index.html new file mode 100644 index 0000000..26e771d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/index.html @@ -0,0 +1,109 @@ + + + +TrackScheduler - + + + +it.discordbot.command.music.config / TrackScheduler
    +
    +

    TrackScheduler

    +class TrackScheduler : AudioEventAdapter +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +TrackScheduler(player: AudioPlayer)
    +

    Properties

    + + + + + + + + + + + + + + + + + + + +
    +

    lastTrack

    +
    +var lastTrack: AudioTrack?
    +

    player

    +
    +val player: AudioPlayer
    +

    queue

    +
    +val queue: Queue<AudioTrack>
    +

    repeating

    +
    +var repeating: Boolean
    +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    isRepeating

    +
    +fun isRepeating(): Boolean
    +

    nextTrack

    +
    +fun nextTrack(): Unit +

    Start the next track, stopping the current one if it is playing.

    +
    +

    onTrackEnd

    +
    +fun onTrackEnd(player: AudioPlayer?, track: AudioTrack?, endReason: AudioTrackEndReason): Unit
    +

    queue

    +
    +fun queue(track: AudioTrack): Unit +

    Add the next track to queue or play right away if nothing is in the queue.

    +
    +

    setRepeating

    +
    +fun setRepeating(repeating: Boolean): Unit
    +

    shuffle

    +
    +fun shuffle(): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/is-repeating.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/is-repeating.html new file mode 100644 index 0000000..0135501 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/is-repeating.html @@ -0,0 +1,14 @@ + + + +TrackScheduler.isRepeating - + + + +it.discordbot.command.music.config / TrackScheduler / isRepeating
    +
    +

    isRepeating

    + +fun isRepeating(): Boolean + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/last-track.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/last-track.html new file mode 100644 index 0000000..398c87b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/last-track.html @@ -0,0 +1,14 @@ + + + +TrackScheduler.lastTrack - + + + +it.discordbot.command.music.config / TrackScheduler / lastTrack
    +
    +

    lastTrack

    + +var lastTrack: AudioTrack? + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/next-track.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/next-track.html new file mode 100644 index 0000000..9fa9b00 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/next-track.html @@ -0,0 +1,15 @@ + + + +TrackScheduler.nextTrack - + + + +it.discordbot.command.music.config / TrackScheduler / nextTrack
    +
    +

    nextTrack

    + +fun nextTrack(): Unit +

    Start the next track, stopping the current one if it is playing.

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/on-track-end.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/on-track-end.html new file mode 100644 index 0000000..6e7d6ca --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/on-track-end.html @@ -0,0 +1,14 @@ + + + +TrackScheduler.onTrackEnd - + + + +it.discordbot.command.music.config / TrackScheduler / onTrackEnd
    +
    +

    onTrackEnd

    + +fun onTrackEnd(player: AudioPlayer?, track: AudioTrack?, endReason: AudioTrackEndReason): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/player.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/player.html new file mode 100644 index 0000000..9ece904 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/player.html @@ -0,0 +1,14 @@ + + + +TrackScheduler.player - + + + +it.discordbot.command.music.config / TrackScheduler / player
    +
    +

    player

    + +val player: AudioPlayer + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/queue.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/queue.html new file mode 100644 index 0000000..3c1e0af --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/queue.html @@ -0,0 +1,19 @@ + + + +TrackScheduler.queue - + + + +it.discordbot.command.music.config / TrackScheduler / queue
    +
    +

    queue

    + +val queue: Queue<AudioTrack> +fun queue(track: AudioTrack): Unit +

    Add the next track to queue or play right away if nothing is in the queue.

    +

    Parameters

    +

    +track - The track to play or add to queue.

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/repeating.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/repeating.html new file mode 100644 index 0000000..474ebcc --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/repeating.html @@ -0,0 +1,14 @@ + + + +TrackScheduler.repeating - + + + +it.discordbot.command.music.config / TrackScheduler / repeating
    +
    +

    repeating

    + +private var repeating: Boolean + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/set-repeating.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/set-repeating.html new file mode 100644 index 0000000..8ce9e2c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/set-repeating.html @@ -0,0 +1,14 @@ + + + +TrackScheduler.setRepeating - + + + +it.discordbot.command.music.config / TrackScheduler / setRepeating
    +
    +

    setRepeating

    + +fun setRepeating(repeating: Boolean): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/shuffle.html b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/shuffle.html new file mode 100644 index 0000000..b24d923 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/-track-scheduler/shuffle.html @@ -0,0 +1,14 @@ + + + +TrackScheduler.shuffle - + + + +it.discordbot.command.music.config / TrackScheduler / shuffle
    +
    +

    shuffle

    + +fun shuffle(): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music.config/index.html b/docs/page/kotlindoc/it.discordbot.command.music.config/index.html new file mode 100644 index 0000000..df07495 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music.config/index.html @@ -0,0 +1,45 @@ + + + +it.discordbot.command.music.config - + + + +it.discordbot.command.music.config
    +
    +

    Package it.discordbot.command.music.config

    +

    Types

    + + + + + + + + + + + + + + + + + + + +
    +

    AudioPlayerSendHandler

    +
    +class AudioPlayerSendHandler : AudioSendHandler
    +

    GuildMusicManager

    +
    +class GuildMusicManager
    +

    MusicManager

    +
    +class MusicManager
    +

    TrackScheduler

    +
    +class TrackScheduler : AudioEventAdapter
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music/-music-command/-init-.html b/docs/page/kotlindoc/it.discordbot.command.music/-music-command/-init-.html new file mode 100644 index 0000000..828ce6f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music/-music-command/-init-.html @@ -0,0 +1,14 @@ + + + +MusicCommand.<init> - + + + +it.discordbot.command.music / MusicCommand / <init>
    +
    +

    <init>

    + +MusicCommand() + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music/-music-command/index.html b/docs/page/kotlindoc/it.discordbot.command.music/-music-command/index.html new file mode 100644 index 0000000..6c16d18 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music/-music-command/index.html @@ -0,0 +1,56 @@ + + + +MusicCommand - + + + +it.discordbot.command.music / MusicCommand
    +
    +

    MusicCommand

    +@Scope("singleton") @Service class MusicCommand : ListenerAdapter +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +MusicCommand()
    +

    Properties

    + + + + + + + + + + + +
    +

    musicManager

    +
    +lateinit var musicManager: MusicManager
    +

    serverManagementInterface

    +
    +lateinit var serverManagementInterface: ServerManagementInterface
    +

    Functions

    + + + + + + + +
    +

    onMessageReceived

    +
    +fun onMessageReceived(event: MessageReceivedEvent?): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music/-music-command/music-manager.html b/docs/page/kotlindoc/it.discordbot.command.music/-music-command/music-manager.html new file mode 100644 index 0000000..dda310a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music/-music-command/music-manager.html @@ -0,0 +1,14 @@ + + + +MusicCommand.musicManager - + + + +it.discordbot.command.music / MusicCommand / musicManager
    +
    +

    musicManager

    + +lateinit var musicManager: MusicManager + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music/-music-command/on-message-received.html b/docs/page/kotlindoc/it.discordbot.command.music/-music-command/on-message-received.html new file mode 100644 index 0000000..a460a26 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music/-music-command/on-message-received.html @@ -0,0 +1,14 @@ + + + +MusicCommand.onMessageReceived - + + + +it.discordbot.command.music / MusicCommand / onMessageReceived
    +
    +

    onMessageReceived

    + +fun onMessageReceived(event: MessageReceivedEvent?): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music/-music-command/server-management-interface.html b/docs/page/kotlindoc/it.discordbot.command.music/-music-command/server-management-interface.html new file mode 100644 index 0000000..adff39d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music/-music-command/server-management-interface.html @@ -0,0 +1,14 @@ + + + +MusicCommand.serverManagementInterface - + + + +it.discordbot.command.music / MusicCommand / serverManagementInterface
    +
    +

    serverManagementInterface

    + +lateinit var serverManagementInterface: ServerManagementInterface + + diff --git a/docs/page/kotlindoc/it.discordbot.command.music/index.html b/docs/page/kotlindoc/it.discordbot.command.music/index.html new file mode 100644 index 0000000..c6aca1a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.music/index.html @@ -0,0 +1,24 @@ + + + +it.discordbot.command.music - + + + +it.discordbot.command.music
    +
    +

    Package it.discordbot.command.music

    +

    Types

    + + + + + + + +
    +

    MusicCommand

    +
    +class MusicCommand : ListenerAdapter
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/index.html b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/index.html new file mode 100644 index 0000000..5f4be9d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/index.html @@ -0,0 +1,57 @@ + + + +RSSReader - + + + +it.discordbot.command.pattern / RSSReader
    +
    +

    RSSReader

    +interface RSSReader +

    Interfaccia per la lettura e la conversione +dei messaggi RSS a MessageEmbed

    +

    Functions

    + + + + + + + + + + + +
    +

    prepareRSStoMessageEmbed

    +
    +abstract fun prepareRSStoMessageEmbed(message: RSSMessage): MessageEmbed
    +

    readRSS

    +
    +abstract fun readRSS(url: String): RSSMessage
    +

    Inheritors

    + + + + + + + + + + + +
    +

    ATMRSSReader

    +
    +class ATMRSSReader : RSSReader +

    Classe per leggere il feed RSS di atm

    +
    +

    BDORSSReader

    +
    +class BDORSSReader : RSSReader +

    Classe per leggere gli RSS di BDO

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/prepare-r-s-sto-message-embed.html b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/prepare-r-s-sto-message-embed.html new file mode 100644 index 0000000..69b59e8 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/prepare-r-s-sto-message-embed.html @@ -0,0 +1,14 @@ + + + +RSSReader.prepareRSStoMessageEmbed - + + + +it.discordbot.command.pattern / RSSReader / prepareRSStoMessageEmbed
    +
    +

    prepareRSStoMessageEmbed

    + +abstract fun prepareRSStoMessageEmbed(message: RSSMessage): MessageEmbed + + diff --git a/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/read-r-s-s.html b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/read-r-s-s.html new file mode 100644 index 0000000..f511426 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-reader/read-r-s-s.html @@ -0,0 +1,14 @@ + + + +RSSReader.readRSS - + + + +it.discordbot.command.pattern / RSSReader / readRSS
    +
    +

    readRSS

    + +abstract fun readRSS(url: String): RSSMessage + + diff --git a/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/index.html b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/index.html new file mode 100644 index 0000000..8e2a8c4 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/index.html @@ -0,0 +1,67 @@ + + + +RSSScheduler - + + + +it.discordbot.command.pattern / RSSScheduler
    +
    +

    RSSScheduler

    +interface RSSScheduler +

    Interfaccia base per i metodi di pubblicazione dei messaggi RSS

    +

    Functions

    + + + + + + + + + + + +
    +

    procedurePublish

    +
    +abstract fun procedurePublish(rssMessage: RSSMessage): Unit +

    Metodo per la preparazione alla pubblicazione dei messaggi RSS

    +
    +

    publishMessage

    +
    +abstract fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList<ServerToChannel>): Unit +

    Metodo per la pubblicazione dei messaggi

    +
    +

    Inheritors

    + + + + + + + + + + + + + + + +
    +

    ATMRSSScheduler

    +
    +class ATMRSSScheduler : RSSScheduler +

    Classe per la schedulaziooe dei messaggi RSS di ATM

    +
    +

    BDONewsRSSScheduler

    +
    +class BDONewsRSSScheduler : RSSScheduler +

    Classe per la schedulaziooe dei messaggi di news di BDO

    +
    +

    BDOPatchRSSScheduler

    +
    +class BDOPatchRSSScheduler : RSSScheduler
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/procedure-publish.html b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/procedure-publish.html new file mode 100644 index 0000000..225b1d8 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/procedure-publish.html @@ -0,0 +1,18 @@ + + + +RSSScheduler.procedurePublish - + + + +it.discordbot.command.pattern / RSSScheduler / procedurePublish
    +
    +

    procedurePublish

    + +abstract fun procedurePublish(rssMessage: RSSMessage): Unit +

    Metodo per la preparazione alla pubblicazione dei messaggi RSS

    +

    Parameters

    +

    +rssMessage - RSSMessage messaggio RSS

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/publish-message.html b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/publish-message.html new file mode 100644 index 0000000..1715887 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.pattern/-r-s-s-scheduler/publish-message.html @@ -0,0 +1,20 @@ + + + +RSSScheduler.publishMessage - + + + +it.discordbot.command.pattern / RSSScheduler / publishMessage
    +
    +

    publishMessage

    + +abstract fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList<ServerToChannel>): Unit +

    Metodo per la pubblicazione dei messaggi

    +

    Parameters

    +

    +message - MessageEmbed Messaggio

    +

    +serversToChannel - ArrayList Lista server e canali

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.pattern/index.html b/docs/page/kotlindoc/it.discordbot.command.pattern/index.html new file mode 100644 index 0000000..4342744 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.pattern/index.html @@ -0,0 +1,36 @@ + + + +it.discordbot.command.pattern - + + + +it.discordbot.command.pattern
    +
    +

    Package it.discordbot.command.pattern

    +

    Types

    + + + + + + + + + + + +
    +

    RSSReader

    +
    +interface RSSReader +

    Interfaccia per la lettura e la conversione +dei messaggi RSS a MessageEmbed

    +
    +

    RSSScheduler

    +
    +interface RSSScheduler +

    Interfaccia base per i metodi di pubblicazione dei messaggi RSS

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-a-r-t_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-a-r-t_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..821512b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-a-r-t_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +ATMCommand.ATM_START_COMMAND - + + + +it.discordbot.command.tpl.atmAlert / ATMCommand / ATM_START_COMMAND
    +
    +

    ATM_START_COMMAND

    + +const val ATM_START_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html new file mode 100644 index 0000000..c917d54 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-a-r-t_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html @@ -0,0 +1,14 @@ + + + +ATMCommand.ATM_START_COMMAND_DESCRIPTION - + + + +it.discordbot.command.tpl.atmAlert / ATMCommand / ATM_START_COMMAND_DESCRIPTION
    +
    +

    ATM_START_COMMAND_DESCRIPTION

    + +const val ATM_START_COMMAND_DESCRIPTION: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-o-p_-c-o-m-m-a-n-d.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-o-p_-c-o-m-m-a-n-d.html new file mode 100644 index 0000000..6720730 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-o-p_-c-o-m-m-a-n-d.html @@ -0,0 +1,14 @@ + + + +ATMCommand.ATM_STOP_COMMAND - + + + +it.discordbot.command.tpl.atmAlert / ATMCommand / ATM_STOP_COMMAND
    +
    +

    ATM_STOP_COMMAND

    + +const val ATM_STOP_COMMAND: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html new file mode 100644 index 0000000..db74ec9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-a-t-m_-s-t-o-p_-c-o-m-m-a-n-d_-d-e-s-c-r-i-p-t-i-o-n.html @@ -0,0 +1,14 @@ + + + +ATMCommand.ATM_STOP_COMMAND_DESCRIPTION - + + + +it.discordbot.command.tpl.atmAlert / ATMCommand / ATM_STOP_COMMAND_DESCRIPTION
    +
    +

    ATM_STOP_COMMAND_DESCRIPTION

    + +const val ATM_STOP_COMMAND_DESCRIPTION: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-init-.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-init-.html new file mode 100644 index 0000000..2d85365 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/-init-.html @@ -0,0 +1,15 @@ + + + +ATMCommand.<init> - + + + +it.discordbot.command.tpl.atmAlert / ATMCommand / <init>
    +
    +

    <init>

    + +ATMCommand() +

    Per i comandi dell'ATM

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/atm-interface.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/atm-interface.html new file mode 100644 index 0000000..76814c6 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/atm-interface.html @@ -0,0 +1,18 @@ + + + +ATMCommand.atmInterface - + + + +it.discordbot.command.tpl.atmAlert / ATMCommand / atmInterface
    +
    +

    atmInterface

    + +lateinit var atmInterface: ATMInterface +

    ATMInterface

    +

    Property

    +

    +atmInterface - ATMInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/index.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/index.html new file mode 100644 index 0000000..6ff73b6 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/index.html @@ -0,0 +1,96 @@ + + + +ATMCommand - + + + +it.discordbot.command.tpl.atmAlert / ATMCommand
    +
    +

    ATMCommand

    +@Scope("singleton") @Service class ATMCommand : ListenerAdapter +

    Per i comandi dell'ATM

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +ATMCommand() +

    Per i comandi dell'ATM

    +
    +

    Properties

    + + + + + + + + + + + +
    +

    atmInterface

    +
    +lateinit var atmInterface: ATMInterface +

    ATMInterface

    +
    +

    serverManagementInterface

    +
    +lateinit var serverManagementInterface: ServerManagementInterface +

    ServerManagementInterface

    +
    +

    Functions

    + + + + + + + +
    +

    onMessageReceived

    +
    +fun onMessageReceived(event: MessageReceivedEvent?): Unit
    +

    Companion Object Properties

    + + + + + + + + + + + + + + + + + + + +
    +

    ATM_START_COMMAND

    +
    +const val ATM_START_COMMAND: String
    +

    ATM_START_COMMAND_DESCRIPTION

    +
    +const val ATM_START_COMMAND_DESCRIPTION: String
    +

    ATM_STOP_COMMAND

    +
    +const val ATM_STOP_COMMAND: String
    +

    ATM_STOP_COMMAND_DESCRIPTION

    +
    +const val ATM_STOP_COMMAND_DESCRIPTION: String
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/on-message-received.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/on-message-received.html new file mode 100644 index 0000000..c24a2d2 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/on-message-received.html @@ -0,0 +1,14 @@ + + + +ATMCommand.onMessageReceived - + + + +it.discordbot.command.tpl.atmAlert / ATMCommand / onMessageReceived
    +
    +

    onMessageReceived

    + +fun onMessageReceived(event: MessageReceivedEvent?): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/server-management-interface.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/server-management-interface.html new file mode 100644 index 0000000..bc7e6a3 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-command/server-management-interface.html @@ -0,0 +1,18 @@ + + + +ATMCommand.serverManagementInterface - + + + +it.discordbot.command.tpl.atmAlert / ATMCommand / serverManagementInterface
    +
    +

    serverManagementInterface

    + +lateinit var serverManagementInterface: ServerManagementInterface +

    ServerManagementInterface

    +

    Property

    +

    +serverManagementInterface - ServerManagementInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/-a-t-m_-l-o-g-o_-r-s-s.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/-a-t-m_-l-o-g-o_-r-s-s.html new file mode 100644 index 0000000..da12fb2 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/-a-t-m_-l-o-g-o_-r-s-s.html @@ -0,0 +1,14 @@ + + + +ATMRSSReader.ATM_LOGO_RSS - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSReader / ATM_LOGO_RSS
    +
    +

    ATM_LOGO_RSS

    + +private const val ATM_LOGO_RSS: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/-init-.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/-init-.html new file mode 100644 index 0000000..e9eaa41 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/-init-.html @@ -0,0 +1,15 @@ + + + +ATMRSSReader.<init> - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSReader / <init>
    +
    +

    <init>

    + +ATMRSSReader() +

    Classe per leggere il feed RSS di atm

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/index.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/index.html new file mode 100644 index 0000000..99bd78f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/index.html @@ -0,0 +1,59 @@ + + + +ATMRSSReader - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSReader
    +
    +

    ATMRSSReader

    +@Scope("singleton") @Component class ATMRSSReader : RSSReader +

    Classe per leggere il feed RSS di atm

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +ATMRSSReader() +

    Classe per leggere il feed RSS di atm

    +
    +

    Functions

    + + + + + + + + + + + +
    +

    prepareRSStoMessageEmbed

    +
    +fun prepareRSStoMessageEmbed(message: RSSMessage): MessageEmbed
    +

    readRSS

    +
    +fun readRSS(url: String): RSSMessage
    +

    Companion Object Properties

    + + + + + + + +
    +

    ATM_LOGO_RSS

    +
    +const val ATM_LOGO_RSS: String
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/prepare-r-s-sto-message-embed.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/prepare-r-s-sto-message-embed.html new file mode 100644 index 0000000..cac1e9a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/prepare-r-s-sto-message-embed.html @@ -0,0 +1,15 @@ + + + +ATMRSSReader.prepareRSStoMessageEmbed - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSReader / prepareRSStoMessageEmbed
    +
    +

    prepareRSStoMessageEmbed

    + +fun prepareRSStoMessageEmbed(message: RSSMessage): MessageEmbed +

    Overrides RSSReader.prepareRSStoMessageEmbed

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/read-r-s-s.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/read-r-s-s.html new file mode 100644 index 0000000..9265055 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-reader/read-r-s-s.html @@ -0,0 +1,15 @@ + + + +ATMRSSReader.readRSS - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSReader / readRSS
    +
    +

    readRSS

    + +fun readRSS(url: String): RSSMessage +

    Overrides RSSReader.readRSS

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/-a-t-m_-r-s-s_-l-i-n-k.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/-a-t-m_-r-s-s_-l-i-n-k.html new file mode 100644 index 0000000..b54e728 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/-a-t-m_-r-s-s_-l-i-n-k.html @@ -0,0 +1,14 @@ + + + +ATMRSSScheduler.ATM_RSS_LINK - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSScheduler / ATM_RSS_LINK
    +
    +

    ATM_RSS_LINK

    + +const val ATM_RSS_LINK: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/-init-.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/-init-.html new file mode 100644 index 0000000..24c29f4 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/-init-.html @@ -0,0 +1,15 @@ + + + +ATMRSSScheduler.<init> - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSScheduler / <init>
    +
    +

    <init>

    + +ATMRSSScheduler() +

    Classe per la schedulaziooe dei messaggi RSS di ATM

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/atm-interface.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/atm-interface.html new file mode 100644 index 0000000..15351fd --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/atm-interface.html @@ -0,0 +1,18 @@ + + + +ATMRSSScheduler.atmInterface - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSScheduler / atmInterface
    +
    +

    atmInterface

    + +lateinit var atmInterface: ATMInterface +

    ATMInterface

    +

    Property

    +

    +atmInterface - ATMInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/atmrss-reader.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/atmrss-reader.html new file mode 100644 index 0000000..1200e6f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/atmrss-reader.html @@ -0,0 +1,18 @@ + + + +ATMRSSScheduler.atmrssReader - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSScheduler / atmrssReader
    +
    +

    atmrssReader

    + +lateinit var atmrssReader: ATMRSSReader +

    ATMRSSReader

    +

    Property

    +

    +atmrssReader - ATMRSSReader

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/index.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/index.html new file mode 100644 index 0000000..38f4155 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/index.html @@ -0,0 +1,93 @@ + + + +ATMRSSScheduler - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSScheduler
    +
    +

    ATMRSSScheduler

    +@Scope("singleton") @Service class ATMRSSScheduler : RSSScheduler +

    Classe per la schedulaziooe dei messaggi RSS di ATM

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +ATMRSSScheduler() +

    Classe per la schedulaziooe dei messaggi RSS di ATM

    +
    +

    Properties

    + + + + + + + + + + + +
    +

    atmInterface

    +
    +lateinit var atmInterface: ATMInterface +

    ATMInterface

    +
    +

    atmrssReader

    +
    +lateinit var atmrssReader: ATMRSSReader +

    ATMRSSReader

    +
    +

    Functions

    + + + + + + + + + + + + + + + +
    +

    procedurePublish

    +
    +fun procedurePublish(rssMessage: RSSMessage): Unit +

    Metodo per la preparazione alla pubblicazione dei messaggi RSS

    +
    +

    publishMessage

    +
    +fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList<ServerToChannel>): Unit +

    Metodo per la pubblicazione dei messaggi

    +
    +

    taskFeedRSSATM

    +
    +fun taskFeedRSSATM(): Unit
    +

    Companion Object Properties

    + + + + + + + +
    +

    ATM_RSS_LINK

    +
    +const val ATM_RSS_LINK: String
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/procedure-publish.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/procedure-publish.html new file mode 100644 index 0000000..c2f2099 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/procedure-publish.html @@ -0,0 +1,19 @@ + + + +ATMRSSScheduler.procedurePublish - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSScheduler / procedurePublish
    +
    +

    procedurePublish

    + +fun procedurePublish(rssMessage: RSSMessage): Unit +

    Overrides RSSScheduler.procedurePublish

    +

    Metodo per la preparazione alla pubblicazione dei messaggi RSS

    +

    Parameters

    +

    +rssMessage - RSSMessage messaggio RSS

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/publish-message.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/publish-message.html new file mode 100644 index 0000000..9ae17e2 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/publish-message.html @@ -0,0 +1,21 @@ + + + +ATMRSSScheduler.publishMessage - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSScheduler / publishMessage
    +
    +

    publishMessage

    + +fun publishMessage(message: MessageEmbed, serversToChannel: ArrayList<ServerToChannel>): Unit +

    Overrides RSSScheduler.publishMessage

    +

    Metodo per la pubblicazione dei messaggi

    +

    Parameters

    +

    +message - MessageEmbed Messaggio

    +

    +serversToChannel - ArrayList Lista server e canali

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/task-feed-r-s-s-a-t-m.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/task-feed-r-s-s-a-t-m.html new file mode 100644 index 0000000..4c57f16 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-r-s-s-scheduler/task-feed-r-s-s-a-t-m.html @@ -0,0 +1,14 @@ + + + +ATMRSSScheduler.taskFeedRSSATM - + + + +it.discordbot.command.tpl.atmAlert / ATMRSSScheduler / taskFeedRSSATM
    +
    +

    taskFeedRSSATM

    + +@Scheduled(900000, 900000) fun taskFeedRSSATM(): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-a-t-m_-t-w-i-t-t-e-r_-i-d.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-a-t-m_-t-w-i-t-t-e-r_-i-d.html new file mode 100644 index 0000000..859f0d2 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-a-t-m_-t-w-i-t-t-e-r_-i-d.html @@ -0,0 +1,14 @@ + + + +ATMTwitterScheduler.ATM_TWITTER_ID - + + + +it.discordbot.command.tpl.atmAlert / ATMTwitterScheduler / ATM_TWITTER_ID
    +
    +

    ATM_TWITTER_ID

    + +private const val ATM_TWITTER_ID: Long + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-init-.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-init-.html new file mode 100644 index 0000000..ab4edc1 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-init-.html @@ -0,0 +1,15 @@ + + + +ATMTwitterScheduler.<init> - + + + +it.discordbot.command.tpl.atmAlert / ATMTwitterScheduler / <init>
    +
    +

    <init>

    + +ATMTwitterScheduler() +

    Classe per la schedulaziooe dei messaggi Twitter di ATM

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-q-u-e-r-y_-p-a-r-a-m.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-q-u-e-r-y_-p-a-r-a-m.html new file mode 100644 index 0000000..539f2a9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-q-u-e-r-y_-p-a-r-a-m.html @@ -0,0 +1,14 @@ + + + +ATMTwitterScheduler.QUERY_PARAM - + + + +it.discordbot.command.tpl.atmAlert / ATMTwitterScheduler / QUERY_PARAM
    +
    +

    QUERY_PARAM

    + +private const val QUERY_PARAM: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-t-w-i-t-t-e-r_-i-m-a-g-e.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-t-w-i-t-t-e-r_-i-m-a-g-e.html new file mode 100644 index 0000000..a70aa9d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-t-w-i-t-t-e-r_-i-m-a-g-e.html @@ -0,0 +1,14 @@ + + + +ATMTwitterScheduler.TWITTER_IMAGE - + + + +it.discordbot.command.tpl.atmAlert / ATMTwitterScheduler / TWITTER_IMAGE
    +
    +

    TWITTER_IMAGE

    + +private const val TWITTER_IMAGE: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-t-w-i-t-t-e-r_-u-r-l.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-t-w-i-t-t-e-r_-u-r-l.html new file mode 100644 index 0000000..9498d89 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/-t-w-i-t-t-e-r_-u-r-l.html @@ -0,0 +1,14 @@ + + + +ATMTwitterScheduler.TWITTER_URL - + + + +it.discordbot.command.tpl.atmAlert / ATMTwitterScheduler / TWITTER_URL
    +
    +

    TWITTER_URL

    + +private const val TWITTER_URL: String + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/atm-interface.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/atm-interface.html new file mode 100644 index 0000000..762e3e9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/atm-interface.html @@ -0,0 +1,18 @@ + + + +ATMTwitterScheduler.atmInterface - + + + +it.discordbot.command.tpl.atmAlert / ATMTwitterScheduler / atmInterface
    +
    +

    atmInterface

    + +lateinit var atmInterface: ATMInterface +

    ATMInterface

    +

    Property

    +

    +atmInterface - ATMInterface

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/index.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/index.html new file mode 100644 index 0000000..cfc2ff3 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/index.html @@ -0,0 +1,103 @@ + + + +ATMTwitterScheduler - + + + +it.discordbot.command.tpl.atmAlert / ATMTwitterScheduler
    +
    +

    ATMTwitterScheduler

    +@Scope("singleton") @Service class ATMTwitterScheduler +

    Classe per la schedulaziooe dei messaggi Twitter di ATM

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +ATMTwitterScheduler() +

    Classe per la schedulaziooe dei messaggi Twitter di ATM

    +
    +

    Properties

    + + + + + + + + + + + +
    +

    atmInterface

    +
    +lateinit var atmInterface: ATMInterface +

    ATMInterface

    +
    +

    twitterManager

    +
    +lateinit var twitterManager: TwitterManager +

    TwitterManager

    +
    +

    Functions

    + + + + + + + + + + + +
    +

    initATMTwitterScheduler

    +
    +fun initATMTwitterScheduler(): Unit
    +

    publish

    +
    +fun publish(tweetID: Long, twitterMessage: String, mediaUrl: String?, profileImageUrl: String): Unit
    +

    Companion Object Properties

    + + + + + + + + + + + + + + + + + + + +
    +

    ATM_TWITTER_ID

    +
    +const val ATM_TWITTER_ID: Long
    +

    QUERY_PARAM

    +
    +const val QUERY_PARAM: String
    +

    TWITTER_IMAGE

    +
    +const val TWITTER_IMAGE: String
    +

    TWITTER_URL

    +
    +const val TWITTER_URL: String
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/init-a-t-m-twitter-scheduler.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/init-a-t-m-twitter-scheduler.html new file mode 100644 index 0000000..60685cd --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/init-a-t-m-twitter-scheduler.html @@ -0,0 +1,14 @@ + + + +ATMTwitterScheduler.initATMTwitterScheduler - + + + +it.discordbot.command.tpl.atmAlert / ATMTwitterScheduler / initATMTwitterScheduler
    +
    +

    initATMTwitterScheduler

    + +@PostConstruct fun initATMTwitterScheduler(): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/publish.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/publish.html new file mode 100644 index 0000000..4aa92da --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/publish.html @@ -0,0 +1,14 @@ + + + +ATMTwitterScheduler.publish - + + + +it.discordbot.command.tpl.atmAlert / ATMTwitterScheduler / publish
    +
    +

    publish

    + +private fun publish(tweetID: Long, twitterMessage: String, mediaUrl: String?, profileImageUrl: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/twitter-manager.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/twitter-manager.html new file mode 100644 index 0000000..78b2045 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/-a-t-m-twitter-scheduler/twitter-manager.html @@ -0,0 +1,18 @@ + + + +ATMTwitterScheduler.twitterManager - + + + +it.discordbot.command.tpl.atmAlert / ATMTwitterScheduler / twitterManager
    +
    +

    twitterManager

    + +lateinit var twitterManager: TwitterManager +

    TwitterManager

    +

    Property

    +

    +twitterManager - TwitterManager

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/index.html b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/index.html new file mode 100644 index 0000000..f34c22c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command.tpl.atm-alert/index.html @@ -0,0 +1,53 @@ + + + +it.discordbot.command.tpl.atmAlert - + + + +it.discordbot.command.tpl.atmAlert
    +
    +

    Package it.discordbot.command.tpl.atmAlert

    +

    Types

    + + + + + + + + + + + + + + + + + + + +
    +

    ATMCommand

    +
    +class ATMCommand : ListenerAdapter +

    Per i comandi dell'ATM

    +
    +

    ATMRSSReader

    +
    +class ATMRSSReader : RSSReader +

    Classe per leggere il feed RSS di atm

    +
    +

    ATMRSSScheduler

    +
    +class ATMRSSScheduler : RSSScheduler +

    Classe per la schedulaziooe dei messaggi RSS di ATM

    +
    +

    ATMTwitterScheduler

    +
    +class ATMTwitterScheduler +

    Classe per la schedulaziooe dei messaggi Twitter di ATM

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command/check-admin-permission.html b/docs/page/kotlindoc/it.discordbot.command/check-admin-permission.html new file mode 100644 index 0000000..f097c9d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command/check-admin-permission.html @@ -0,0 +1,20 @@ + + + +checkAdminPermission - + + + +it.discordbot.command / checkAdminPermission
    +
    +

    checkAdminPermission

    + +fun checkAdminPermission(event: MessageReceivedEvent): Boolean +

    Metodo che controlla se l'utente ha i permessi di amministrare il server

    +

    Parameters

    +

    +event - MessageReceivedEvent evento del messaggio ricevuto

    +

    Return
    +Boolean True, l'utente ha permessi amministrativi

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command/check-command.html b/docs/page/kotlindoc/it.discordbot.command/check-command.html new file mode 100644 index 0000000..a1984d1 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command/check-command.html @@ -0,0 +1,27 @@ + + + +checkCommand - + + + +it.discordbot.command / checkCommand
    +
    +

    checkCommand

    + +fun checkCommand(@NotNull event: MessageReceivedEvent, @NotNull simbolCommand: String, @NotNull commandName: String): Boolean +

    Metodo per controllare se il comando inserito dall'utente +è il comando controllato. +Viene controllato se il messaggio è con il simbolo di comando +o viene citato il bot.

    +

    Parameters

    +

    +event - MessageReceivedEvent evento del messaggio ricevuto

    +

    +simbolCommand - String simbolo di comando del server

    +

    +commandName - String nome del comando

    +

    Return
    +Boolean il comando confrontato e quello voluto sono uguali

    + + diff --git a/docs/page/kotlindoc/it.discordbot.command/index.html b/docs/page/kotlindoc/it.discordbot.command/index.html new file mode 100644 index 0000000..ceb84d1 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command/index.html @@ -0,0 +1,47 @@ + + + +it.discordbot.command - + + + +it.discordbot.command
    +
    +

    Package it.discordbot.command

    +

    Functions

    + + + + + + + + + + + + + + + +
    +

    checkAdminPermission

    +
    +fun checkAdminPermission(event: MessageReceivedEvent): Boolean +

    Metodo che controlla se l'utente ha i permessi di amministrare il server

    +
    +

    checkCommand

    +
    +fun checkCommand(event: MessageReceivedEvent, simbolCommand: String, commandName: String): Boolean +

    Metodo per controllare se il comando inserito dall'utente +è il comando controllato. +Viene controllato se il messaggio è con il simbolo di comando +o viene citato il bot.

    +
    +

    rejectCommand

    +
    +fun rejectCommand(event: MessageReceivedEvent): Unit +

    Metodo per inviare il messaggio prefatto che l'utente non ha i permessi necessari

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.command/reject-command.html b/docs/page/kotlindoc/it.discordbot.command/reject-command.html new file mode 100644 index 0000000..c689598 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.command/reject-command.html @@ -0,0 +1,18 @@ + + + +rejectCommand - + + + +it.discordbot.command / rejectCommand
    +
    +

    rejectCommand

    + +fun rejectCommand(event: MessageReceivedEvent): Unit +

    Metodo per inviare il messaggio prefatto che l'utente non ha i permessi necessari

    +

    Parameters

    +

    +event - MessageReceivedEvent

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/-init-.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/-init-.html new file mode 100644 index 0000000..afc16ea --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/-init-.html @@ -0,0 +1,15 @@ + + + +JDAController.<init> - + + + +it.discordbot.core / JDAController / <init>
    +
    +

    <init>

    + +JDAController() +

    Classe principale di avviamento del Bot Discord

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/atm-command.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/atm-command.html new file mode 100644 index 0000000..281afb6 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/atm-command.html @@ -0,0 +1,18 @@ + + + +JDAController.atmCommand - + + + +it.discordbot.core / JDAController / atmCommand
    +
    +

    atmCommand

    + +lateinit var atmCommand: ATMCommand +

    ATMCommand

    +

    Property

    +

    +atmCommand - ATMCommand

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/bdo-command.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/bdo-command.html new file mode 100644 index 0000000..75d1dc1 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/bdo-command.html @@ -0,0 +1,18 @@ + + + +JDAController.bdoCommand - + + + +it.discordbot.core / JDAController / bdoCommand
    +
    +

    bdoCommand

    + +lateinit var bdoCommand: BDOCommand +

    BDOCommand

    +

    Property

    +

    +bdoCommand - BDOCommand

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/general-command.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/general-command.html new file mode 100644 index 0000000..5b6b41d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/general-command.html @@ -0,0 +1,18 @@ + + + +JDAController.generalCommand - + + + +it.discordbot.core / JDAController / generalCommand
    +
    +

    generalCommand

    + +lateinit var generalCommand: GeneralCommand +

    GeneralCommand

    +

    Property

    +

    +generalCommand - GeneralCommand

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/index.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/index.html new file mode 100644 index 0000000..2056b70 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/index.html @@ -0,0 +1,120 @@ + + + +JDAController - + + + +it.discordbot.core / JDAController
    +
    +

    JDAController

    +@Scope("singleton") @Component class JDAController +

    Classe principale di avviamento del Bot Discord

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +JDAController() +

    Classe principale di avviamento del Bot Discord

    +
    +

    Properties

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    atmCommand

    +
    +lateinit var atmCommand: ATMCommand +

    ATMCommand

    +
    +

    bdoCommand

    +
    +lateinit var bdoCommand: BDOCommand +

    BDOCommand

    +
    +

    generalCommand

    +
    +lateinit var generalCommand: GeneralCommand +

    GeneralCommand

    +
    +

    jdaToken

    +
    +lateinit var jdaToken: String +

    String Chiave API per il bot Discord

    +
    +

    joinListener

    +
    +lateinit var joinListener: JoinListener +

    JoinListener

    +
    +

    musicCommand

    +
    +lateinit var musicCommand: MusicCommand +

    MusicCommand

    +
    +

    testCommand

    +
    +lateinit var testCommand: TestCommand +

    TestCommand

    +
    +

    Functions

    + + + + + + + +
    +

    init

    +
    +fun init(): Unit
    +

    Companion Object Properties

    + + + + + + + +
    +

    jda

    +
    +lateinit var jda: JDA
    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/init.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/init.html new file mode 100644 index 0000000..a10b33a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/init.html @@ -0,0 +1,14 @@ + + + +JDAController.init - + + + +it.discordbot.core / JDAController / init
    +
    +

    init

    + +@PostConstruct fun init(): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/jda-token.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/jda-token.html new file mode 100644 index 0000000..68e113a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/jda-token.html @@ -0,0 +1,18 @@ + + + +JDAController.jdaToken - + + + +it.discordbot.core / JDAController / jdaToken
    +
    +

    jdaToken

    + +private lateinit var jdaToken: String +

    String Chiave API per il bot Discord

    +

    Property

    +

    +jdaToken - String Chiave API per il bot Discord

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/jda.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/jda.html new file mode 100644 index 0000000..8c4df50 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/jda.html @@ -0,0 +1,14 @@ + + + +JDAController.jda - + + + +it.discordbot.core / JDAController / jda
    +
    +

    jda

    + +lateinit var jda: JDA + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/join-listener.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/join-listener.html new file mode 100644 index 0000000..8df0ce1 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/join-listener.html @@ -0,0 +1,18 @@ + + + +JDAController.joinListener - + + + +it.discordbot.core / JDAController / joinListener
    +
    +

    joinListener

    + +lateinit var joinListener: JoinListener +

    JoinListener

    +

    Property

    +

    +joinListener - JoinListener

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/music-command.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/music-command.html new file mode 100644 index 0000000..682d5fd --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/music-command.html @@ -0,0 +1,18 @@ + + + +JDAController.musicCommand - + + + +it.discordbot.core / JDAController / musicCommand
    +
    +

    musicCommand

    + +lateinit var musicCommand: MusicCommand +

    MusicCommand

    +

    Property

    +

    +musicCommand - MusicCommand

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/test-command.html b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/test-command.html new file mode 100644 index 0000000..1f8edd9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-j-d-a-controller/test-command.html @@ -0,0 +1,18 @@ + + + +JDAController.testCommand - + + + +it.discordbot.core / JDAController / testCommand
    +
    +

    testCommand

    + +lateinit var testCommand: TestCommand +

    TestCommand

    +

    Property

    +

    +testCommand - TestCommand

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-takao-log/-init-.html b/docs/page/kotlindoc/it.discordbot.core/-takao-log/-init-.html new file mode 100644 index 0000000..5bc184a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-takao-log/-init-.html @@ -0,0 +1,15 @@ + + + +TakaoLog.<init> - + + + +it.discordbot.core / TakaoLog / <init>
    +
    +

    <init>

    + +TakaoLog() +

    Logger Unico per il bot

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-takao-log/index.html b/docs/page/kotlindoc/it.discordbot.core/-takao-log/index.html new file mode 100644 index 0000000..efe0fcf --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-takao-log/index.html @@ -0,0 +1,66 @@ + + + +TakaoLog - + + + +it.discordbot.core / TakaoLog
    +
    +

    TakaoLog

    +@Component class TakaoLog +

    Logger Unico per il bot

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +TakaoLog() +

    Logger Unico per il bot

    +
    +

    Companion Object Properties

    + + + + + + + +
    +

    logger

    +
    +var logger: Logger!
    +

    Companion Object Functions

    + + + + + + + + + + + + + + + +
    +

    logDebug

    +
    +fun logDebug(message: String): Unit
    +

    logError

    +
    +fun logError(message: String): Unit
    +

    logInfo

    +
    +fun logInfo(message: String): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-takao-log/log-debug.html b/docs/page/kotlindoc/it.discordbot.core/-takao-log/log-debug.html new file mode 100644 index 0000000..8e85bb6 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-takao-log/log-debug.html @@ -0,0 +1,14 @@ + + + +TakaoLog.logDebug - + + + +it.discordbot.core / TakaoLog / logDebug
    +
    +

    logDebug

    + +fun logDebug(message: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-takao-log/log-error.html b/docs/page/kotlindoc/it.discordbot.core/-takao-log/log-error.html new file mode 100644 index 0000000..0fb0c81 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-takao-log/log-error.html @@ -0,0 +1,14 @@ + + + +TakaoLog.logError - + + + +it.discordbot.core / TakaoLog / logError
    +
    +

    logError

    + +fun logError(message: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-takao-log/log-info.html b/docs/page/kotlindoc/it.discordbot.core/-takao-log/log-info.html new file mode 100644 index 0000000..6e58dbe --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-takao-log/log-info.html @@ -0,0 +1,14 @@ + + + +TakaoLog.logInfo - + + + +it.discordbot.core / TakaoLog / logInfo
    +
    +

    logInfo

    + +fun logInfo(message: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-takao-log/logger.html b/docs/page/kotlindoc/it.discordbot.core/-takao-log/logger.html new file mode 100644 index 0000000..fdb12ad --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-takao-log/logger.html @@ -0,0 +1,14 @@ + + + +TakaoLog.logger - + + + +it.discordbot.core / TakaoLog / logger
    +
    +

    logger

    + +private var logger: Logger! + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/-init-.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/-init-.html new file mode 100644 index 0000000..b1495fa --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/-init-.html @@ -0,0 +1,15 @@ + + + +TwitterManager.<init> - + + + +it.discordbot.core / TwitterManager / <init>
    +
    +

    <init>

    + +TwitterManager() +

    Classe che si occupa di collegarsi ai sistemi di twitter

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/get-twitter-stream.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/get-twitter-stream.html new file mode 100644 index 0000000..a1588d2 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/get-twitter-stream.html @@ -0,0 +1,14 @@ + + + +TwitterManager.getTwitterStream - + + + +it.discordbot.core / TwitterManager / getTwitterStream
    +
    +

    getTwitterStream

    + +fun getTwitterStream(): TwitterStream + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/index.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/index.html new file mode 100644 index 0000000..1439954 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/index.html @@ -0,0 +1,122 @@ + + + +TwitterManager - + + + +it.discordbot.core / TwitterManager
    +
    +

    TwitterManager

    +@Scope("singleton") @Component class TwitterManager +

    Classe che si occupa di collegarsi ai sistemi di twitter

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +TwitterManager() +

    Classe che si occupa di collegarsi ai sistemi di twitter

    +
    +

    Properties

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    twitterAccessToken

    +
    +lateinit var twitterAccessToken: String +

    String AccessToken

    +
    +

    twitterAccessTokenSecret

    +
    +lateinit var twitterAccessTokenSecret: String +

    String AccessTokenSecret

    +
    +

    twitterConsumerKey

    +
    +lateinit var twitterConsumerKey: String +

    String ConsumerKey

    +
    +

    twitterConsumerSecret

    +
    +lateinit var twitterConsumerSecret: String +

    String ConsumerSecret

    +
    +

    twitterStream

    +
    +lateinit var twitterStream: TwitterStream +

    TwitterStream

    +
    +

    twitterStreamFactory

    +
    +lateinit var twitterStreamFactory: TwitterStreamFactory +

    TwitterStreamFactory

    +
    +

    Functions

    + + + + + + + + + + + + + + + + + + + +
    +

    getTwitterStream

    +
    +fun getTwitterStream(): TwitterStream
    +

    initTwitter

    +
    +fun initTwitter(): Unit
    +

    setTwitterStreamFilter

    +
    +fun setTwitterStreamFilter(filterQuery: FilterQuery): TwitterManager
    +

    setTwitterStreamListener

    +
    +fun setTwitterStreamListener(listener: StatusListener): TwitterManager +

    Metodo per aggiungere un listener di Twitter

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/init-twitter.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/init-twitter.html new file mode 100644 index 0000000..eb72a63 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/init-twitter.html @@ -0,0 +1,14 @@ + + + +TwitterManager.initTwitter - + + + +it.discordbot.core / TwitterManager / initTwitter
    +
    +

    initTwitter

    + +@PostConstruct fun initTwitter(): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/set-twitter-stream-filter.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/set-twitter-stream-filter.html new file mode 100644 index 0000000..5963aca --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/set-twitter-stream-filter.html @@ -0,0 +1,14 @@ + + + +TwitterManager.setTwitterStreamFilter - + + + +it.discordbot.core / TwitterManager / setTwitterStreamFilter
    +
    +

    setTwitterStreamFilter

    + +fun setTwitterStreamFilter(filterQuery: FilterQuery): TwitterManager + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/set-twitter-stream-listener.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/set-twitter-stream-listener.html new file mode 100644 index 0000000..08bec44 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/set-twitter-stream-listener.html @@ -0,0 +1,20 @@ + + + +TwitterManager.setTwitterStreamListener - + + + +it.discordbot.core / TwitterManager / setTwitterStreamListener
    +
    +

    setTwitterStreamListener

    + +fun setTwitterStreamListener(listener: StatusListener): TwitterManager +

    Metodo per aggiungere un listener di Twitter

    +

    Parameters

    +

    +listener - StatusListener

    +

    Return
    +TwitterManager

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-access-token-secret.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-access-token-secret.html new file mode 100644 index 0000000..366e88f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-access-token-secret.html @@ -0,0 +1,18 @@ + + + +TwitterManager.twitterAccessTokenSecret - + + + +it.discordbot.core / TwitterManager / twitterAccessTokenSecret
    +
    +

    twitterAccessTokenSecret

    + +lateinit var twitterAccessTokenSecret: String +

    String AccessTokenSecret

    +

    Property

    +

    +twitterAccessTokenSecret - String AccessTokenSecret

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-access-token.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-access-token.html new file mode 100644 index 0000000..60c0fe9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-access-token.html @@ -0,0 +1,18 @@ + + + +TwitterManager.twitterAccessToken - + + + +it.discordbot.core / TwitterManager / twitterAccessToken
    +
    +

    twitterAccessToken

    + +lateinit var twitterAccessToken: String +

    String AccessToken

    +

    Property

    +

    +twitterAccessToken - String AccessToken

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-consumer-key.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-consumer-key.html new file mode 100644 index 0000000..3bddd4c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-consumer-key.html @@ -0,0 +1,18 @@ + + + +TwitterManager.twitterConsumerKey - + + + +it.discordbot.core / TwitterManager / twitterConsumerKey
    +
    +

    twitterConsumerKey

    + +lateinit var twitterConsumerKey: String +

    String ConsumerKey

    +

    Property

    +

    +twitterConsumerKey - String ConsumerKey

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-consumer-secret.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-consumer-secret.html new file mode 100644 index 0000000..6b22b1b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-consumer-secret.html @@ -0,0 +1,18 @@ + + + +TwitterManager.twitterConsumerSecret - + + + +it.discordbot.core / TwitterManager / twitterConsumerSecret
    +
    +

    twitterConsumerSecret

    + +lateinit var twitterConsumerSecret: String +

    String ConsumerSecret

    +

    Property

    +

    +twitterConsumerSecret - String ConsumerSecret

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-stream-factory.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-stream-factory.html new file mode 100644 index 0000000..4ae7d7c --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-stream-factory.html @@ -0,0 +1,18 @@ + + + +TwitterManager.twitterStreamFactory - + + + +it.discordbot.core / TwitterManager / twitterStreamFactory
    +
    +

    twitterStreamFactory

    + +private lateinit var twitterStreamFactory: TwitterStreamFactory +

    TwitterStreamFactory

    +

    Property

    +

    +twitterStreamFactory - TwitterStreamFactory

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-stream.html b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-stream.html new file mode 100644 index 0000000..70159ee --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/-twitter-manager/twitter-stream.html @@ -0,0 +1,18 @@ + + + +TwitterManager.twitterStream - + + + +it.discordbot.core / TwitterManager / twitterStream
    +
    +

    twitterStream

    + +private lateinit var twitterStream: TwitterStream +

    TwitterStream

    +

    Property

    +

    +twitterStream - TwitterStream

    + + diff --git a/docs/page/kotlindoc/it.discordbot.core/index.html b/docs/page/kotlindoc/it.discordbot.core/index.html new file mode 100644 index 0000000..0066150 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.core/index.html @@ -0,0 +1,44 @@ + + + +it.discordbot.core - + + + +it.discordbot.core
    +
    +

    Package it.discordbot.core

    +

    Types

    + + + + + + + + + + + + + + + +
    +

    JDAController

    +
    +class JDAController +

    Classe principale di avviamento del Bot Discord

    +
    +

    TakaoLog

    +
    +class TakaoLog +

    Logger Unico per il bot

    +
    +

    TwitterManager

    +
    +class TwitterManager +

    Classe che si occupa di collegarsi ai sistemi di twitter

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/-init-.html b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/-init-.html new file mode 100644 index 0000000..3bacaeb --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/-init-.html @@ -0,0 +1,15 @@ + + + +ATMInterface.<init> - + + + +it.discordbot.database.filter / ATMInterface / <init>
    +
    +

    <init>

    + +ATMInterface() +

    Classe di interfacciamento al db per le funzioni di ATM

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/get-a-t-m-alert-channels.html b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/get-a-t-m-alert-channels.html new file mode 100644 index 0000000..0910fc7 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/get-a-t-m-alert-channels.html @@ -0,0 +1,14 @@ + + + +ATMInterface.getATMAlertChannels - + + + +it.discordbot.database.filter / ATMInterface / getATMAlertChannels
    +
    +

    getATMAlertChannels

    + +fun getATMAlertChannels(): ArrayList<ServerToChannel> + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/get-last-a-t-m-alert.html b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/get-last-a-t-m-alert.html new file mode 100644 index 0000000..5fb2971 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/get-last-a-t-m-alert.html @@ -0,0 +1,14 @@ + + + +ATMInterface.getLastATMAlert - + + + +it.discordbot.database.filter / ATMInterface / getLastATMAlert
    +
    +

    getLastATMAlert

    + +fun getLastATMAlert(): String? + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/index.html b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/index.html new file mode 100644 index 0000000..cd93b19 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/index.html @@ -0,0 +1,91 @@ + + + +ATMInterface - + + + +it.discordbot.database.filter / ATMInterface
    +
    +

    ATMInterface

    +@Scope("singleton") @Component class ATMInterface +

    Classe di interfacciamento al db per le funzioni di ATM

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +ATMInterface() +

    Classe di interfacciamento al db per le funzioni di ATM

    +
    +

    Properties

    + + + + + + + + + + + +
    +

    rssLinkRepository

    +
    +lateinit var rssLinkRepository: RSSLinkRepository +

    RSSLinkRepository

    +
    +

    serverDiscordRepository

    +
    +lateinit var serverDiscordRepository: ServerDiscordRepository +

    ServerDiscordRepository

    +
    +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + +
    +

    getATMAlertChannels

    +
    +fun getATMAlertChannels(): ArrayList<ServerToChannel>
    +

    getLastATMAlert

    +
    +fun getLastATMAlert(): String?
    +

    removeATMAlertChannel

    +
    +fun removeATMAlertChannel(serverID: String): String?
    +

    setATMAlertChannel

    +
    +fun setATMAlertChannel(serverID: String, channelID: String): Unit
    +

    setLastATMAlert

    +
    +fun setLastATMAlert(url: String): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/remove-a-t-m-alert-channel.html b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/remove-a-t-m-alert-channel.html new file mode 100644 index 0000000..94f7200 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/remove-a-t-m-alert-channel.html @@ -0,0 +1,14 @@ + + + +ATMInterface.removeATMAlertChannel - + + + +it.discordbot.database.filter / ATMInterface / removeATMAlertChannel
    +
    +

    removeATMAlertChannel

    + +fun removeATMAlertChannel(serverID: String): String? + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/rss-link-repository.html b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/rss-link-repository.html new file mode 100644 index 0000000..aee55fc --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/rss-link-repository.html @@ -0,0 +1,18 @@ + + + +ATMInterface.rssLinkRepository - + + + +it.discordbot.database.filter / ATMInterface / rssLinkRepository
    +
    +

    rssLinkRepository

    + +lateinit var rssLinkRepository: RSSLinkRepository +

    RSSLinkRepository

    +

    Property

    +

    +rssLinkRepository - RSSLinkRepository

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/server-discord-repository.html b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/server-discord-repository.html new file mode 100644 index 0000000..35fda7d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/server-discord-repository.html @@ -0,0 +1,18 @@ + + + +ATMInterface.serverDiscordRepository - + + + +it.discordbot.database.filter / ATMInterface / serverDiscordRepository
    +
    +

    serverDiscordRepository

    + +lateinit var serverDiscordRepository: ServerDiscordRepository +

    ServerDiscordRepository

    +

    Property

    +

    +serverDiscordRepository - ServerDiscordRepository

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/set-a-t-m-alert-channel.html b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/set-a-t-m-alert-channel.html new file mode 100644 index 0000000..6246b35 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/set-a-t-m-alert-channel.html @@ -0,0 +1,14 @@ + + + +ATMInterface.setATMAlertChannel - + + + +it.discordbot.database.filter / ATMInterface / setATMAlertChannel
    +
    +

    setATMAlertChannel

    + +fun setATMAlertChannel(serverID: String, channelID: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/set-last-a-t-m-alert.html b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/set-last-a-t-m-alert.html new file mode 100644 index 0000000..dd666ac --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-a-t-m-interface/set-last-a-t-m-alert.html @@ -0,0 +1,14 @@ + + + +ATMInterface.setLastATMAlert - + + + +it.discordbot.database.filter / ATMInterface / setLastATMAlert
    +
    +

    setLastATMAlert

    + +fun setLastATMAlert(url: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/-init-.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/-init-.html new file mode 100644 index 0000000..dfb40e9 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/-init-.html @@ -0,0 +1,15 @@ + + + +BDOBossInterface.<init> - + + + +it.discordbot.database.filter / BDOBossInterface / <init>
    +
    +

    <init>

    + +BDOBossInterface() +

    Classe di interfacciamento al db per le funzioni di BDO Boss

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/get-b-d-o-boss-channels.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/get-b-d-o-boss-channels.html new file mode 100644 index 0000000..42aa287 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/get-b-d-o-boss-channels.html @@ -0,0 +1,14 @@ + + + +BDOBossInterface.getBDOBossChannels - + + + +it.discordbot.database.filter / BDOBossInterface / getBDOBossChannels
    +
    +

    getBDOBossChannels

    + +fun getBDOBossChannels(): ArrayList<ServerToChannel> + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/get-b-d-o-boss-list.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/get-b-d-o-boss-list.html new file mode 100644 index 0000000..7e1d9b3 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/get-b-d-o-boss-list.html @@ -0,0 +1,14 @@ + + + +BDOBossInterface.getBDOBossList - + + + +it.discordbot.database.filter / BDOBossInterface / getBDOBossList
    +
    +

    getBDOBossList

    + +fun getBDOBossList(): ArrayList<Giorno> + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/index.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/index.html new file mode 100644 index 0000000..4a90319 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/index.html @@ -0,0 +1,75 @@ + + + +BDOBossInterface - + + + +it.discordbot.database.filter / BDOBossInterface
    +
    +

    BDOBossInterface

    +@Scope("singleton") @Controller class BDOBossInterface +

    Classe di interfacciamento al db per le funzioni di BDO Boss

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +BDOBossInterface() +

    Classe di interfacciamento al db per le funzioni di BDO Boss

    +
    +

    Properties

    + + + + + + + +
    +

    serverDiscordRepository

    +
    +lateinit var serverDiscordRepository: ServerDiscordRepository +

    ServerDiscordRepository

    +
    +

    Functions

    + + + + + + + + + + + + + + + + + + + +
    +

    getBDOBossChannels

    +
    +fun getBDOBossChannels(): ArrayList<ServerToChannel>
    +

    getBDOBossList

    +
    +fun getBDOBossList(): ArrayList<Giorno>
    +

    removeBDOBossChannel

    +
    +fun removeBDOBossChannel(serverID: String): String?
    +

    setBDOBossChannel

    +
    +fun setBDOBossChannel(serverID: String, channelID: String): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/remove-b-d-o-boss-channel.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/remove-b-d-o-boss-channel.html new file mode 100644 index 0000000..ce6788a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/remove-b-d-o-boss-channel.html @@ -0,0 +1,14 @@ + + + +BDOBossInterface.removeBDOBossChannel - + + + +it.discordbot.database.filter / BDOBossInterface / removeBDOBossChannel
    +
    +

    removeBDOBossChannel

    + +fun removeBDOBossChannel(serverID: String): String? + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/server-discord-repository.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/server-discord-repository.html new file mode 100644 index 0000000..673db8a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/server-discord-repository.html @@ -0,0 +1,18 @@ + + + +BDOBossInterface.serverDiscordRepository - + + + +it.discordbot.database.filter / BDOBossInterface / serverDiscordRepository
    +
    +

    serverDiscordRepository

    + +lateinit var serverDiscordRepository: ServerDiscordRepository +

    ServerDiscordRepository

    +

    Property

    +

    +serverDiscordRepository - ServerDiscordRepository

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/set-b-d-o-boss-channel.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/set-b-d-o-boss-channel.html new file mode 100644 index 0000000..f6bd92f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-boss-interface/set-b-d-o-boss-channel.html @@ -0,0 +1,14 @@ + + + +BDOBossInterface.setBDOBossChannel - + + + +it.discordbot.database.filter / BDOBossInterface / setBDOBossChannel
    +
    +

    setBDOBossChannel

    + +fun setBDOBossChannel(serverID: String, channelID: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/-init-.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/-init-.html new file mode 100644 index 0000000..62e8018 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/-init-.html @@ -0,0 +1,15 @@ + + + +BDONewsInterface.<init> - + + + +it.discordbot.database.filter / BDONewsInterface / <init>
    +
    +

    <init>

    + +BDONewsInterface() +

    Classe di interfacciamento al db per le funzioni di BDO News

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/get-b-d-o-news-channels.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/get-b-d-o-news-channels.html new file mode 100644 index 0000000..05c8a94 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/get-b-d-o-news-channels.html @@ -0,0 +1,14 @@ + + + +BDONewsInterface.getBDONewsChannels - + + + +it.discordbot.database.filter / BDONewsInterface / getBDONewsChannels
    +
    +

    getBDONewsChannels

    + +fun getBDONewsChannels(): ArrayList<ServerToChannel> + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/get-last-b-d-o-news.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/get-last-b-d-o-news.html new file mode 100644 index 0000000..ea7b2f1 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/get-last-b-d-o-news.html @@ -0,0 +1,14 @@ + + + +BDONewsInterface.getLastBDONews - + + + +it.discordbot.database.filter / BDONewsInterface / getLastBDONews
    +
    +

    getLastBDONews

    + +fun getLastBDONews(): String + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/index.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/index.html new file mode 100644 index 0000000..a82bb11 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/index.html @@ -0,0 +1,91 @@ + + + +BDONewsInterface - + + + +it.discordbot.database.filter / BDONewsInterface
    +
    +

    BDONewsInterface

    +@Scope("singleton") @Component class BDONewsInterface +

    Classe di interfacciamento al db per le funzioni di BDO News

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +BDONewsInterface() +

    Classe di interfacciamento al db per le funzioni di BDO News

    +
    +

    Properties

    + + + + + + + + + + + +
    +

    rssLinkRepository

    +
    +lateinit var rssLinkRepository: RSSLinkRepository +

    RSSLinkRepository

    +
    +

    serverDiscordRepository

    +
    +lateinit var serverDiscordRepository: ServerDiscordRepository +

    ServerDiscordRepository

    +
    +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + +
    +

    getBDONewsChannels

    +
    +fun getBDONewsChannels(): ArrayList<ServerToChannel>
    +

    getLastBDONews

    +
    +fun getLastBDONews(): String
    +

    removeBDONewsChannel

    +
    +fun removeBDONewsChannel(serverID: String): String?
    +

    setBDONews

    +
    +fun setBDONews(link: String): Unit
    +

    setBDONewsChannel

    +
    +fun setBDONewsChannel(serverID: String, channelID: String): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/remove-b-d-o-news-channel.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/remove-b-d-o-news-channel.html new file mode 100644 index 0000000..268d092 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/remove-b-d-o-news-channel.html @@ -0,0 +1,14 @@ + + + +BDONewsInterface.removeBDONewsChannel - + + + +it.discordbot.database.filter / BDONewsInterface / removeBDONewsChannel
    +
    +

    removeBDONewsChannel

    + +fun removeBDONewsChannel(serverID: String): String? + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/rss-link-repository.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/rss-link-repository.html new file mode 100644 index 0000000..ac353b6 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/rss-link-repository.html @@ -0,0 +1,18 @@ + + + +BDONewsInterface.rssLinkRepository - + + + +it.discordbot.database.filter / BDONewsInterface / rssLinkRepository
    +
    +

    rssLinkRepository

    + +lateinit var rssLinkRepository: RSSLinkRepository +

    RSSLinkRepository

    +

    Property

    +

    +rssLinkRepository - RSSLinkRepository

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/server-discord-repository.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/server-discord-repository.html new file mode 100644 index 0000000..6713638 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/server-discord-repository.html @@ -0,0 +1,18 @@ + + + +BDONewsInterface.serverDiscordRepository - + + + +it.discordbot.database.filter / BDONewsInterface / serverDiscordRepository
    +
    +

    serverDiscordRepository

    + +lateinit var serverDiscordRepository: ServerDiscordRepository +

    ServerDiscordRepository

    +

    Property

    +

    +serverDiscordRepository - ServerDiscordRepository

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/set-b-d-o-news-channel.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/set-b-d-o-news-channel.html new file mode 100644 index 0000000..4546992 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/set-b-d-o-news-channel.html @@ -0,0 +1,14 @@ + + + +BDONewsInterface.setBDONewsChannel - + + + +it.discordbot.database.filter / BDONewsInterface / setBDONewsChannel
    +
    +

    setBDONewsChannel

    + +fun setBDONewsChannel(serverID: String, channelID: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/set-b-d-o-news.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/set-b-d-o-news.html new file mode 100644 index 0000000..9fc7428 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-news-interface/set-b-d-o-news.html @@ -0,0 +1,14 @@ + + + +BDONewsInterface.setBDONews - + + + +it.discordbot.database.filter / BDONewsInterface / setBDONews
    +
    +

    setBDONews

    + +fun setBDONews(link: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/-init-.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/-init-.html new file mode 100644 index 0000000..055ee1d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/-init-.html @@ -0,0 +1,15 @@ + + + +BDOPatchInterface.<init> - + + + +it.discordbot.database.filter / BDOPatchInterface / <init>
    +
    +

    <init>

    + +BDOPatchInterface() +

    Classe di interfacciamento al db per le funzioni di BDO Patch

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/get-b-d-o-patch-channels.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/get-b-d-o-patch-channels.html new file mode 100644 index 0000000..de1b21a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/get-b-d-o-patch-channels.html @@ -0,0 +1,14 @@ + + + +BDOPatchInterface.getBDOPatchChannels - + + + +it.discordbot.database.filter / BDOPatchInterface / getBDOPatchChannels
    +
    +

    getBDOPatchChannels

    + +fun getBDOPatchChannels(): ArrayList<ServerToChannel> + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/get-last-b-d-o-patch.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/get-last-b-d-o-patch.html new file mode 100644 index 0000000..c8551cb --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/get-last-b-d-o-patch.html @@ -0,0 +1,14 @@ + + + +BDOPatchInterface.getLastBDOPatch - + + + +it.discordbot.database.filter / BDOPatchInterface / getLastBDOPatch
    +
    +

    getLastBDOPatch

    + +fun getLastBDOPatch(): String + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/index.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/index.html new file mode 100644 index 0000000..3140918 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/index.html @@ -0,0 +1,91 @@ + + + +BDOPatchInterface - + + + +it.discordbot.database.filter / BDOPatchInterface
    +
    +

    BDOPatchInterface

    +@Scope("singleton") @Component class BDOPatchInterface +

    Classe di interfacciamento al db per le funzioni di BDO Patch

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +BDOPatchInterface() +

    Classe di interfacciamento al db per le funzioni di BDO Patch

    +
    +

    Properties

    + + + + + + + + + + + +
    +

    rssLinkRepository

    +
    +lateinit var rssLinkRepository: RSSLinkRepository +

    RSSLinkRepository

    +
    +

    serverDiscordRepository

    +
    +lateinit var serverDiscordRepository: ServerDiscordRepository +

    ServerDiscordRepository

    +
    +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + +
    +

    getBDOPatchChannels

    +
    +fun getBDOPatchChannels(): ArrayList<ServerToChannel>
    +

    getLastBDOPatch

    +
    +fun getLastBDOPatch(): String
    +

    removeBDOPatchChannel

    +
    +fun removeBDOPatchChannel(serverID: String): String?
    +

    setBDOPatchChannel

    +
    +fun setBDOPatchChannel(serverID: String, channelID: String): Unit
    +

    setLastPatch

    +
    +fun setLastPatch(linkPatch: String): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/remove-b-d-o-patch-channel.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/remove-b-d-o-patch-channel.html new file mode 100644 index 0000000..cb81f6f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/remove-b-d-o-patch-channel.html @@ -0,0 +1,14 @@ + + + +BDOPatchInterface.removeBDOPatchChannel - + + + +it.discordbot.database.filter / BDOPatchInterface / removeBDOPatchChannel
    +
    +

    removeBDOPatchChannel

    + +fun removeBDOPatchChannel(serverID: String): String? + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/rss-link-repository.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/rss-link-repository.html new file mode 100644 index 0000000..5a0de15 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/rss-link-repository.html @@ -0,0 +1,18 @@ + + + +BDOPatchInterface.rssLinkRepository - + + + +it.discordbot.database.filter / BDOPatchInterface / rssLinkRepository
    +
    +

    rssLinkRepository

    + +lateinit var rssLinkRepository: RSSLinkRepository +

    RSSLinkRepository

    +

    Property

    +

    +rssLinkRepository - RSSLinkRepository

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/server-discord-repository.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/server-discord-repository.html new file mode 100644 index 0000000..0cf6810 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/server-discord-repository.html @@ -0,0 +1,18 @@ + + + +BDOPatchInterface.serverDiscordRepository - + + + +it.discordbot.database.filter / BDOPatchInterface / serverDiscordRepository
    +
    +

    serverDiscordRepository

    + +lateinit var serverDiscordRepository: ServerDiscordRepository +

    ServerDiscordRepository

    +

    Property

    +

    +serverDiscordRepository - ServerDiscordRepository

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/set-b-d-o-patch-channel.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/set-b-d-o-patch-channel.html new file mode 100644 index 0000000..c517158 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/set-b-d-o-patch-channel.html @@ -0,0 +1,14 @@ + + + +BDOPatchInterface.setBDOPatchChannel - + + + +it.discordbot.database.filter / BDOPatchInterface / setBDOPatchChannel
    +
    +

    setBDOPatchChannel

    + +fun setBDOPatchChannel(serverID: String, channelID: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/set-last-patch.html b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/set-last-patch.html new file mode 100644 index 0000000..0aa2253 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-b-d-o-patch-interface/set-last-patch.html @@ -0,0 +1,14 @@ + + + +BDOPatchInterface.setLastPatch - + + + +it.discordbot.database.filter / BDOPatchInterface / setLastPatch
    +
    +

    setLastPatch

    + +fun setLastPatch(linkPatch: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/-init-.html b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/-init-.html new file mode 100644 index 0000000..808d09e --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/-init-.html @@ -0,0 +1,15 @@ + + + +ServerManagementInterface.<init> - + + + +it.discordbot.database.filter / ServerManagementInterface / <init>
    +
    +

    <init>

    + +ServerManagementInterface() +

    Classe di interfacciamento al db per le funzioni base del BOT

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/delete-server.html b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/delete-server.html new file mode 100644 index 0000000..6fdc6bb --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/delete-server.html @@ -0,0 +1,14 @@ + + + +ServerManagementInterface.deleteServer - + + + +it.discordbot.database.filter / ServerManagementInterface / deleteServer
    +
    +

    deleteServer

    + +fun deleteServer(serverID: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/get-simbol-command.html b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/get-simbol-command.html new file mode 100644 index 0000000..f076429 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/get-simbol-command.html @@ -0,0 +1,14 @@ + + + +ServerManagementInterface.getSimbolCommand - + + + +it.discordbot.database.filter / ServerManagementInterface / getSimbolCommand
    +
    +

    getSimbolCommand

    + +fun getSimbolCommand(serverID: String): String + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/index.html b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/index.html new file mode 100644 index 0000000..94a2818 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/index.html @@ -0,0 +1,75 @@ + + + +ServerManagementInterface - + + + +it.discordbot.database.filter / ServerManagementInterface
    +
    +

    ServerManagementInterface

    +@Scope("singleton") @Component class ServerManagementInterface +

    Classe di interfacciamento al db per le funzioni base del BOT

    +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +ServerManagementInterface() +

    Classe di interfacciamento al db per le funzioni base del BOT

    +
    +

    Properties

    + + + + + + + +
    +

    serverDiscordRepository

    +
    +lateinit var serverDiscordRepository: ServerDiscordRepository +

    ServerDiscordRepository

    +
    +

    Functions

    + + + + + + + + + + + + + + + + + + + +
    +

    deleteServer

    +
    +fun deleteServer(serverID: String): Unit
    +

    getSimbolCommand

    +
    +fun getSimbolCommand(serverID: String): String
    +

    newServer

    +
    +fun newServer(serverID: String, serverName: String): Unit
    +

    setSimbolCommand

    +
    +fun setSimbolCommand(serverID: String, simbolCommand: String): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/new-server.html b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/new-server.html new file mode 100644 index 0000000..566ca4d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/new-server.html @@ -0,0 +1,14 @@ + + + +ServerManagementInterface.newServer - + + + +it.discordbot.database.filter / ServerManagementInterface / newServer
    +
    +

    newServer

    + +fun newServer(serverID: String, serverName: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/server-discord-repository.html b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/server-discord-repository.html new file mode 100644 index 0000000..99e1fee --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/server-discord-repository.html @@ -0,0 +1,18 @@ + + + +ServerManagementInterface.serverDiscordRepository - + + + +it.discordbot.database.filter / ServerManagementInterface / serverDiscordRepository
    +
    +

    serverDiscordRepository

    + +private lateinit var serverDiscordRepository: ServerDiscordRepository +

    ServerDiscordRepository

    +

    Property

    +

    +serverDiscordRepository - ServerDiscordRepository

    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/set-simbol-command.html b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/set-simbol-command.html new file mode 100644 index 0000000..c3cb169 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/-server-management-interface/set-simbol-command.html @@ -0,0 +1,14 @@ + + + +ServerManagementInterface.setSimbolCommand - + + + +it.discordbot.database.filter / ServerManagementInterface / setSimbolCommand
    +
    +

    setSimbolCommand

    + +fun setSimbolCommand(serverID: String, simbolCommand: String): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot.database.filter/index.html b/docs/page/kotlindoc/it.discordbot.database.filter/index.html new file mode 100644 index 0000000..ff7efb3 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.filter/index.html @@ -0,0 +1,62 @@ + + + +it.discordbot.database.filter - + + + +it.discordbot.database.filter
    +
    +

    Package it.discordbot.database.filter

    +

    Types

    + + + + + + + + + + + + + + + + + + + + + + + +
    +

    ATMInterface

    +
    +class ATMInterface +

    Classe di interfacciamento al db per le funzioni di ATM

    +
    +

    BDOBossInterface

    +
    +class BDOBossInterface +

    Classe di interfacciamento al db per le funzioni di BDO Boss

    +
    +

    BDONewsInterface

    +
    +class BDONewsInterface +

    Classe di interfacciamento al db per le funzioni di BDO News

    +
    +

    BDOPatchInterface

    +
    +class BDOPatchInterface +

    Classe di interfacciamento al db per le funzioni di BDO Patch

    +
    +

    ServerManagementInterface

    +
    +class ServerManagementInterface +

    Classe di interfacciamento al db per le funzioni base del BOT

    +
    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.repository/-r-s-s-link-repository/get-first-by-id.html b/docs/page/kotlindoc/it.discordbot.database.repository/-r-s-s-link-repository/get-first-by-id.html new file mode 100644 index 0000000..cd1e4b7 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.repository/-r-s-s-link-repository/get-first-by-id.html @@ -0,0 +1,14 @@ + + + +RSSLinkRepository.getFirstById - + + + +it.discordbot.database.repository / RSSLinkRepository / getFirstById
    +
    +

    getFirstById

    + +abstract fun getFirstById(id: Long = 1): RSSLink + + diff --git a/docs/page/kotlindoc/it.discordbot.database.repository/-r-s-s-link-repository/index.html b/docs/page/kotlindoc/it.discordbot.database.repository/-r-s-s-link-repository/index.html new file mode 100644 index 0000000..441e3c6 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.repository/-r-s-s-link-repository/index.html @@ -0,0 +1,25 @@ + + + +RSSLinkRepository - + + + +it.discordbot.database.repository / RSSLinkRepository
    +
    +

    RSSLinkRepository

    +interface RSSLinkRepository : CrudRepository<RSSLink, Int> +

    Functions

    + + + + + + + +
    +

    getFirstById

    +
    +abstract fun getFirstById(id: Long = 1): RSSLink
    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/find-server-discord-by-server-id.html b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/find-server-discord-by-server-id.html new file mode 100644 index 0000000..eefb2ff --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/find-server-discord-by-server-id.html @@ -0,0 +1,14 @@ + + + +ServerDiscordRepository.findServerDiscordByServerId - + + + +it.discordbot.database.repository / ServerDiscordRepository / findServerDiscordByServerId
    +
    +

    findServerDiscordByServerId

    + +abstract fun findServerDiscordByServerId(serverID: String): ServerDiscord + + diff --git a/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-a-t-m-alert-channels.html b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-a-t-m-alert-channels.html new file mode 100644 index 0000000..e0139d0 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-a-t-m-alert-channels.html @@ -0,0 +1,14 @@ + + + +ServerDiscordRepository.getAllATMAlertChannels - + + + +it.discordbot.database.repository / ServerDiscordRepository / getAllATMAlertChannels
    +
    +

    getAllATMAlertChannels

    + +@Query("SELECT new it.discordbot.beans.ServerToChannel(serv.serverId, serv.atmAlertIDChannel) from ServerDiscord serv where serv.atmAlertIDChannel is not null") abstract fun getAllATMAlertChannels(): ArrayList<ServerToChannel> + + diff --git a/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-boss-channels.html b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-boss-channels.html new file mode 100644 index 0000000..ba89a1f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-boss-channels.html @@ -0,0 +1,14 @@ + + + +ServerDiscordRepository.getAllBDOBossChannels - + + + +it.discordbot.database.repository / ServerDiscordRepository / getAllBDOBossChannels
    +
    +

    getAllBDOBossChannels

    + +@Query("SELECT new it.discordbot.beans.ServerToChannel(serv.serverId, serv.bdoBossIDChannel) from ServerDiscord serv where serv.bdoBossIDChannel is not null") abstract fun getAllBDOBossChannels(): ArrayList<ServerToChannel> + + diff --git a/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-news-channels.html b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-news-channels.html new file mode 100644 index 0000000..dc28743 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-news-channels.html @@ -0,0 +1,14 @@ + + + +ServerDiscordRepository.getAllBDONewsChannels - + + + +it.discordbot.database.repository / ServerDiscordRepository / getAllBDONewsChannels
    +
    +

    getAllBDONewsChannels

    + +@Query("SELECT new it.discordbot.beans.ServerToChannel(serv.serverId, serv.bdoNewsIDChannel) from ServerDiscord serv where serv.bdoNewsIDChannel is not null") abstract fun getAllBDONewsChannels(): ArrayList<ServerToChannel> + + diff --git a/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-patch-channels.html b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-patch-channels.html new file mode 100644 index 0000000..571e6d5 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/get-all-b-d-o-patch-channels.html @@ -0,0 +1,14 @@ + + + +ServerDiscordRepository.getAllBDOPatchChannels - + + + +it.discordbot.database.repository / ServerDiscordRepository / getAllBDOPatchChannels
    +
    +

    getAllBDOPatchChannels

    + +@Query("SELECT new it.discordbot.beans.ServerToChannel(serv.serverId, serv.bdoPatchIDChannel) from ServerDiscord serv where serv.bdoPatchIDChannel is not null") abstract fun getAllBDOPatchChannels(): ArrayList<ServerToChannel> + + diff --git a/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/index.html b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/index.html new file mode 100644 index 0000000..49283cc --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.repository/-server-discord-repository/index.html @@ -0,0 +1,53 @@ + + + +ServerDiscordRepository - + + + +it.discordbot.database.repository / ServerDiscordRepository
    +
    +

    ServerDiscordRepository

    +@Repository interface ServerDiscordRepository : CrudRepository<ServerDiscord, String> +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + +
    +

    findServerDiscordByServerId

    +
    +abstract fun findServerDiscordByServerId(serverID: String): ServerDiscord
    +

    getAllATMAlertChannels

    +
    +abstract fun getAllATMAlertChannels(): ArrayList<ServerToChannel>
    +

    getAllBDOBossChannels

    +
    +abstract fun getAllBDOBossChannels(): ArrayList<ServerToChannel>
    +

    getAllBDONewsChannels

    +
    +abstract fun getAllBDONewsChannels(): ArrayList<ServerToChannel>
    +

    getAllBDOPatchChannels

    +
    +abstract fun getAllBDOPatchChannels(): ArrayList<ServerToChannel>
    + + diff --git a/docs/page/kotlindoc/it.discordbot.database.repository/index.html b/docs/page/kotlindoc/it.discordbot.database.repository/index.html new file mode 100644 index 0000000..7c29b62 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot.database.repository/index.html @@ -0,0 +1,31 @@ + + + +it.discordbot.database.repository - + + + +it.discordbot.database.repository
    +
    +

    Package it.discordbot.database.repository

    +

    Types

    + + + + + + + + + + + +
    +

    RSSLinkRepository

    +
    +interface RSSLinkRepository : CrudRepository<RSSLink, Int>
    +

    ServerDiscordRepository

    +
    +interface ServerDiscordRepository : CrudRepository<ServerDiscord, String>
    + + diff --git a/docs/page/kotlindoc/it.discordbot/-start-bot/-init-.html b/docs/page/kotlindoc/it.discordbot/-start-bot/-init-.html new file mode 100644 index 0000000..4ca86bf --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot/-start-bot/-init-.html @@ -0,0 +1,14 @@ + + + +StartBot.<init> - + + + +it.discordbot / StartBot / <init>
    +
    +

    <init>

    + +StartBot() + + diff --git a/docs/page/kotlindoc/it.discordbot/-start-bot/index.html b/docs/page/kotlindoc/it.discordbot/-start-bot/index.html new file mode 100644 index 0000000..11d1c0d --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot/-start-bot/index.html @@ -0,0 +1,25 @@ + + + +StartBot - + + + +it.discordbot / StartBot
    +
    +

    StartBot

    +@SpringBootApplication @EnableScheduling class StartBot +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +StartBot()
    + + diff --git a/docs/page/kotlindoc/it.discordbot/-test-command/-init-.html b/docs/page/kotlindoc/it.discordbot/-test-command/-init-.html new file mode 100644 index 0000000..12e6878 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot/-test-command/-init-.html @@ -0,0 +1,14 @@ + + + +TestCommand.<init> - + + + +it.discordbot / TestCommand / <init>
    +
    +

    <init>

    + +TestCommand() + + diff --git a/docs/page/kotlindoc/it.discordbot/-test-command/bdo-news-interface.html b/docs/page/kotlindoc/it.discordbot/-test-command/bdo-news-interface.html new file mode 100644 index 0000000..92f1464 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot/-test-command/bdo-news-interface.html @@ -0,0 +1,14 @@ + + + +TestCommand.bdoNewsInterface - + + + +it.discordbot / TestCommand / bdoNewsInterface
    +
    +

    bdoNewsInterface

    + +lateinit var bdoNewsInterface: <ERROR CLASS> + + diff --git a/docs/page/kotlindoc/it.discordbot/-test-command/index.html b/docs/page/kotlindoc/it.discordbot/-test-command/index.html new file mode 100644 index 0000000..77ea96f --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot/-test-command/index.html @@ -0,0 +1,37 @@ + + + +TestCommand - + + + +it.discordbot / TestCommand
    +
    +

    TestCommand

    +@Component class TestCommand : ListenerAdapter +

    Constructors

    + + + + + + + +
    +

    <init>

    +
    +TestCommand()
    +

    Functions

    + + + + + + + +
    +

    onMessageReceived

    +
    +fun onMessageReceived(event: MessageReceivedEvent?): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot/-test-command/on-message-received.html b/docs/page/kotlindoc/it.discordbot/-test-command/on-message-received.html new file mode 100644 index 0000000..99da442 --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot/-test-command/on-message-received.html @@ -0,0 +1,14 @@ + + + +TestCommand.onMessageReceived - + + + +it.discordbot / TestCommand / onMessageReceived
    +
    +

    onMessageReceived

    + +fun onMessageReceived(event: MessageReceivedEvent?): Unit + + diff --git a/docs/page/kotlindoc/it.discordbot/index.html b/docs/page/kotlindoc/it.discordbot/index.html new file mode 100644 index 0000000..355933a --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot/index.html @@ -0,0 +1,43 @@ + + + +it.discordbot - + + + +it.discordbot
    +
    +

    Package it.discordbot

    +

    Types

    + + + + + + + + + + + +
    +

    StartBot

    +
    +class StartBot
    +

    TestCommand

    +
    +class TestCommand : ListenerAdapter
    +

    Functions

    + + + + + + + +
    +

    main

    +
    +fun main(args: Array<String>): Unit
    + + diff --git a/docs/page/kotlindoc/it.discordbot/main.html b/docs/page/kotlindoc/it.discordbot/main.html new file mode 100644 index 0000000..3a5360b --- /dev/null +++ b/docs/page/kotlindoc/it.discordbot/main.html @@ -0,0 +1,14 @@ + + + +main - + + + +it.discordbot / main
    +
    +

    main

    + +fun main(args: Array<String>): Unit + + diff --git a/docs/page/kotlindoc/package-list b/docs/page/kotlindoc/package-list new file mode 100644 index 0000000..eaadbbb --- /dev/null +++ b/docs/page/kotlindoc/package-list @@ -0,0 +1,18 @@ +$dokka.format:html +$dokka.linkExtension:html + +it.discordbot +it.discordbot.beans +it.discordbot.beans.boss +it.discordbot.command +it.discordbot.command.BDO +it.discordbot.command.BDO.RSS +it.discordbot.command.BDO.boss +it.discordbot.command.generalCommand +it.discordbot.command.music +it.discordbot.command.music.config +it.discordbot.command.pattern +it.discordbot.command.tpl.atmAlert +it.discordbot.core +it.discordbot.database.filter +it.discordbot.database.repository diff --git a/docs/page/kotlindoc/style.css b/docs/page/kotlindoc/style.css new file mode 100644 index 0000000..914be69 --- /dev/null +++ b/docs/page/kotlindoc/style.css @@ -0,0 +1,283 @@ +@import url(https://fonts.googleapis.com/css?family=Open+Sans:300i,400,700); + +body, table { + padding:50px; + font:14px/1.5 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif; + color:#555; + font-weight:300; + margin-left: auto; + margin-right: auto; + max-width: 1440px; +} + +.keyword { + color:black; + font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + font-size:12px; +} + +.symbol { + font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + font-size:12px; +} + +.identifier { + color: darkblue; + font-size:12px; + font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; +} + +h1, h2, h3, h4, h5, h6 { + color:#222; + margin:0 0 20px; +} + +p, ul, ol, table, pre, dl { + margin:0 0 20px; +} + +h1, h2, h3 { + line-height:1.1; +} + +h1 { + font-size:28px; +} + +h2 { + color:#393939; +} + +h3, h4, h5, h6 { + color:#494949; +} + +a { + color:#258aaf; + font-weight:400; + text-decoration:none; +} + +a:hover { + color: inherit; + text-decoration:underline; +} + +a small { + font-size:11px; + color:#555; + margin-top:-0.6em; + display:block; +} + +.wrapper { + width:860px; + margin:0 auto; +} + +blockquote { + border-left:1px solid #e5e5e5; + margin:0; + padding:0 0 0 20px; + font-style:italic; +} + +code, pre { + font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + color:#333; + font-size:12px; +} + +pre { + display: block; +/* + padding:8px 8px; + background: #f8f8f8; + border-radius:5px; + border:1px solid #e5e5e5; +*/ + overflow-x: auto; +} + +table { + width:100%; + border-collapse:collapse; +} + +th, td { + text-align:left; + vertical-align: top; + padding:5px 10px; +} + +dt { + color:#444; + font-weight:700; +} + +th { + color:#444; +} + +img { + max-width:100%; +} + +header { + width:270px; + float:left; + position:fixed; +} + +header ul { + list-style:none; + height:40px; + + padding:0; + + background: #eee; + background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); + background: -webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); + background: -o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); + background: -ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); + background: linear-gradient(top, #f8f8f8 0%,#dddddd 100%); + + border-radius:5px; + border:1px solid #d2d2d2; + box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0; + width:270px; +} + +header li { + width:89px; + float:left; + border-right:1px solid #d2d2d2; + height:40px; +} + +header ul a { + line-height:1; + font-size:11px; + color:#999; + display:block; + text-align:center; + padding-top:6px; + height:40px; +} + +strong { + color:#222; + font-weight:700; +} + +header ul li + li { + width:88px; + border-left:1px solid #fff; +} + +header ul li + li + li { + border-right:none; + width:89px; +} + +header ul a strong { + font-size:14px; + display:block; + color:#222; +} + +section { + width:500px; + float:right; + padding-bottom:50px; +} + +small { + font-size:11px; +} + +hr { + border:0; + background:#e5e5e5; + height:1px; + margin:0 0 20px; +} + +footer { + width:270px; + float:left; + position:fixed; + bottom:50px; +} + +@media print, screen and (max-width: 960px) { + + div.wrapper { + width:auto; + margin:0; + } + + header, section, footer { + float:none; + position:static; + width:auto; + } + + header { + padding-right:320px; + } + + section { + border:1px solid #e5e5e5; + border-width:1px 0; + padding:20px 0; + margin:0 0 20px; + } + + header a small { + display:inline; + } + + header ul { + position:absolute; + right:50px; + top:52px; + } +} + +@media print, screen and (max-width: 720px) { + body { + word-wrap:break-word; + } + + header { + padding:0; + } + + header ul, header p.view { + position:static; + } + + pre, code { + word-wrap:normal; + } +} + +@media print, screen and (max-width: 480px) { + body { + padding:15px; + } + + header ul { + display:none; + } +} + +@media print { + body { + padding:0.4in; + font-size:12pt; + color:#444; + } +} From 122378b79268596586ddb25fae6dcdf1f58ff759 Mon Sep 17 00:00:00 2001 From: samuele794 Date: Sat, 18 May 2019 23:31:47 +0200 Subject: [PATCH 12/12] Bug Fix, Fixato BDO Boss 4500 Aggiunto Help Comandi ATM Corretto Rilevamento Tweet di ATM --- .../it/discordbot/command/BDO/boss/BossUtil.kt | 2 +- .../command/generalCommand/GeneralCommand.kt | 3 +++ .../command/tpl/atmAlert/ATMTwitterScheduler.kt | 12 ++++++++++-- src/main/resources/application.properties | 1 + 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt b/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt index 748f9a7..fbfbf81 100644 --- a/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt +++ b/src/main/kotlin/it/discordbot/command/BDO/boss/BossUtil.kt @@ -102,7 +102,7 @@ class BossUtil { publish(this?.nomeBoss, "5") } - 0 -> getHourBoss(ora + 1, 0, giorno?.bosses).apply { + 0 -> getHourBoss(ora, 0, giorno?.bosses).apply { publish(this?.nomeBoss, "0") } } diff --git a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt index 40d7615..1192ec9 100644 --- a/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt +++ b/src/main/kotlin/it/discordbot/command/generalCommand/GeneralCommand.kt @@ -4,6 +4,7 @@ import it.discordbot.command.BDO.BDOCommand import it.discordbot.command.checkAdminPermission import it.discordbot.command.checkCommand import it.discordbot.command.rejectCommand +import it.discordbot.command.tpl.atmAlert.ATMCommand import it.discordbot.core.JDAController import it.discordbot.database.filter.ServerManagementInterface import net.dv8tion.jda.core.EmbedBuilder @@ -91,6 +92,8 @@ class GeneralCommand : ListenerAdapter() { addField(symbolCommand + BDOCommand.BDO_BOSS_START_COMMAND, BDOCommand.BDO_BOSS_START_COMMAND_DESCRIPTION, false) addField(symbolCommand + BDOCommand.BDO_BOSS_STOP_COMMAND, BDOCommand.BDO_BOSS_STOP_COMMAND_DESCRIPTION, false) addField(symbolCommand + BDOCommand.BDO_BOSS_TABLE, BDOCommand.BDO_BOSS_TABLE_COMMAND_DESCRIPTION, false) + addField(symbolCommand + ATMCommand.ATM_START_COMMAND, ATMCommand.ATM_START_COMMAND_DESCRIPTION, false) + addField(symbolCommand + ATMCommand.ATM_STOP_COMMAND, ATMCommand.ATM_STOP_COMMAND_DESCRIPTION, false) }.build() } diff --git a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt index b44d724..04c41d7 100644 --- a/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt +++ b/src/main/kotlin/it/discordbot/command/tpl/atmAlert/ATMTwitterScheduler.kt @@ -39,8 +39,14 @@ class ATMTwitterScheduler { fun initATMTwitterScheduler() { val listener = object : StatusListener { override fun onStatus(status: Status) { - if (status.user.id == ATM_TWITTER_ID && status.isRetweet) { - TakaoLog.logInfo("ATMUSERID = " + status.user.screenName + " " + status.user.id + "\nMESSAGE = " + status.text) + TakaoLog.logInfo("ATMUSERID = " + status.user.screenName + " " + status.user.id + "\nMESSAGE = " + status.text) + + TakaoLog.logInfo("ATM IN REPLY USER ID = " + status.inReplyToUserId) + TakaoLog.logInfo("ATM IN REPLY STATUS ID = " + status.inReplyToStatusId) + TakaoLog.logInfo("ATM IN REPLY SCREEN NAME ID = " + status.inReplyToScreenName) + if (status.user.id == ATM_TWITTER_ID && !status.isRetweet + &&(status.inReplyToUserId == -1L || status.inReplyToUserId == ATM_TWITTER_ID)) { + TakaoLog.logInfo("ATMUSERID = " + status.user.screenName + " " + status.user.id + "\nMESSAGE = " + status.text + "\n PASSATO PER PROCESSAZIONE") thread(start = true) { val tweetID: Long @@ -110,6 +116,8 @@ class ATMTwitterScheduler { twitterMessage.contains("sciopero", ignoreCase = true) || twitterMessage.contains("manifestazione", ignoreCase = true) || twitterMessage.contains("aggiornamento", ignoreCase = true)) { + TakaoLog.logInfo("INIZIO PUBBLICAZIONE ATM TWITTER") + val message = EmbedBuilder().apply { setAuthor("ATM (@atm_informa)", tweetUrl, profileImageUrl) setDescription(twitterMessage) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8341fd0..d2669a8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -6,6 +6,7 @@ spring.profiles.active=dev logging.level.root=INFO logging.level.org.springframework.web=DEBUG logging.level.org.hibernate=ERROR +logging.level.kotlin.it.discordbot = DEBUG spring.output.ansi.enabled=always #logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n