From d3f0d0361725b69adabaf86d6ac444ceb4939ccc Mon Sep 17 00:00:00 2001 From: Kaoss BassCannon Date: Mon, 25 May 2015 00:00:21 +1000 Subject: [PATCH] Base Files All Files Works 100% --- .classpath | 10 ++ .project | 17 ++ .settings/org.eclipse.jdt.core.prefs | 11 ++ README.md | 14 ++ .../mccoder/com/AbstractConfigHandler.class | Bin 0 -> 1181 bytes bin/me/mccoder/com/AntiBook.class | Bin 0 -> 3949 bytes bin/me/mccoder/com/BookFilter.class | Bin 0 -> 464 bytes bin/me/mccoder/com/BookListener$1.class | Bin 0 -> 2635 bytes bin/me/mccoder/com/BookListener.class | Bin 0 -> 3840 bytes bin/me/mccoder/com/ConfigHandler.class | Bin 0 -> 3686 bytes bin/me/mccoder/com/FilterCommand.class | Bin 0 -> 2685 bytes bin/me/mccoder/com/IBookFilter.class | Bin 0 -> 466 bytes bin/me/mccoder/com/v1_8_R1/BookFilter.class | Bin 0 -> 8487 bytes bin/me/mccoder/com/v1_8_R2/BookFilter.class | Bin 0 -> 8718 bytes bin/me/mccoder/com/v1_8_R3/BookFilter.class | Bin 0 -> 8718 bytes plugin.yml | 10 ++ src/me/mccoder/com/AbstractConfigHandler.java | 34 ++++ src/me/mccoder/com/AntiBook.java | 90 ++++++++++ src/me/mccoder/com/BookFilter.java | 18 ++ src/me/mccoder/com/BookListener.java | 79 +++++++++ src/me/mccoder/com/ConfigHandler.java | 90 ++++++++++ src/me/mccoder/com/FilterCommand.java | 56 ++++++ src/me/mccoder/com/IBookFilter.java | 18 ++ src/me/mccoder/com/v1_8_R1/BookFilter.java | 161 ++++++++++++++++++ src/me/mccoder/com/v1_8_R2/BookFilter.java | 161 ++++++++++++++++++ src/me/mccoder/com/v1_8_R3/BookFilter.java | 161 ++++++++++++++++++ 26 files changed, 930 insertions(+) create mode 100644 .classpath create mode 100644 .project create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 README.md create mode 100644 bin/me/mccoder/com/AbstractConfigHandler.class create mode 100644 bin/me/mccoder/com/AntiBook.class create mode 100644 bin/me/mccoder/com/BookFilter.class create mode 100644 bin/me/mccoder/com/BookListener$1.class create mode 100644 bin/me/mccoder/com/BookListener.class create mode 100644 bin/me/mccoder/com/ConfigHandler.class create mode 100644 bin/me/mccoder/com/FilterCommand.class create mode 100644 bin/me/mccoder/com/IBookFilter.class create mode 100644 bin/me/mccoder/com/v1_8_R1/BookFilter.class create mode 100644 bin/me/mccoder/com/v1_8_R2/BookFilter.class create mode 100644 bin/me/mccoder/com/v1_8_R3/BookFilter.class create mode 100644 plugin.yml create mode 100644 src/me/mccoder/com/AbstractConfigHandler.java create mode 100644 src/me/mccoder/com/AntiBook.java create mode 100644 src/me/mccoder/com/BookFilter.java create mode 100644 src/me/mccoder/com/BookListener.java create mode 100644 src/me/mccoder/com/ConfigHandler.java create mode 100644 src/me/mccoder/com/FilterCommand.java create mode 100644 src/me/mccoder/com/IBookFilter.java create mode 100644 src/me/mccoder/com/v1_8_R1/BookFilter.java create mode 100644 src/me/mccoder/com/v1_8_R2/BookFilter.java create mode 100644 src/me/mccoder/com/v1_8_R3/BookFilter.java diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..9438ccd --- /dev/null +++ b/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..6cac1a3 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + AntiBook + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a21537 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/README.md b/README.md new file mode 100644 index 0000000..c319c56 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# HeroVerseMC +HeroVerseMC's new plugin. + + +# Copyright +Copyright (C) 2015 - Samuel McCoder and the HeroVerseMC's project team - All Rights Reserved
+If you have any issues or questions about this repository, please leave a post in this repositories issues section, which can be found here.
+Ensure to read the license section below before using any of this project.
+ + +# License ++Licensed under the Apache License, Version 2.0 (Apache-2.0); you may not use this file except in compliance with the License. You may obtain a copy of the License at +
http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/bin/me/mccoder/com/AbstractConfigHandler.class b/bin/me/mccoder/com/AbstractConfigHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..cbaa1b2a9036be27fc10aa4473164136b2e77c37 GIT binary patch literal 1181 zcmb7EZEw<06n-vr>nL|aH=PVYMK^>_xz6cg#F&^Ziyw$H(O}}YOIxs8X-O$d{8=Ur zqaXYM{wU+QZ52#3fhK*q=brOC&w081@$=hv0FQ8>Bg3#gaKyl}0^13N6%53S?kEbS z6&(hC&+WgIzU?`o4vpc`sXUj$lYU>EbWa^CVptw}3PpHcXVO@<4U>AO6^4Q+z$cjg2p-S_E!Fy$-7 zIybON*jt2GA+{>zy@O)R%@fp=o5t)9;}hCZj7CDZ&oD(bV#Q_3pfZDEBq*Au>P*Ga ORC@@4(eFs*|M(Yn(;P7X literal 0 HcmV?d00001 diff --git a/bin/me/mccoder/com/AntiBook.class b/bin/me/mccoder/com/AntiBook.class new file mode 100644 index 0000000000000000000000000000000000000000..728efeda62fc9f572fb59190a4c3c57115e20523 GIT binary patch literal 3949 zcmb7H`Bxj)75*Lwj}QaFGTyL*g&hYW12Q;GY>TAEfNQycsYOU|THAv(h%sV@NF(ah zb(1FDn>J0-CXKtVv`LpFwPh2Uv`LdLj=T3?=;^Qhp+B|fUq6)#pc?fmY7r2)Wymn~k^JnWo*mOBGrB-<$VzINaV=}eb#c>Y zPa8Rbt(C$`7E)5JWeylQc_)A-Y*MgMV7BFso1hZub7sCpM%G~cNsA2?+ub&?3&uBTqc0-vrolP=$9})^qFppQ_=NzdR zlOArA_chZp4d%3rN&r!etGEyMGcCy2j+-g{-0>-TBOGs!%j1(O9>Dvle=a|nbFd(= zDIAX%Ve56QBtIp|PfHWmqR>=Kf{yl2Yq@C&Kc^bS{oq8I?>@c%^oefCDXn4}25Xl7 zU|!46k@!NVfX>r4vsX0|}S9wB| zrCpJT#r|`6Lc!;$!&)V%NUGusvd-71+y>;zs>4(GqJpOdnkyjTX^|?vgl8nyR|+)y z!&)VXWkcfT%PMNHE`W>ps)Dbu2UqYfYt|~hCS6mmKb40KrNhB_-L!LlydP1#jFKbXT1sNdT|oO{wr(Bn(%o zxBP07UjGe#r{K4Iba*hns#q1*@U{z>!E<^tZ(D3EZDo&{(!HVYbE)UyFx$D12h>Fm(|v3&?Z^&pPwY z1)S*&W}JEN0>&asFek2H?lK-M*_!JpAisbVkIwPvLpL79d32sf7j8W2a=CmY_)*EF zw0Mk@9R+-xTh+Z+@hN)v@hWV44yPiQT)~TYk}j8vOL(?`=N9pG@A}(|_&(QH@H~G% zmfQ~dT;^@T7v0!w^|`^3<8pMW9SCHxo&MO)ShNrhAx5K>tDR`aF4(vo52Fo_vj;wb z2#duYEHHl0qYIabsW-3}Z}A2C7wp5|`G4C#_-6el?!v!tKnNTZ>k$*JxLfSzOS2t) zB8tP}I0l^PMT*)1V;6*a`=FW)ca!tt?S@w&U4;2*(MuI;t;MFC(F17kq0l!{RCqRxsf_XRQ n;TBxx#y(NWjW}7tb;;@v#LFM6QOWIoa+_F%n_#e{1%Lf7W{3;V literal 0 HcmV?d00001 diff --git a/bin/me/mccoder/com/BookFilter.class b/bin/me/mccoder/com/BookFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..9505ddac1f097f16e585a13bdec0f6f80f8ea696 GIT binary patch literal 464 zcmaixKTpFj5XIjW+LDyg0%Blbg?7OUTPq|wAdrF>BC)5&L~j0Aa-2$hH3mKa9}01C zkchf4S$g-o^SyUp-yfd@n6SpD@s;Br0gi!b literal 0 HcmV?d00001 diff --git a/bin/me/mccoder/com/BookListener$1.class b/bin/me/mccoder/com/BookListener$1.class new file mode 100644 index 0000000000000000000000000000000000000000..7205a960778bb96fec14e9a80b4e3a50f1fb45ff GIT binary patch literal 2635 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 Z&5gbx60s5d&40d$>wHT*5Aw~w{{dR~HI4uP literal 0 HcmV?d00001 diff --git a/bin/me/mccoder/com/ConfigHandler.class b/bin/me/mccoder/com/ConfigHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..93096c427ea776c914ac9920ad4d211884252339 GIT binary patch literal 3686 zcma)9X?Gjd8GdfONR}swBa*l{kPIb@?2w2M5(0LT%Cc;$k)>3UZ4_G6u{4$^9?uwQ zWCLC30^KRyR|=sUU1$pdJ4re1={fz@-_+CgxicesER?qXpt$Xie1&~@ru0?PukX^QJdDRs;SpQ=oUEI#*tWPICZV!?BEpWznUmc zmnYMiVk$2X&0N>kw798RwRpj)8&+*pU^hh?j%GP?n%UID=o7f7Vj7j@GSwNjRbDhq zN3RP+TwT+-xl}$3g@Q}=nqDuj=#7R}(*+dwd_IxSrn6IF?Bz~nNps5UTHT^4fdQ8x zmn|prsYEfI%Z3pZ*e}hjX^wuHwkma9lSW(G$V}deFb+^W$Vk3w%cY6b_$&>6NTAQO zYvroG(4@7XHGEtLl`p5W zleq{k;E50(Z`pK_PSoq#a}5Qf7^B}>Ln1G5EcR3Y-rT}4S`&2xCGZrm7P;HJdA{$xJ$VMa^Z^M7C6%W{s-ptja|}9na;i zJP^jDz*$vIJ8nKT!)mC;R)VX#%I;H{%~f0G+F;t3wED_o)0Cc0D^M{+urh|FXPYYv zdcCMEm@KVm#;$1QoK`m^?Qiyu`3bu}ma*%#_(F4e*>K{kX0v8k@vH7nRZ!y1Qnk*tE6kgyv|{`B?>Xn5QV~m}5rZOiK1sS-GTcQwH&7=eyj2#cIX0r!*a!=!E6bp=Z>IF&hJt%k`_m5>vW!-FXB zShgEeb0U_!tIt7W67ppQA4YEoD;&0Nk8byij6VVswoLr0z`cG5E(h(IY!^;QmWNbC z-yW3V3pfgzSQFU8@TKQl6C@h@0B|8ZD=^qT9LAf5$r~qvbv!SP5BCw4Pb>HgKFiUP zPqCX01}kF=AEtjDpHuL8d_ng4>Z)#WIG+k)zq8E)aQH??`|%>a6v9gkU>gvLg@P~R zE40tB1P;W~elV^IU#m3#HEI6qZB};{P6w+}@?{0z#4GFx$M*PH1ue(|BCdzuR`4Bs zm)Vz)78!Mf+m~KfzCVTQR(G+ctHLci({^ za;+Gy$#nlr!BHHOtJf7A_f~HxIDumVf+Z@_Y^8#uRhDP8Re#v@Yt`z6zNj@#ry)(g zso*#GElqCk%TNN5_$C88t=Kq{evdzd@Rq>7?eg&*SMW#tNg%W)9}+n>)4|xaV77cV z4yge~%OS!h+PVObw;*(e$Pze78Cre$?Q-xA@G+rq6M9&mTz0tFUQYd<^a2t=ki;DvxkLR-FNl2cg z zCO~!N4tiY3;VQYwkB=cw9o;Cj0unM=QrC@$E;WX#W!+0HM0w~<@Q8<^kS9mIG zI4FF*U3j9SFfYgd;=wcRO41#byo>ibc<}05ZSH3~3U722eyv@&&{24^qwtM(;U_x^ J-*WxC{U0*$S|9)b literal 0 HcmV?d00001 diff --git a/bin/me/mccoder/com/FilterCommand.class b/bin/me/mccoder/com/FilterCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..7d50707f621e228a0f0b2cd27ea7c24675f2befb GIT binary patch literal 2685 zcmai0TXPd-7=FIA&8F!Vq#RQzE?6`@5d;Kn0BuW=LJ!b}B1OebvQ4(#?3Ue4A)b%? z0Ph&DoN?p^FJ!b#bv#~hq4(Z7PJf18Fg{;4v`I^FCWqa9&(HI{@4LT0`2HsVM{rX? zNMLutNE9*|Cu_Kgj8jOQHZ9+9hnzw|x3dZw1)iAG7xjdt+quL>W95Y5g4 z9Ac7DG@w;QGd2k{#Ji@O!30$(hzM*RHEm5vcK-;L3(XDCSHRXNfVWXcn zJ%K&zgVj{dyqX=mQjoxGe6)VOQ-)3Sl8@0yj;>)i<-4YxOJ3RdsB0#QU1(Pj6KJm= zPQ{bhEuiEKe_SuH%5Cwkjm{$2LuhBqY(}ABpMt$LTn2flcp9C2Zd@zsmN$~K9oHDr zJ$l_9-{`b!CW2=Ov`+TYWbZ)WzXfr0E9er?>Zcu`q@qX0Yt8H4dBZK3o@Y9?f)tNRB;r?0$fw21tPGs*7=yu#xQj&*^C#FRM0Q5waVi|v5Mn3A)sEG97&~y z$FB}fOq?T{)oDIdWo|EFK*7t5Ri{5x3}T39k#z^>lVvcib=o7cl>&LP1;cnn!D*hM z`dTW^U_>Aq@F%SW25ZjvqoDj>tR+?FRE%Pb07$AH@*xnf1#``PK=P_4^Pj*41?L4i ztI(~huVNBYWKGXzCFcT1<5#M&UNc-f5|wr-`lgjQqkH)=eSv&lBn#`?bg*bz?CmI0 zXl=%;m{D+<4Of-eP+s?k9LsT4T)}IcQUez*4hZb1&S6!Dgs1R^imP~&&8aUeaB>Lr zRd-r2Vv`#?x{^vVg0#TN0WF};$ZCs*E1O7jW;Hq4G})LM`%6n3hOK#qulbHva*D3D ziiJ!gE7Ra9uZdn6PW7Wp%bbe5oInxZ3G`+E P)CD7urrZL0w^jy6mG93X|!ok#P zvRTLQG~4mDjAQ${X=}P&(oD-Ta=N9RothY@AZtkc7gSu6C^t+FpNfD}{P1O`s1=Hy zujL&ptLfTx*YthXT}FYf%7y1SEF=m6W)Tzxy364!n@h{+#Lu=$#7rxC1T|fvuZ8mb z;n)nzq6{vyebuzCTYHr?z_VBpaHBm&of}55fVPcOmL9zFlAw6&BlZOI2{L1gR|lw> znsnbNG2l$D)>%CQRTGl&Y~y+`1X{~OlMPW>meDC5oQ%QQLN?p@xAt;yKsF2ZasfB+ z+r)31+{1jg2=TfZQU12@?lkX1{Ev3ugWBEm9X5Yc*4e_}O|%8Jpb=YXv5g*p9f3BV zY~vm6%3g^Uwo_L2DZXYr8EK_=2|L?5mhjXq{MpmCe;Ln)a0`F*{EFUNxZU#$di$GV zP0KhS&>xP4@1qzCFX7N#yzmv~y1&KdC7g_fmvJhDekG>d$1$mWmf-!!v(*q&rj{`t z!lj-ckh**i(|2)c39q;5OUNu?b{S>}w=uI$TBwm8Uz0l0)~%85Sts?Yq>XnP?y$%P z0wiISzq_y#?bw6e=tKwlcy)ryeT+0ra+Bxz^keMDO*Z5g=*E}S_!$ZOhC}#^uY7-V z#Yu=K1MpTMUcn-+6Iud_8z_|tSixI(yG+jt-od-1s1u*#J-koo`|ue)z=sGkata^u gN?}|{UDE^kUfHYQFhBpI;~#XiOX@zMG=xw815Y~ea{vGU literal 0 HcmV?d00001 diff --git a/bin/me/mccoder/com/IBookFilter.class b/bin/me/mccoder/com/IBookFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..b7a26f13d83ce546db61ff3ee77beb404d1e3959 GIT binary patch literal 466 zcmaixy-ve06ot<%w4p790%Ad8g?7OUTM-f+5S4-$BC)5&SZ;nSIZh;Aje!T?p%AwY zL)3-I(mkJ#?>YYd`TPQKi_-`_!bPD(A*Fp&PDopb)zaGR(d1sa2>XQTCT&uYr==Dz z>y470Fszi1t=7sBE@yE7YHxCp^UyHZii`OxVa)84ZIpYiG~xV@4t9xm36BAzIKXmy-VD+t8~rp!>!SK$g@pGSk7YWv{=_!X1p+Eqe^ex zhgf-4BtDhdV*VdMxatOJd*N%lRV@gk#MVwK4#yi$JLTSN;Q@iL$G-vex$8a#*mfS_ bAe=*tSRb?6!y(TnI12L#j(Ns@K{@#a97=)x literal 0 HcmV?d00001 diff --git a/bin/me/mccoder/com/v1_8_R1/BookFilter.class b/bin/me/mccoder/com/v1_8_R1/BookFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..f60774e9bfd0ad02140805c390089f9f248cbe04 GIT binary patch literal 8487 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 literal 0 HcmV?d00001 diff --git a/bin/me/mccoder/com/v1_8_R2/BookFilter.class b/bin/me/mccoder/com/v1_8_R2/BookFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..78370cdd59c6b91ac5e6cddfa5dabc0496dbd847 GIT binary patch literal 8718 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 literal 0 HcmV?d00001 diff --git a/bin/me/mccoder/com/v1_8_R3/BookFilter.class b/bin/me/mccoder/com/v1_8_R3/BookFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..0151d5da405e992e78d7e777b65d4896ae51f055 GIT binary patch literal 8718 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 literal 0 HcmV?d00001 diff --git a/plugin.yml b/plugin.yml new file mode 100644 index 0000000..b04de57 --- /dev/null +++ b/plugin.yml @@ -0,0 +1,10 @@ +name: AntiBook +version: 1.0 +main: me.mccoder.com.AntiBook +author: McCoder +description: Fixes an exploit with JSON books +commands: + filter: + aliases: [bookfilter, filterbook] + usage: / + permission: antibook.filter \ No newline at end of file diff --git a/src/me/mccoder/com/AbstractConfigHandler.java b/src/me/mccoder/com/AbstractConfigHandler.java new file mode 100644 index 0000000..df7a1e6 --- /dev/null +++ b/src/me/mccoder/com/AbstractConfigHandler.java @@ -0,0 +1,34 @@ +package me.mccoder.com; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.FileConfigurationOptions; +import org.bukkit.plugin.Plugin; + +public abstract class AbstractConfigHandler +{ + protected final Plugin plugin; + protected FileConfiguration config; + + public AbstractConfigHandler(Plugin plugin) + { + this.plugin = plugin; + } + + public void loadConfig() + { + this.config = this.plugin.getConfig(); + this.config.options().copyDefaults(true); + addDefaults(); + saveConfig(); + loadData(); + } + + public void saveConfig() + { + this.plugin.saveConfig(); + } + + protected abstract void loadData(); + + protected abstract void addDefaults(); +} diff --git a/src/me/mccoder/com/AntiBook.java b/src/me/mccoder/com/AntiBook.java new file mode 100644 index 0000000..e94780c --- /dev/null +++ b/src/me/mccoder/com/AntiBook.java @@ -0,0 +1,90 @@ +package me.mccoder.com; + +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.Bukkit; +import org.bukkit.command.PluginCommand; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitScheduler; + +public class AntiBook + extends JavaPlugin +{ + ConfigHandler config; + IBookFilter filter; + + public void onDisable() + { + Bukkit.getScheduler().cancelTasks(this); + + PluginDescriptionFile desc = getDescription(); + getLogger().log(Level.INFO, "{0} vers. {1} by McCoder deactivated", new String[] { desc.getName(), desc.getVersion() }); + } + + public void onEnable() + { + boolean enable = true; + + loadConfig(); + + String version = Bukkit.getServer().getClass().getCanonicalName(); + version = version.substring(0, version.lastIndexOf('.')); + version = version.substring(version.lastIndexOf('.') + 1); + switch (version) + { + case "v1_8_R1": + this.filter = new me.mccoder.com.v1_8_R1.BookFilter(); + getLogger().log(Level.INFO, "Detected supported server version {0}", version); + break; + case "v1_8_R2": + this.filter = new me.mccoder.com.v1_8_R2.BookFilter(); + getLogger().log(Level.INFO, "Detected supported server version {0}", version); + break; + case "v1_8_R3": + this.filter = new me.mccoder.com.v1_8_R3.BookFilter(); + getLogger().log(Level.INFO, "Detected supported server version {0}", version); + break; + default: + getLogger().log(Level.SEVERE, "Unsupported server version {0}. Disabling plugin.", version); + getLogger().log(Level.SEVERE, "Please check for updates at {0}", getDescription().getWebsite()); + enable = false; + Bukkit.getPluginManager().disablePlugin(this); + } + if (enable) + { + this.filter.setLogger(getLogger()); + this.filter.setHoverMsg(this.config.getHoverMsg()); + this.filter.setFilterActions(this.config.getFilterActions()); + + registerCommands(); + + registerEvents(); + + PluginDescriptionFile desc = getDescription(); + getLogger().log(Level.INFO, "{0} vers. {1} by McCoder activated", new String[] { desc.getName(), desc.getVersion() }); + } + } + + private void loadConfig() + { + this.config = new ConfigHandler(this); + this.config.loadConfig(); + } + + public IBookFilter getFilter() + { + return this.filter; + } + + private void registerCommands() + { + getCommand("filter").setExecutor(new FilterCommand(this)); + } + + private void registerEvents() + { + Bukkit.getPluginManager().registerEvents(new BookListener(this), this); + } +} diff --git a/src/me/mccoder/com/BookFilter.java b/src/me/mccoder/com/BookFilter.java new file mode 100644 index 0000000..c2d5e93 --- /dev/null +++ b/src/me/mccoder/com/BookFilter.java @@ -0,0 +1,18 @@ +package me.mccoder.com; + +import java.util.List; +import java.util.logging.Logger; +import org.bukkit.inventory.ItemStack; + +public abstract interface BookFilter +{ + public abstract void setLogger(Logger paramLogger); + + public abstract void setHoverMsg(String paramString); + + public abstract void setFilterActions(List paramList); + + public abstract ItemStack filterBook(ItemStack paramItemStack); + + public abstract Object filterBook(Object paramObject); +} diff --git a/src/me/mccoder/com/BookListener.java b/src/me/mccoder/com/BookListener.java new file mode 100644 index 0000000..c15b5ca --- /dev/null +++ b/src/me/mccoder/com/BookListener.java @@ -0,0 +1,79 @@ +package me.mccoder.com; + +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerEditBookEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitScheduler; + +public class BookListener + implements Listener +{ + private final AntiBook plugin; + + public BookListener(AntiBook plugin) + { + this.plugin = plugin; + } + + @EventHandler(priority=EventPriority.LOW) + public void onBookEdit(final PlayerEditBookEvent event) + { + if (this.plugin.config.isOnCreation()) { + Bukkit.getScheduler().runTaskLater(this.plugin, new Runnable() + { + public void run() + { + Inventory inv = event.getPlayer().getInventory(); + for (int i = 0; i < inv.getSize(); i++) + { + ItemStack item = inv.getItem(i); + if ((item != null) && (item.getType() == Material.WRITTEN_BOOK)) + { + if (BookListener.this.plugin.config.isDebug()) { + BookListener.this.plugin.getLogger().log(Level.INFO, "Filtering edited ItemStack: {0}", item); + } + ItemStack filtered = BookListener.this.plugin.getFilter().filterBook(item); + if (filtered != null) + { + BookListener.this.plugin.getLogger().log(Level.WARNING, "Player {0} {1} created a book with illegal JSON content!", new Object[] { event.getPlayer().getName(), event.getPlayer().getUniqueId() }); + + inv.setItem(i, filtered); + } + } + } + } + }, 4L); + } + } + + @EventHandler(priority=EventPriority.LOW) + public void onBookRead(PlayerInteractEvent event) + { + if ((this.plugin.config.isOnRead()) && ((event.getAction() == Action.RIGHT_CLICK_AIR) || (event.getAction() == Action.RIGHT_CLICK_BLOCK)) && (event.getItem() != null) && (event.getItem().getType() == Material.WRITTEN_BOOK) && (!event.getPlayer().hasPermission("antibook.overridefilter"))) + { + if (this.plugin.config.isDebug()) { + this.plugin.getLogger().log(Level.INFO, "Filtering read ItemStack: {0}", event.getPlayer().getItemInHand()); + } + ItemStack filtered = this.plugin.getFilter().filterBook(event.getPlayer().getItemInHand()); + if (filtered != null) + { + this.plugin.getLogger().log(Level.WARNING, "Player {0} {1} just tried to read a book with illegal JSON content!", new Object[] { event.getPlayer().getName(), event.getPlayer().getUniqueId() }); + + event.getPlayer().setItemInHand(filtered); + for (String line : this.plugin.config.getChatWarning()) { + event.getPlayer().sendMessage(line); + } + } + } + } +} diff --git a/src/me/mccoder/com/ConfigHandler.java b/src/me/mccoder/com/ConfigHandler.java new file mode 100644 index 0000000..0dd1d95 --- /dev/null +++ b/src/me/mccoder/com/ConfigHandler.java @@ -0,0 +1,90 @@ +package me.mccoder.com; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.plugin.Plugin; + +public class ConfigHandler + extends AbstractConfigHandler +{ + private static final String PATH_FILTER = "click_action_filter"; + private static final String PATH_HOVER = "hover_message"; + private static final String PATH_WARNING = "chat_warning"; + private static final String PATH_ON_CREATION = "activate.on_creation"; + private static final String PATH_ON_READ = "activate.on_read"; + private static final String PATH_DEBUG = "log_debug"; + private static final List DEF_FILTER = Arrays.asList(new String[] { "RUN_COMMAND", "OPEN_FILE", "OPEN_URL", "SUGGEST_COMMAND", "TWITCH_USER_INFO" }); + private static final String DEF_HOVER = "Illegal content was filtered from this book"; + private static final List DEF_WARNING = Arrays.asList(new String[] { " ==== WARNING ==== WARNING ==== WARNING ====", "", " DO NOT CLICK ON ANYTHING IN THIS BOOK!", "", " It contains illegal code and is potential harmful", "", " ==== WARNING ==== WARNING ==== WARNING ====" }); + private List filterActions; + private String hoverMsg; + private List chatWarning; + private boolean onCreation; + private boolean onRead; + private boolean debug; + + public ConfigHandler(Plugin plugin) + { + super(plugin); + } + + protected void loadData() + { + this.filterActions = this.config.getStringList("click_action_filter"); + + this.hoverMsg = ChatColor.translateAlternateColorCodes('&', this.config.getString("hover_message")); + + this.chatWarning = new ArrayList(this.config.getStringList("chat_warning")); + for (int i = 0; i < getChatWarning().size(); i++) { + getChatWarning().set(i, ChatColor.RED + ChatColor.translateAlternateColorCodes('&', (String)getChatWarning().get(i))); + } + this.onCreation = this.config.getBoolean("activate.on_creation"); + + this.onRead = this.config.getBoolean("activate.on_read"); + + this.debug = this.config.getBoolean("log_debug"); + } + + protected void addDefaults() + { + this.config.addDefault("click_action_filter", DEF_FILTER); + this.config.addDefault("hover_message", "Illegal content was filtered from this book"); + this.config.addDefault("chat_warning", DEF_WARNING); + this.config.addDefault("activate.on_creation", Boolean.valueOf(true)); + this.config.addDefault("activate.on_read", Boolean.valueOf(true)); + this.config.addDefault("log_debug", Boolean.valueOf(false)); + } + + public List getFilterActions() + { + return this.filterActions; + } + + public String getHoverMsg() + { + return this.hoverMsg; + } + + public List getChatWarning() + { + return this.chatWarning; + } + + public boolean isOnCreation() + { + return this.onCreation; + } + + public boolean isOnRead() + { + return this.onRead; + } + + public boolean isDebug() + { + return this.debug; + } +} diff --git a/src/me/mccoder/com/FilterCommand.java b/src/me/mccoder/com/FilterCommand.java new file mode 100644 index 0000000..03375f7 --- /dev/null +++ b/src/me/mccoder/com/FilterCommand.java @@ -0,0 +1,56 @@ +package me.mccoder.com; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +public class FilterCommand + implements CommandExecutor +{ + private final AntiBook plugin; + + public FilterCommand(AntiBook plugin) + { + this.plugin = plugin; + } + + public boolean onCommand(CommandSender sender, Command command, String s, String[] strings) + { + if ((command.getName().equalsIgnoreCase("filter")) && (sender.hasPermission("antibook.filter"))) + { + if ((sender instanceof Player)) + { + Player player = (Player)sender; + ItemStack book = player.getItemInHand(); + if ((book != null) && (book.getType() == Material.WRITTEN_BOOK)) + { + ItemStack newBook = this.plugin.getFilter().filterBook(book); + if (newBook != null) + { + player.getInventory().addItem(new ItemStack[] { newBook }); + sender.sendMessage(ChatColor.AQUA + "A filtered version of this book has been set to your inventory"); + } + else + { + sender.sendMessage(ChatColor.AQUA + "This book does not contain any illegal JSON code"); + } + } + else + { + sender.sendMessage(ChatColor.RED + "You must hold a written book in your hand to filter"); + } + } + else + { + sender.sendMessage(ChatColor.RED + "This command can only be used by a player!"); + } + return true; + } + return false; + } +} diff --git a/src/me/mccoder/com/IBookFilter.java b/src/me/mccoder/com/IBookFilter.java new file mode 100644 index 0000000..8e9a31b --- /dev/null +++ b/src/me/mccoder/com/IBookFilter.java @@ -0,0 +1,18 @@ +package me.mccoder.com; + +import java.util.List; +import java.util.logging.Logger; +import org.bukkit.inventory.ItemStack; + +public abstract interface IBookFilter +{ + public abstract void setLogger(Logger paramLogger); + + public abstract void setHoverMsg(String paramString); + + public abstract void setFilterActions(List paramList); + + public abstract ItemStack filterBook(ItemStack paramItemStack); + + public abstract Object filterBook(Object paramObject); +} diff --git a/src/me/mccoder/com/v1_8_R1/BookFilter.java b/src/me/mccoder/com/v1_8_R1/BookFilter.java new file mode 100644 index 0000000..923c995 --- /dev/null +++ b/src/me/mccoder/com/v1_8_R1/BookFilter.java @@ -0,0 +1,161 @@ +package me.mccoder.com.v1_8_R1; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import me.mccoder.com.IBookFilter; +import net.minecraft.server.v1_8_R1.ChatClickable; +import net.minecraft.server.v1_8_R1.ChatComponentText; +import net.minecraft.server.v1_8_R1.ChatHoverable; +import net.minecraft.server.v1_8_R1.ChatModifier; +import net.minecraft.server.v1_8_R1.ChatSerializer; +import net.minecraft.server.v1_8_R1.EnumClickAction; +import net.minecraft.server.v1_8_R1.EnumHoverAction; +import net.minecraft.server.v1_8_R1.IChatBaseComponent; +import net.minecraft.server.v1_8_R1.ItemWrittenBook; +import net.minecraft.server.v1_8_R1.NBTTagCompound; +import net.minecraft.server.v1_8_R1.NBTTagList; +import net.minecraft.server.v1_8_R1.NBTTagString; +import org.bukkit.craftbukkit.v1_8_R1.inventory.CraftItemStack; + +public class BookFilter + implements IBookFilter +{ + private static final String PAGES_KEY = "pages"; + private static final int PAGES_KEY_VALUE = 9; + private static final int PAGES_LIST_VALUE = 8; + private Logger logger = Logger.getLogger(BookFilter.class.getName()); + private Set filterActions = EnumSet.of(EnumClickAction.RUN_COMMAND, EnumClickAction.OPEN_FILE, EnumClickAction.OPEN_URL, EnumClickAction.SUGGEST_COMMAND); + private String hoverMsg = "Illegal content was filtered from this book"; + + public org.bukkit.inventory.ItemStack filterBook(org.bukkit.inventory.ItemStack filterItem) + { + Object result = filterBook(CraftItemStack.asNMSCopy(filterItem)); + if (result != null) { + return CraftItemStack.asBukkitCopy((net.minecraft.server.v1_8_R1.ItemStack)result); + } + return null; + } + + public Object filterBook(Object filterItem) + { + if (filterItem == null) { + return null; + } + if (!(filterItem instanceof net.minecraft.server.v1_8_R1.ItemStack)) { + throw new IllegalArgumentException("Expected object of type net.minecraft.server.v1_8_R1.ItemStack. Received " + filterItem.getClass()); + } + net.minecraft.server.v1_8_R1.ItemStack mcStack = (net.minecraft.server.v1_8_R1.ItemStack)filterItem; + try + { + if (!(mcStack.getItem() instanceof ItemWrittenBook)) { + return null; + } + mcStack = mcStack.cloneItemStack(); + + NBTTagCompound tag = mcStack.hasTag() ? mcStack.getTag() : null; + NBTTagList pages = (tag != null) && (tag.hasKeyOfType("pages", 9)) ? tag.getList("pages", 8) : null; + + boolean filtered = false; + for (int i = 0; (pages != null) && (i < pages.size()); i++) + { + String jsonPage = pages.getString(i); + IChatBaseComponent component; + try + { + component = jsonPage != null ? ChatSerializer.a(jsonPage) : null; + } + catch (Exception e) + { + component = null; + this.logger.log(Level.WARNING, "Unable to parse page {0} of book type {1} to IChatBaseComponent.This means it is probably not a JSON book and can be ignored.", new Object[] { Integer.valueOf(i), mcStack.getItem().getClass() }); + + this.logger.log(Level.WARNING, "Page: {0}", jsonPage); + this.logger.log(Level.WARNING, "Original Exception:", e); + } + List subComponents = new ArrayList(); + addComponents(component, subComponents); + + boolean changedPage = false; + for (IChatBaseComponent subComponent : subComponents) + { + ChatModifier modifier = subComponent.getChatModifier(); + ChatClickable clickable = modifier.h(); + if ((clickable != null) && (this.filterActions.contains(clickable.a()))) + { + this.logger.log(Level.WARNING, "Filtered illegal content from item!"); + this.logger.log(Level.WARNING, subComponent.toString()); + + modifier.setChatHoverable(new ChatHoverable(EnumHoverAction.SHOW_TEXT, new ChatComponentText(this.hoverMsg))); + + modifier.setChatClickable(null); + subComponent.setChatModifier(modifier); + + changedPage = true; + filtered = true; + } + } + if (changedPage) + { + jsonPage = ChatSerializer.a(component); + pages.a(i, new NBTTagString(jsonPage)); + } + } + if (filtered) + { + tag.set("pages", pages); + mcStack.setTag(tag); + return mcStack; + } + return null; + } + catch (Throwable e) + { + this.logger.log(Level.SEVERE, "Failed to filter book due to an unexpected exception", e); + } + return null; + } + + private static void addComponents(IChatBaseComponent component, List list) + { + if (component != null) + { + list.add(component); + + List children = component.a(); + if (children != null) { + for (IChatBaseComponent child : children) { + addComponents(child, list); + } + } + } + } + + public void setLogger(Logger logger) + { + this.logger = logger; + } + + public void setHoverMsg(String hoverMsg) + { + this.hoverMsg = hoverMsg; + } + + public void setFilterActions(List actions) + { + this.filterActions = EnumSet.noneOf(EnumClickAction.class); + for (String actionString : actions) { + try + { + this.filterActions.add(EnumClickAction.valueOf(actionString.toUpperCase())); + } + catch (IllegalArgumentException e) + { + this.logger.log(Level.WARNING, "Invalid ActionEnum: {0}", actionString.toUpperCase()); + } + } + } +} diff --git a/src/me/mccoder/com/v1_8_R2/BookFilter.java b/src/me/mccoder/com/v1_8_R2/BookFilter.java new file mode 100644 index 0000000..4f16089 --- /dev/null +++ b/src/me/mccoder/com/v1_8_R2/BookFilter.java @@ -0,0 +1,161 @@ +package me.mccoder.com.v1_8_R2; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import me.mccoder.com.IBookFilter; +import net.minecraft.server.v1_8_R2.ChatClickable; +import net.minecraft.server.v1_8_R2.ChatClickable.EnumClickAction; +import net.minecraft.server.v1_8_R2.ChatComponentText; +import net.minecraft.server.v1_8_R2.ChatHoverable; +import net.minecraft.server.v1_8_R2.ChatHoverable.EnumHoverAction; +import net.minecraft.server.v1_8_R2.ChatModifier; +import net.minecraft.server.v1_8_R2.IChatBaseComponent; +import net.minecraft.server.v1_8_R2.IChatBaseComponent.ChatSerializer; +import net.minecraft.server.v1_8_R2.ItemWrittenBook; +import net.minecraft.server.v1_8_R2.NBTTagCompound; +import net.minecraft.server.v1_8_R2.NBTTagList; +import net.minecraft.server.v1_8_R2.NBTTagString; +import org.bukkit.craftbukkit.v1_8_R2.inventory.CraftItemStack; + +public class BookFilter + implements IBookFilter +{ + private static final String PAGES_KEY = "pages"; + private static final int PAGES_KEY_VALUE = 9; + private static final int PAGES_LIST_VALUE = 8; + private Logger logger = Logger.getLogger(BookFilter.class.getName()); + private Set filterActions = EnumSet.of(ChatClickable.EnumClickAction.RUN_COMMAND, ChatClickable.EnumClickAction.OPEN_FILE, ChatClickable.EnumClickAction.OPEN_URL, ChatClickable.EnumClickAction.SUGGEST_COMMAND); + private String hoverMsg = "Illegal content was filtered from this book"; + + public org.bukkit.inventory.ItemStack filterBook(org.bukkit.inventory.ItemStack filterItem) + { + Object result = filterBook(CraftItemStack.asNMSCopy(filterItem)); + if (result != null) { + return CraftItemStack.asBukkitCopy((net.minecraft.server.v1_8_R2.ItemStack)result); + } + return null; + } + + public Object filterBook(Object filterItem) + { + if (filterItem == null) { + return null; + } + if (!(filterItem instanceof net.minecraft.server.v1_8_R2.ItemStack)) { + throw new IllegalArgumentException("Expected object of type net.minecraft.server.v1_8_R2.ItemStack. Received " + filterItem.getClass()); + } + net.minecraft.server.v1_8_R2.ItemStack mcStack = (net.minecraft.server.v1_8_R2.ItemStack)filterItem; + try + { + if (!(mcStack.getItem() instanceof ItemWrittenBook)) { + return null; + } + mcStack = mcStack.cloneItemStack(); + + NBTTagCompound tag = mcStack.hasTag() ? mcStack.getTag() : null; + NBTTagList pages = (tag != null) && (tag.hasKeyOfType("pages", 9)) ? tag.getList("pages", 8) : null; + + boolean filtered = false; + for (int i = 0; (pages != null) && (i < pages.size()); i++) + { + String jsonPage = pages.getString(i); + IChatBaseComponent component; + try + { + component = jsonPage != null ? IChatBaseComponent.ChatSerializer.a(jsonPage) : null; + } + catch (Exception e) + { + component = null; + this.logger.log(Level.WARNING, "Unable to parse page {0} of book type {1} to IChatBaseComponent.This means it is probably not a JSON book and can be ignored.", new Object[] { Integer.valueOf(i), mcStack.getItem().getClass() }); + + this.logger.log(Level.WARNING, "Page: {0}", jsonPage); + this.logger.log(Level.WARNING, "Original Exception:", e); + } + List subComponents = new ArrayList(); + addComponents(component, subComponents); + + boolean changedPage = false; + for (IChatBaseComponent subComponent : subComponents) + { + ChatModifier modifier = subComponent.getChatModifier(); + ChatClickable clickable = modifier.h(); + if ((clickable != null) && (this.filterActions.contains(clickable.a()))) + { + this.logger.log(Level.WARNING, "Filtered illegal content from item!"); + this.logger.log(Level.WARNING, subComponent.toString()); + + modifier.setChatHoverable(new ChatHoverable(ChatHoverable.EnumHoverAction.SHOW_TEXT, new ChatComponentText(this.hoverMsg))); + + modifier.setChatClickable(null); + subComponent.setChatModifier(modifier); + + changedPage = true; + filtered = true; + } + } + if (changedPage) + { + jsonPage = IChatBaseComponent.ChatSerializer.a(component); + pages.a(i, new NBTTagString(jsonPage)); + } + } + if (filtered) + { + tag.set("pages", pages); + mcStack.setTag(tag); + return mcStack; + } + return null; + } + catch (Throwable e) + { + this.logger.log(Level.SEVERE, "Failed to filter book due to an unexpected exception", e); + } + return null; + } + + private static void addComponents(IChatBaseComponent component, List list) + { + if (component != null) + { + list.add(component); + + List children = component.a(); + if (children != null) { + for (IChatBaseComponent child : children) { + addComponents(child, list); + } + } + } + } + + public void setLogger(Logger logger) + { + this.logger = logger; + } + + public void setHoverMsg(String hoverMsg) + { + this.hoverMsg = hoverMsg; + } + + public void setFilterActions(List actions) + { + this.filterActions = EnumSet.noneOf(ChatClickable.EnumClickAction.class); + for (String actionString : actions) { + try + { + this.filterActions.add(ChatClickable.EnumClickAction.valueOf(actionString.toUpperCase())); + } + catch (IllegalArgumentException e) + { + this.logger.log(Level.WARNING, "Invalid ActionEnum: {0}", actionString.toUpperCase()); + } + } + } +} diff --git a/src/me/mccoder/com/v1_8_R3/BookFilter.java b/src/me/mccoder/com/v1_8_R3/BookFilter.java new file mode 100644 index 0000000..df208e6 --- /dev/null +++ b/src/me/mccoder/com/v1_8_R3/BookFilter.java @@ -0,0 +1,161 @@ +package me.mccoder.com.v1_8_R3; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import me.mccoder.com.IBookFilter; +import net.minecraft.server.v1_8_R3.ChatClickable; +import net.minecraft.server.v1_8_R3.ChatClickable.EnumClickAction; +import net.minecraft.server.v1_8_R3.ChatComponentText; +import net.minecraft.server.v1_8_R3.ChatHoverable; +import net.minecraft.server.v1_8_R3.ChatHoverable.EnumHoverAction; +import net.minecraft.server.v1_8_R3.ChatModifier; +import net.minecraft.server.v1_8_R3.IChatBaseComponent; +import net.minecraft.server.v1_8_R3.IChatBaseComponent.ChatSerializer; +import net.minecraft.server.v1_8_R3.ItemWrittenBook; +import net.minecraft.server.v1_8_R3.NBTTagCompound; +import net.minecraft.server.v1_8_R3.NBTTagList; +import net.minecraft.server.v1_8_R3.NBTTagString; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; + +public class BookFilter + implements IBookFilter +{ + private static final String PAGES_KEY = "pages"; + private static final int PAGES_KEY_VALUE = 9; + private static final int PAGES_LIST_VALUE = 8; + private Logger logger = Logger.getLogger(BookFilter.class.getName()); + private Set filterActions = EnumSet.of(ChatClickable.EnumClickAction.RUN_COMMAND, ChatClickable.EnumClickAction.OPEN_FILE, ChatClickable.EnumClickAction.OPEN_URL, ChatClickable.EnumClickAction.SUGGEST_COMMAND); + private String hoverMsg = "Illegal content was filtered from this book"; + + public org.bukkit.inventory.ItemStack filterBook(org.bukkit.inventory.ItemStack filterItem) + { + Object result = filterBook(CraftItemStack.asNMSCopy(filterItem)); + if (result != null) { + return CraftItemStack.asBukkitCopy((net.minecraft.server.v1_8_R3.ItemStack)result); + } + return null; + } + + public Object filterBook(Object filterItem) + { + if (filterItem == null) { + return null; + } + if (!(filterItem instanceof net.minecraft.server.v1_8_R3.ItemStack)) { + throw new IllegalArgumentException("Expected object of type net.minecraft.server.v1_8_R3.ItemStack. Received " + filterItem.getClass()); + } + net.minecraft.server.v1_8_R3.ItemStack mcStack = (net.minecraft.server.v1_8_R3.ItemStack)filterItem; + try + { + if (!(mcStack.getItem() instanceof ItemWrittenBook)) { + return null; + } + mcStack = mcStack.cloneItemStack(); + + NBTTagCompound tag = mcStack.hasTag() ? mcStack.getTag() : null; + NBTTagList pages = (tag != null) && (tag.hasKeyOfType("pages", 9)) ? tag.getList("pages", 8) : null; + + boolean filtered = false; + for (int i = 0; (pages != null) && (i < pages.size()); i++) + { + String jsonPage = pages.getString(i); + IChatBaseComponent component; + try + { + component = jsonPage != null ? IChatBaseComponent.ChatSerializer.a(jsonPage) : null; + } + catch (Exception e) + { + component = null; + this.logger.log(Level.WARNING, "Unable to parse page {0} of book type {1} to IChatBaseComponent.This means it is probably not a JSON book and can be ignored.", new Object[] { Integer.valueOf(i), mcStack.getItem().getClass() }); + + this.logger.log(Level.WARNING, "Page: {0}", jsonPage); + this.logger.log(Level.WARNING, "Original Exception:", e); + } + List subComponents = new ArrayList(); + addComponents(component, subComponents); + + boolean changedPage = false; + for (IChatBaseComponent subComponent : subComponents) + { + ChatModifier modifier = subComponent.getChatModifier(); + ChatClickable clickable = modifier.h(); + if ((clickable != null) && (this.filterActions.contains(clickable.a()))) + { + this.logger.log(Level.WARNING, "Filtered illegal content from item!"); + this.logger.log(Level.WARNING, subComponent.toString()); + + modifier.setChatHoverable(new ChatHoverable(ChatHoverable.EnumHoverAction.SHOW_TEXT, new ChatComponentText(this.hoverMsg))); + + modifier.setChatClickable(null); + subComponent.setChatModifier(modifier); + + changedPage = true; + filtered = true; + } + } + if (changedPage) + { + jsonPage = IChatBaseComponent.ChatSerializer.a(component); + pages.a(i, new NBTTagString(jsonPage)); + } + } + if (filtered) + { + tag.set("pages", pages); + mcStack.setTag(tag); + return mcStack; + } + return null; + } + catch (Throwable e) + { + this.logger.log(Level.SEVERE, "Failed to filter book due to an unexpected exception", e); + } + return null; + } + + private static void addComponents(IChatBaseComponent component, List list) + { + if (component != null) + { + list.add(component); + + List children = component.a(); + if (children != null) { + for (IChatBaseComponent child : children) { + addComponents(child, list); + } + } + } + } + + public void setLogger(Logger logger) + { + this.logger = logger; + } + + public void setHoverMsg(String hoverMsg) + { + this.hoverMsg = hoverMsg; + } + + public void setFilterActions(List actions) + { + this.filterActions = EnumSet.noneOf(ChatClickable.EnumClickAction.class); + for (String actionString : actions) { + try + { + this.filterActions.add(ChatClickable.EnumClickAction.valueOf(actionString.toUpperCase())); + } + catch (IllegalArgumentException e) + { + this.logger.log(Level.WARNING, "Invalid ActionEnum: {0}", actionString.toUpperCase()); + } + } + } +}