From 55003429acccdae8f2c8098c46d09f423b69f97b Mon Sep 17 00:00:00 2001 From: aucguy Date: Sun, 9 Nov 2014 11:04:21 -0600 Subject: [PATCH 01/20] Updating spc to minecraft 1.7.2 Lots of commands still need to be fixed --- README.md | 2 + resources/mcmod.info | 18 ++ spc1.6.2-src.zip | Bin 0 -> 131588 bytes src/com/sijobe/spc/ModSpc.java | 97 ++++++ src/com/sijobe/spc/command/Ascend.java | 1 + src/com/sijobe/spc/command/BlockReach.java | 5 +- src/com/sijobe/spc/command/Bring.java | 9 +- src/com/sijobe/spc/command/Cannon.java | 5 +- src/com/sijobe/spc/command/Cheats.java | 1 + src/com/sijobe/spc/command/ClearDrops.java | 9 +- src/com/sijobe/spc/command/Damage.java | 1 + src/com/sijobe/spc/command/Descend.java | 1 + src/com/sijobe/spc/command/Difficulty.java | 26 +- src/com/sijobe/spc/command/DoDrops.java | 1 + src/com/sijobe/spc/command/Effect.java | 1 + src/com/sijobe/spc/command/Enchant.java | 1 + src/com/sijobe/spc/command/EnderChest.java | 3 +- src/com/sijobe/spc/command/EnderCrystal.java | 1 + src/com/sijobe/spc/command/Explode.java | 1 + src/com/sijobe/spc/command/Firework.java | 3 +- src/com/sijobe/spc/command/Fly.java | 5 + src/com/sijobe/spc/command/Gamemode.java | 1 + src/com/sijobe/spc/command/Give.java | 16 +- src/com/sijobe/spc/command/Heal.java | 1 + src/com/sijobe/spc/command/Health.java | 1 + src/com/sijobe/spc/command/Help.java | 1 + src/com/sijobe/spc/command/Home.java | 1 + src/com/sijobe/spc/command/Hunger.java | 1 + src/com/sijobe/spc/command/Ignite.java | 8 +- src/com/sijobe/spc/command/InstantMine.java | 3 +- src/com/sijobe/spc/command/Jump.java | 3 +- src/com/sijobe/spc/command/Kill.java | 3 +- src/com/sijobe/spc/command/KillAll.java | 5 +- src/com/sijobe/spc/command/Light.java | 1 + src/com/sijobe/spc/command/LongerLegs.java | 1 + src/com/sijobe/spc/command/Macro.java | 1 + src/com/sijobe/spc/command/MovePlayer.java | 1 + src/com/sijobe/spc/command/Noclip.java | 15 +- src/com/sijobe/spc/command/Path.java | 60 ++-- src/com/sijobe/spc/command/Platform.java | 6 +- src/com/sijobe/spc/command/Repair.java | 1 + src/com/sijobe/spc/command/SPC.java | 1 + src/com/sijobe/spc/command/Scuba.java | 1 + src/com/sijobe/spc/command/SetSpawn.java | 1 + src/com/sijobe/spc/command/SetSpeed.java | 1 + src/com/sijobe/spc/command/Skin.java | 1 + src/com/sijobe/spc/command/Spawn.java | 3 + src/com/sijobe/spc/command/SpawnPortal.java | 9 +- src/com/sijobe/spc/command/Sudo.java | 1 + src/com/sijobe/spc/command/SuperHeat.java | 18 +- src/com/sijobe/spc/command/Teleport.java | 1 + src/com/sijobe/spc/command/Time.java | 1 + src/com/sijobe/spc/command/UsePortal.java | 1 + src/com/sijobe/spc/command/Waypoint.java | 1 + src/com/sijobe/spc/command/Weather.java | 1 + src/com/sijobe/spc/core/Constants.java | 7 +- .../sijobe/spc/hooks/InitialiseCommands.java | 38 ++- src/com/sijobe/spc/hooks/WorldEditCUI.java | 18 +- .../spc/overwrite/ONetServerHandler.java | 100 +++--- .../sijobe/spc/util/CommandBlockHelper.java | 31 +- .../sijobe/spc/util/DynamicClassLoader.java | 2 +- src/com/sijobe/spc/util/ForgeHelper.java | 20 +- src/com/sijobe/spc/util/PathData.java | 23 ++ src/com/sijobe/spc/worldedit/LocalPlayer.java | 120 ------- src/com/sijobe/spc/worldedit/LocalWorld.java | 302 ------------------ .../spc/worldedit/MinecraftBiomeType.java | 61 ---- .../spc/worldedit/MinecraftBiomeTypes.java | 38 --- .../worldedit/PropertiesConfiguration.java | 23 -- .../sijobe/spc/worldedit/ServerInterface.java | 41 --- .../spc/worldedit/WorldEditCommandSet.java | 199 ------------ .../sijobe/spc/worldedit/WorldEditEvents.java | 119 ------- src/com/sijobe/spc/wrapper/Block.java | 52 +++ src/com/sijobe/spc/wrapper/Blocks.java | 15 + src/com/sijobe/spc/wrapper/CommandBase.java | 16 +- .../sijobe/spc/wrapper/CommandManager.java | 4 +- src/com/sijobe/spc/wrapper/CommandSender.java | 10 +- src/com/sijobe/spc/wrapper/Entity.java | 40 +-- src/com/sijobe/spc/wrapper/Item.java | 86 +++-- src/com/sijobe/spc/wrapper/Minecraft.java | 4 +- .../sijobe/spc/wrapper/MinecraftServer.java | 2 +- src/com/sijobe/spc/wrapper/Player.java | 93 +++--- src/com/sijobe/spc/wrapper/Potion.java | 6 +- src/com/sijobe/spc/wrapper/Stats.java | 4 +- src/com/sijobe/spc/wrapper/World.java | 63 ++-- 84 files changed, 663 insertions(+), 1236 deletions(-) create mode 100644 resources/mcmod.info create mode 100644 spc1.6.2-src.zip create mode 100644 src/com/sijobe/spc/ModSpc.java create mode 100644 src/com/sijobe/spc/util/PathData.java delete mode 100644 src/com/sijobe/spc/worldedit/LocalPlayer.java delete mode 100644 src/com/sijobe/spc/worldedit/LocalWorld.java delete mode 100644 src/com/sijobe/spc/worldedit/MinecraftBiomeType.java delete mode 100644 src/com/sijobe/spc/worldedit/MinecraftBiomeTypes.java delete mode 100644 src/com/sijobe/spc/worldedit/PropertiesConfiguration.java delete mode 100644 src/com/sijobe/spc/worldedit/ServerInterface.java delete mode 100644 src/com/sijobe/spc/worldedit/WorldEditCommandSet.java delete mode 100644 src/com/sijobe/spc/worldedit/WorldEditEvents.java create mode 100644 src/com/sijobe/spc/wrapper/Block.java create mode 100644 src/com/sijobe/spc/wrapper/Blocks.java diff --git a/README.md b/README.md index a6168f1..506bcef 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ Single Player Commands +This branch is an update for minecraft 1.7.2 +Lots of commands currently don't work! \ No newline at end of file diff --git a/resources/mcmod.info b/resources/mcmod.info new file mode 100644 index 0000000..629fdee --- /dev/null +++ b/resources/mcmod.info @@ -0,0 +1,18 @@ +[ +{ + "modid": "spc", + "name": "Single Player Commands", + "description": "Adds various commands to minecraft", + "version": "2.0", + "mcversion": "1.7.2", + "url": "", + "updateUrl": "", + "authorList": ["sijobe", "q3hardcore", "aucguy"], + "credits": "simo_415 for making this mod in the first place, + q3hardcore and Lamp-Post for adding some commands and + aucguy for updating the mod to minecraft 1.7.2", + "logoFile": "", + "screenshots": [], + "dependencies": [] +} +] diff --git a/spc1.6.2-src.zip b/spc1.6.2-src.zip new file mode 100644 index 0000000000000000000000000000000000000000..159349307ee70b4e480a3dbea4a52aa0b260d27b GIT binary patch literal 131588 zcmaI7V|Zli7PcGPwrzEsbZpzUZFFqgtk^a?wmPPJ=mcxTPJ z<{a-c#&eG`6{JDI(18B+a#gn!{r8vuyup5b8r$14I$K)V8<{dH{GWwx|FsbD?+cwB zjQ_92|NX0&|Nq5bC$TlOGxG5 ztPI@@0ji4j>+DE=96O&5vlGRODLDn}!b+{o4OO)9Y?>EUh@#B1^Q&gUNjQ>Y6I!3o z_@b*NIvl!8{Y=zbo9^!0`10TrSF3o$$`gw>@>Y@M)D6jcX);Hpn{us#X(97&`bAAT z#l19^GbsuH{`XY9A+VW@L#YxDnMQIgpUk@zD~4lv7Uu0mJxevTvIXb7Z7kCd2~ONg zS_b9?8?)X@Ptuh^e;_<}v`@|!3v|D6f%v(RmEk|C_aCYGw4l6BzK?xgHv&igdbfR`NtJ+#f(kImW%f5PAsI-ZM2|3H5y51|+SCIJmMK_u!cry_p=vnZvUzf1 zDs>`z02)mvB!vj=3`F4`S4HQ#w0Un`3+L&xdZnrqRtuS4#NJ2bs?BW&PQ%3Qj@R!n z{5l)sjbOQ!k<+M$<0CBcEEppbC{_wMHy+7We6*+j4n0g(Z_|m!7eA zXL!}m-$rxJV4VzL-zv`+bxOnv^lL+o&>NvbxdXDN+e}E~P0EF4{ARuq(H<^s#R13cv5jMcQFwU<$3x*z&ra=3Y7ugv`0naBls$9u`8~bUsK1S@ zuMu}aGzh?M?A8KS;gs|1O=ASWTk@V}Om;G>4XH#9B*!Op%w6R<%nlt3XnbK()*PqM9Z;D{ag3bmi@8A&&CJLc<$Tc6FmaUl7%#VP=Z%S|7IH}6rZXTQPKl? z_l_i=Ph3rNx-7qPS2U4XKe41*&kvKZjwRP~C4cR}wDSM8ZF(>yv6Mho&M? zUbC-Xr-#JHESm}t;Yc!&rw9)tk#oes;;_+gi}zi5a}Sj=j71DRq!@~sU^B*rWIuvw z(WjhCMhn%t3`xvBgHmaZ0&$+?Ph6#FOJBfzinX$G+TvJ*Va3?U(^t=HR&3rTva&dcNqZrD^^KC$d_#xIJ*rN(`6saep ztXkOBx+Mc z!3+ilVS`-q`_`rTxP9O_Rale=S3=q?CDm8@!yryBF1FX`3eqFXxkbOP2nGiqO((e1 ze{1cAf6`!pQ-O-C`jn+9n({>wLL5e25gZTRmjFZ0?r%IUQZq~K3C*87_DW!>0O=oB zgXq_LVSsv7c=UQ#tE&|ZKNmnzFDlc<{**;uz)x6+;)jD+O7Pf+c?KsGMY<&^FdJ(c z{uJNYo&Y(EFkyZf-TK5GecQjpqhAT{H|(@Y7XDqjROs*N{`)sQiLZucF2#qV67A4Q ziS29q`ZBK1{yps9!_esR8blrv2#AFM2#Dx^hoO+=e}eE*Q~N8Cp!p%jfA&=%Ce6!e zMqUCeJGdj(ajJ9Zk=eWiW5D`KVK0TJG9g;Z1A6$3M^c>czKtvvxO-+ zJNlIaN%&#O-zUY%k|ogw_Td_D`=5S2VdRkOl$pW^4j4}t56FxKshX4*I=;lRx=tGB zM!I#xnS4Y@iDG$XJN&H2@(04+9|;c=p&l=(H0>H<#y1w_f}N@BV=dIuU`KvVCs}}B zhD!k|VApEU3gQV!3WmA~bJTw3CyCJOyb9zuYm*JY`5j+(i?irEE_;Pj6hCnT?lp>y7u)4mwx+TOj8k#0@ zmYI)iYK$*>^CQJG35$64TPl>aWNCDC!rn>fBtXxWvumil;|N5Odtd$g)u)MmU?fUc z(9@vryOF&&t)w_}i~<@cr3;ugu@j;vQ)*e>a3lq@V@VnmTKHJBzmNbw^%+5;i@aQ& zoQG-mgfv@Riol>jH1c`az#ud1a!o>HTGCi!+d&~Gx^Q-;II3_CF^|Z{K=#!bVDF$^ zQFDh4SEqCLo?}aFg8+16MAu;h#ct!VAu2ca<|jv9!i!L zx9%?_UE$he$~w?V)^*O^?JxNCvT}Ov-9Z)^Jr{cO>i|KLD;a$vR_IjCse`Y;3@(&r z^*r0gT*E{*`(2k0zt*nto5~}+PW1N@yyycHsA)MgU-5~dhmbJnzK;qrq~I7o&}PJk z%TbNV24IE9Gmn1se8XVNn|&TGK1!8`ixVSVGcrP&u`*5t3;AFHS9qG5V4t-T7uUUb zfQ0|GIw5Ah{#*D4hb=9)Xm1;qm!0TkOOHZ=L{HR)m|Ha*~Di-#O4UXLykrk zO3R&Ntq9pHRXQ04I0k$p1`5YnOktAr<`eI%c8(KS9jG(T^a_u9hwLru%N3Gt{e~N zeC4BFrT)CcE^$edugcwIrXOMTottDm9gMT0N;`3lO&j|(=(G$dgcmkf@0W4PR{y&Z zX-HR#p#3NneVeE+L@7rh zl@WlZ-iXNbm4ME+lKXwU;BbEbasvMI2c1t09HWXD-lQAhO~QPRcsw*1NosIu$7PoO z_}a^eE+`t@B1bojYLK?l8|vbX@Qibw2w}G07xBWq){tD~P04%WLVJV{M74@RxSu6x zb_s>fisslFce1g#>J|`j(ZS<;ow&*5H{xW-7OhsSK^@9!s3w9t)uyj`skSoi70z3G zCDE!h|Ghu(1m3H?SgNJPur{q4V&eP<#ZXzs|)Ok>9Ul*DN)Lh*S&kxcQ0J zq*TcRway~d)2-^-P%im=lU{@-+F6mUcN3}2Yp8|AG^aqD#)fG)x^6 z4}}Y9p5@X)D>Jjh;pV8Ob@?;=F>AR0r%II&?ORR`>L$#kocID$TE>l&hB^!yzRpZT zzWd0%HVD(NQ^|J;DAk++2Bj z3eZL7Xpep@%d&#kr{LX3>e|L$+O*zM=i@Q&yWIZfa_cc~-pgyEAY=C!@Tp|M4(Iwv zIG?+HP*7~_xQSieQ2~rMF8uhKj6f;~#Ul$`2UIXex%X0Mv`n&V+wqeAgy_idwK%f?BkuqZr! z3;A=G0sMvja{n=ySLYO;j-HzH?G^!!1Nii7qLScn#*drp|1x)nCh&@$U*--O1_+4a zACj?+y|J~DsiCpOzw5#r)pfgdP9$HB9shLI0HN^?sWm%2c3IqIw{@ULiaO8>VMRI% zOQXh=ubiAyT>aTCtkl3D*(C`LnmCp*$ZF0ou6dU-g^bc3{q2*)9P6An;`BN(;-PH) z)a`{OZM=zIE!6y$r~K#zxDjt@&NtLL^)?xsLDXj&O}o&uxZW@MQK7~Rd+Xc@pdn|o zAAsoKl4D>8OmM~|nsBwFuNBwcCsHqc-Akz#4)V#M&cG-Z$1FppCr~Jrj)UT@1fL@?x8+R*0 z$Xt*2QDkj~Ady}uL-#?TsX_{2_A}-C?THav28w)u`Xg&?SW0ov=V_xU*r8SSZxHw( z`N4%#(a*g86X#jbA~mc>sk9jHh}exH{N;#Y?aMWq`Bs^I)UII@Qzjn?zGp1}+P4QT zuA)E%UeVfA`6;bCv~eCBgM3(-sE4yD>pXD$gbyh_ON&-L@|0S~(f56;?Mb(v%7_~iQtj`tXeYPKcx=LVT0>9FV%3)8`lBF} zSXIdl+1FN+y~IDhTXQy9Id9EZ;5cc#1V6?bSv4sKO(@^is%UbX1zxEs%3}7(7zf#$ zbqrASad4OK;gZt~6k87l!GL6gY2T~gsQYjR=Y6LQUcTA8VdBSP7Y*1f&t*$qG4lyM zf>B(N?o$gCMZhs(Z+`C3`opnwW(#Vm(?}mK<{F#;e%s#6fuJMEeSIUBt_xru>YMnONXcAb zotfml-z%o`FnERvNPmg+MTd2HqAZX1QZ*VkB4C*k-Fwb3L0zPZ z+amQzu;}tHofeSJ-RPATwN1{IOf8{$XT`O?X6{=&=}|TOA^8&c345wn*q+-<^DAz( zD>^m*iITTpph4nQ3IbttT=#LJ{P%FloIe7UAq1_} zH|hXI7b_^zMyR># zvHR?dBKac;dXP#^eS{i8ah?9?q-?;zFjFR~!OsSbR|G=BRk9f8#sHCGI>Fbz99hrs zy{Dsjyx3+r#H^`Ro1+=g64r4#@^&s`ZY=+7H~EG2iRu221C|bLs!k8dG@%+>`=!>_ zc^kBQpulu$a8D`|edP#hEQ`GWC~c;@yxlMZn^?=szW74=x$8Z5-HYJN-~KeelP&ke zl#9TSZi9#FE-+5=wzBmeL%Xwp+tYTce9V*$8x*%b@0L8kqExvW;m?{#M|{T?##@bYb`xl8`O7BQOrj1gE>T z$I6{3}ajl&(=oTr}l}Ady1=@0D z$1ZrII|x2C9Y}&&7Aj3y7T=<)B;Q-IO9~U2jO5ar8TLN>j7eL4Pj<|{O_SP=I6WaYAR8gKL)LpM-Mc2R?j65$tgM?}kkP#QGiqKJ) z>%Ly%{fI@9kbr(aFb8%LnM`3)uT3)-YAuB7u1}Tgt;Tr$L2iPVS-r%f>Aouu$L&H3 zmJ@%$fLwziRD*DCcCQo;8CMfCW6fum{5&yr`6P-)z35&mP%5;kDBEk)%`vi_upQUj zYS;7L5z;#*L{R$aK@kjRsTF3;=^fm7<4MfFO}FK_dGQ^5I?gp)Lc(5Im9FEoP78lY z2~go?w28^5c@7YW*Gk+)X3Ij8yQ^f^XHf z0hiM`d-ptZT7NI2-o^Ax!^{{uz!1Z)<1!`@868<*(OUW_pVYcFToM;44}T5+Y<)Ut zBI-WYD3UW){Gh1ZCfWP>UwCTG!zTvws}wsGb>!c#~edgY(H zi}GVsmX+|(Sh%!IdOz7KTEe@bi1*v7#f`+D0Gk4@*V+3fvYpj^m=#j8SBLG#(=+YZ z``=eofR-&y4gntwBw4rNddekxn`T9;@s=g+SuZ;cnE+2fz zpUFmq(Rx^^rUN3ieAfvIw-DT_4@8E`qARvLyq)| z{tSNH?!Gv17Ai^6o$-H{;h5=o->U=-J8Rs#A4k-}EV{k9IoN!8Usl7FWf-8@E%AVI zmv)29E0Y&?zSHsbccwQ!lfJoaOU=adUxdhtQS+Yd>kfYqikS0MJ0tGXJAPuGFrPJ@*veZw@B1huJAcCjr`2y>d|~-r+sCJcxe7K z``jT+G_(}-dbTz3JA0k^4rp!rj6Zd>ty~R65YrFfrbPpEzV&JmDyrwqvrb{Vm_fES z=-LZ8%a`9~Bd)15F!kMUh7g71VI4 zl_bbHAdd7v5mTkCcczuVzFJfL_UhDy8C6uWvJX==re!Ikqo@nxB(Igi2ARv`ZC1UV zeu#i9Qq-VL%Vv(7hEF-j%tLKRfPV~6aaM&%)UO5km@sBW)HrT?N5o0#IgK|Vj6n~$ z!M0NOevX>hi!54-DAb@|X#w4To)yxc=&nq2fdKuDnyWI@5nbWyvrs=nM_e|=rS}># zuiM_khi66271zmXkV)Epe85mH%$%PpqWS46Ab%u5>Ig5!ih|h_TOHF!b;SGdmcDL% zqWu8-gU>_LB&L132bJlgu_3cOQM+wkx#YzB{y>KgA@2|L_o$MSe%F8biYmn~vHl0& zC~RYD=p^D~@9>|#`Z3YDWIfC7ReWdO;#a;>O)U8GyJaCI})iR(H*5B zt(8iYWF3~R1invN&yj^DH3jzFZ4mSZ?f}_>n02_^k0s|}4oBz`A!kX?V;RiZPu}X^bb~|x>^1>8 z2|}c9vmlBE@PMXBnY~&lEJFaGrtXQ*8_c}MnC8ReMdqVbBg462ywH#cBS53FgLNuCi<7~e!==Y( zl9!Wv45X%D#SOMCYGT5ADWQXPq$_6})|h5~Cm){5->qma7{k5Bd<6^gKnG zt>2Mi&9}?M`^pwRF?Jr|b~7(%Sk^5q(_Tbe>~1a19I&88RVh;!wYG6j8gdj1)UlR& z8D5*BF8K#yXJY!_^KYpZoxbOQf_nerJQfmz0J{1ZRNU6^A93hWhS@ss2gbz>3>`Em zxp8#$08HoHE!hdz+{{k**()Ro8NIkeW{#Y-`V0!Ia%fzcTISfyA0@yuc!G9=s>GR5i( zV=e-?GpQhT zkRmjCocm}Wi~;I07tJVoG=pfLr5@J#l_u9(&w%cy<7*W-kdZVeUI(&^W7g;yUtESd zBz;`^EF8X!dgT#$_j*|iN=DlRH9ujqGvgCGbGh2G{^lE?3sQ*1rp3)RO2~14~O9eNT2n>o~6kcFK z_RmVF5oj1FnsCq#x(#3asbL>=+xjE~)2C8-zYMBS(tIx;WNv@0vLa)1+Hd`)5^C{Lb@@hPfEwJ7wTO8+N zgT^^ef_&94{S|xw;p$Qq1l3D;1QlKyEGLF5I^8<6jM2jQzd9;cp=nT%(<#)YXVjgetwM_GnsL!SHc z#IpTXkGDTmZXXWi&OJ3-i>)D1+OYZ}eg?NfT@gOfbo%>gb6Vr4atS!oPftJm?jz_W zA6n*JTse1voPy&wxymN%B?Q|e5hi4xRXB7BylilGa(F{;&3j(=E)k$)DT*>n`PjtS zOso}dn^+5R&>^NwMCLH~iEjW?<(l6HN5<67P1^HR?gn*q{#fDKn5sPRJMT2_9xD97^%y2R)pM;fy^i+6$8 zM(7*2)kN=$$P-j%qj}|D?g|ehl_)n?0J(~M%)>cDjhoJZQD@n-m64C!pQEusq@)Z~ zfyHaB8Ier;#zTzX`%Xg-Lec}xbDQ3|={h;1_tq><*t{3f&_b1uYe{Ky3K4A;;@+#D zxEt}}0g0(;HKTdl#xoTlR*6sJ`5q{BR6Si*qEB^`kcnV=<}2U; zX>4dCVfojvPE5R_^dJ+`$TsXd!bmQK#M6~X&ic==dYG&kC)pWKR#{=E>cE#xS!-8i zcIM#V{VTuE*F53(Xj~B86q=isaY^t}RXFLUAx_!(U}<&F-@0@8yC5O7l~=RIl0y8^ zajLx@F0oyieopEpuy?Ny^z3C;hD8{7#S_I5mCl1WP5np)XPO#C?WVw9DH2e1iBQ7& z4;miQs6Z#Vl~u&o?fDF6lC-xr9CgH+!x3SWzQVk@#ZMRz9qOJ&*wLK_-aKQ>2Fi}e zrNp|h@c!vRv%aOXf4F+PfR^p3FC=5d>ZZ+Bv1QW!c!bWfY?_2~1i?Iwj&?BT%GwLYAFTRMn#^&52J! zrWK3g_PZFosMM`OlI(k##}j4CC4Kk__k=&3NwG(OD_hWMTiV# zXf$w7n%m%ecE?rB2*lt(WJ|CkNFFH$wFo5^DD*JPD6Q`Dg(Z&#CNd51NNK!`4VggX zc_#GzLd9hSJ&2pb8*6(^v6U4@@)b?wuA!M|>KhdI3q!XWTNZB*#=osM?2~Y3lBHX+ zh;ooQ(7X`LXyElaa>~}J$0aFHBv|a=biBOVnp{XAuIQFVUDwoJW$?Zw*t760;s@0Z zTOE7MwD&)^{VZ<6l4_#EL_wV@O~uZs%c`bcS?5|TLykP(Zq%lcQ8qqP-S;gJfuaAz zz)lZcVD{zb3mBLxiP%|f1bNA@8acp{IgOr~^$HBQ{V|IwDsG#bE_5Vp1(ZHt=bNMz#dg*{(OA838A{ z#ZFjs5UCGxW%hpNPfufiYZ$QLz;c7b+O#!JA2EC{liwVUm*X<>hqZ=;**gaGrynfw)$|4>ngnEv0R zJ)81hQR!d1__>?RM;EZC1g$sxLMO}=Fg!9ltVhAYRYqJ-x-J=B@_x-TVwu&F6{^~N z`}^6^y@%rX7S>-VTy;3wLk-o0A`aV@l_9CyuXY<%v!+Q`6iu!8LPnBDt(@jztJfjr z$TK!Grh5;69BeyKjT<>p`;GB|`_Q$B6O#Wv@%4=%q<(75!MJEU2)<2;9H&k>xT`?0 zkOo@q8*xM}MmVh!za(z3uL^e%bV-Gg!!4B3R8h&?J`PWGtR3LMTUusxl-Uqr11Z+S zuv97tIpa?|>)K;KN;9(5K)7vZU)?s3)hqbFB6SAoiCALx=VHIX>{m}FYJ-~wKljfd z;7>3#nW#4ewd&Tw35M+HV+-yGpC=9mO^<)qwOD_=X3;}k!Zr116-+q@HAw>r_3}4fokWNSNC^Z$1xQ)n+Q}c zapd4^?Eq)hO}WiL)U|7VZdQnjM1@wpjG6ErKEcEkJZod|mVvDKBT^tC`QF|cjc`1V zplQkvJvX@7O|aiDDgJizyM06@22JOzG3>W;LXCL?;J)&CKOsKI=6(OWdK#ySnc;jf zKGT1;jUtw2W|qdTHZGojDd-pHTN8l$SKFeFMOIn^)8MkWTvwZ0s#5AfRA9NFBD1Ey zubCKgQ&*xh@{^wuQ^LSjJPi@a=gIkLe}uwhiw~FB!)TAjkJ4^VwcvPu1{xNE=TNEr zCuKpr*AnUchI^bye%1hH!iMLV{kRXmL1t86w?U$;!v1=;JV;Ct$8Z_u*DT5a5@4MT zyoG=lE@{OTv;zxHPtxqlm%O<5=N5hz%b;c!ZBDKVZHf~#%`9G{K`_h%7IDmLeqU7a zPl3T7h+!L1KJQR4%}4!I(2|2Vbo0im*M~)fZV7 zk`Wbj+}0v&t6bZ3tA`yg_#-96f8r`?#AG}Tzb)pq~`NO};!dG`5?EJro%Be|5y#9?c zEC=`x%qP5YbP;(GC}F`>pZ5yQ&Xj(K);t2$G}%;0^NlidDOcdJW7@=B*`dNZgT{&G zz*JhN_l9NjG!-MQ$k8s--97D;Gi}1=b=AP~a`1KQ+U0#E7-5E&4&v*5=E`wSP~*N@ zAU+hAp|x30JB3%NYq~(3Wpx)q*GWEdQI=0mq0+`#RNE*DEkBo)ep$O@2(Vf2ZY?OG;j>@&uPH^|06Ov zDr5gDPP)H}6PcW-WQfUmY2f84GfeoMMX{vp$d)f#Ii*3Ony5Ap@$rlxIU(JMO%6A< zM|V9nNh+Ny_Zy2?6`XZXjeJxlgXIrh+vM7mSR-+ylI81)Fli^&(HqCvgyAb!YveJ> zz8ck7sLnkIz14lybIy@zL}m`;3#*-j_V$)Ufa7n=T^}TnR zzNk5A@)cDE)`dtVk20-^Czx6n2ygQ4QaRsdzmahh@q4*u9UK#EP18@PLLgC+k02F? zQcy^1)7Noz+c)H+*62J?CG|YlYXP*JkeXpwtUWaRpR^G7f8@)4aD^VD+A+>yb+ivM7UiX6UO`dY954oEPcY+>wWhDxZ|{q~e9+F{?h=PHw=9kh`Xg7!&&4J#ljMjo z>Y1#w=p3ve9ctMRQEBC^gxXC@lCNDi?l>FP-)t+6HbRDpUw@*@={~;w*Q`pBLuO&e z7dNr{dd`95e{&O2Gc!};zidsn`d8wR_;hO^{$Q;dJE9#PlR9ugfXh8?{y-2_35Tv-O_e~dsJjBMiJYT*^}kPjHm=s1mp{t<>5K= z(sJ|3PM_mHm){9yRZa;in2IIaMm|$qzEi}7g)>KWV|)SMpT$qyC=I%|@1ez71)eS{ zwf)F00}4PnG8RPO5)e*e#7j3;no&B5GSgU)$WyD|?X`O|<6tLI3xy}Xs}W{Ct^wdt zbl&PZP-LjHgN%u?#SE#7Np=#Z^Ag*P#>g_wvSB1#4Xj&lnB6N)jF3Z;H{okiK4iup znpSlf(mqHhOhU&7y1u1}Ks35X-M7bY*Sz|F5HNO{qOv12&E9SQ>E(LNRIdfB3gdwz z{S<*ZvHJeQFHM6VSU5rug`j5OUHuT19>A-GBq=CypbV5mMa+Cq9O!30+kP6`5kwqF z?xLwfTOwmx-RAXO4N1W@Tci~K*Z~n;NWsOae4d#tLAMqm0n|kE#Wycg z)R{j^*6UUJe#0#J{2-GK%fWp9M~|K~;jXyE}iV7{VfA53efqnVBD# z+p{;vGU?DUyO5*E_POe!2AjjZD${Hl&)lE3!riZBQA97$l9X919eD!waCEKpsFb)b z2Uy&$GmtF>7!zEieuto_C7R(-@!pf^)RuAgBec|Hl<+P^eyIQ96v5

$5%_%yK6E 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 z zyT6ixWOYkBbNEj2855<9!nLC!%X+ygpRcvjWMw_K6$`ohuzgA_Z_22xmgXaz^ncU{ zMt+uqXaHTnHDCw$FN!1u11EjGzbPC_S^y^+iWh)VV@pA27P3*tfV=bq6WvtI=z=_v z^cS*y{Q6SNQ0zqm{eaK5Q^q|sl-Ri7{K}JNwuAjSF;~mJK_H)WDr&QRs1zAc{xHSw ze&bd}+AuT1L_ZCleQFj$eVp9M(+Q>u0q5C>XOOaSZ3hjtrBltJKZ+uZO4Z8`v*?Jw zAC}56ehZC6#W0-N4HlcqT2*IJWf7OGl*YR`HKs3}!1j**o3 z;R)MU^-3YcS)xV;<_cJo#;g_59}Rs%F~ybw1+9@Is@kuyj-)lXNz_9%q>QBpd`w&0 ziiDQ}LQMPN7RC#mrO~)BzlDyXn(_;OKZ#L!tgA(E$`K;nlI|3zGe|ZtAr#_hIaS>m zNI8(~+xkl;IKlP@YTC#vL@_!RY(!0O{zFzph^!8oXw znUIP?VAg}ra$Gt1-O+g+q&>R}7mr^*puBuQW;MA6Lz)V%ZhVwRteLNv)yjamsJw5}QB2EkREqhHdla)_4({@1k?4ZgJjxIuoXGi`=9TvMI+vv8^wdmMlt5Lz)64 zxr8OtOM4K^ic(M_JQ&K;_po)~JsTujgcAKuFHp}Y2nGMdD}E@L>T8?`V46{LuF{0u;oshd#%i(-N@tfPTQhY%gyJp&{}4XN={?Cr%!nw z`tVT0alWwlh-|=_sY}wWnMz-;#zcX>lS-Z$Yd!Ka7}b3#C%5qgGe^9upI@|IoWP>!H@#;$ga3w&(kvL*_C$T$)+*C zd<3!7AJoZIfHh%35%Ldaz(omJehrynI*1wJr_3s6PlamqL7LP8dz(mMpvkEgP7&7t zi^d=H*CWF+DpRhSHP%tzWxJNiDyf0%ikna>yvcODpe94}aCcP14yBSPbc zh9;=Db+xARP*M|Oq8RfFsUF;|ZsmgQtji(W1;c8BRIP_v5#ZKC(! zB=P#!k>oCOpJm~~Mo+z_NJ`b8rdq`6Zh3pf$E({X{SG?Q)afD7++_bnB7e%F^Wf9G zU;on2^a0_3=|uct5kNgL3FLe%`YINnDCd%hXh9q4$5!lg#K~IJvs5#-{!@knI=96D z4#qILH1_eadnH@~-h#rFRL>48p{}0OwvvhQQ&MOqkr&P(XP^QY63>F8%SM}B+LS9S{}IFsV|c&hQwVYL{POULgAaC7MP{f(boN6}-#_aUa5n zk;_iZ{J&7NuiUa@sPXsvPY3% zoPHfBv9BJvz^6bn1o#kE@uD}W+{oB1Lb1#EhtT)XhGvJ)q84;t!H$X z+AuNx=n;}C1feD+lGKoB8w|Blc zA{c#8%|T5MrJHW^u(k^i8kpl_J539k`ZJVU4Gh}yt*3U)_8U!P|Eopgg}s0hbt+By zs&H@_rlC?G)j8oDSu;lHYD^;OF;1#sDa+>q-7htP!H}mTV?dJZqe(GS`Xr%L;Z&_` z%I;L;vFp3J`}LnyKv>Mt)j>36f){zodekR*hOK=jVI0T|V{tmx?jMmP9e}BdokRi% z7*Dn2UYh8_mfzr9h*TIgrI$Syd!MQuvrA(=8vNNoYGiEc8$*Mghlp!#w3l(*uh_aA z=0^n>L1J4dB?bPkTkD ziT9&23I!Z;HiuNe80?Z_Ou-8D#vDX?e;bE<^sC<;X7F1O3u_=ggr>b%A%^l%DX^Dr9 zU+1lf){yZrpR7@Q@Exwzmet*4F^?%u1lKQLXxJsDh8;-ihln#8rophY#*)Q>S<7Yh zlocd?lGAXM)L}3ssA>k4zUAu0YCN1rOC(fjrypU_TVCw`#-FVXkQZaT$%Hg5|pJ=B-NApA&$RNE}@>4L)U4B zQsFGuivxe>jh|s*p2=h{`)NI0+}?L_#bXSQL*NxI1_j%73?4H`yBVk94=Dtn;RJQvSW-;Mxl#+KoO1j= zo7quU+Gk#p+ap<1uhamZ-5b>vyS`JX8t;E!BVpt0<%3mQ8!*C&ud~ z&+xTOKNyHdke_OaC`QSrm*CVZAJqqRI|}u)L!Jw{M)@Dy^Mqb~v2mxaRG}mR57pPS zAcK=Fm!kOH4hRtL zode+h@#JO#2Njum`w0@6!C>p&;&y72BByl{@;))OB+`uV`|rY^bTRmi?X%PA!ErS{ z)1NieXXuxyA?Z@*mgdbG(_rTa1u39V0|?!Lgf^7>pW2`pwwIRjTeTs?Q6vW^XLsAjRPj+*h2i=^433$xxQDZ!P4Q8~GZ3bA z-K;DGvSJOL(T5y9;q8Y=*_#sh2aI9#zXM688HDc?uU=+RKTb%zFyZ?^yt%xkg6f+hi{J%9!2KgzgRMsFQBb4_|hUMlygB$ zWspXeA6@X>fDsLl$?jfuSF#aIoAc;3E48dwi4-J0k-|zU+jq*|GZv?o-MwL+b*-fJymfP3_hmre_Ts-%tlhrmGoxM1y^_2WHslV4yQ$+b z{6?g74V8p&i1~iB0eaDShj$KB;u5u%Sn}~|4%Mq)S5*rlk^oTc4x1D&Vk-JV$K)v* ze$A~-NgM{RVmpE@s0ex(en8Pf{7@}?VR7mr@Mf9KDbug}2>5ovk_o!$1SZ)_YnUB$ z^$S(Xs*3fl4e?kpoO6c&1DZm`Fc>Xyk>NKeoiEc4Vqg~4?e!Oy;Hie$%k&EWuTYQH z^;C(O)&mwq8`HgiV)n}|dz=*j_8thBe{ZJ$|C&EjSp%T2NAYIc`LZqQlntXA76w6a z${>|w>fwtsstu^53inGgO^>2BCpH?^0_f{qYiXs^#$iD6MjZB^G9&CUw`VW{RH+FE zyTc$O6mdnL+j7+AY?{|-x<-N)){!LB0IGP}y5l&BHr=$*Pm92iRO5P;)5wN{)pI4v z(~vnT@w<%Ce^zL+8`w2E%DjrvD*n{lX&ZoxC|G zoTa|2%9xZ+{yrN=CZ(y9nOfhv^b%t2(x@(MA$JV?!bjguRkr^!e7Li@_;zJO>)pxI z%CSvuu;nJxX-a3>+~-V1M@sRVK)O_(z7D@eBZ?!?1~Z_TaaD6)M-V^F4tsBUHYJ(E zN|o{1RiaaNna5!?ImI%E840Z)MS(7;414GH`SkhS(bJu!@0zixESuvUCh*~dPUn|U z%?rzvrf}TO4sg^KEbpdxq$u^J{6v3$4pU*NzTT1OTG#iOo$;&XVYL0-=ey;ce52mJ zsG&}+z>knnY>LMmD=VdAI>p-TRhkIs$q~u$)_NszJ&@J>?HH9Xw_RIjPg*b;-Tiz$ zn1p6CY8+24$9IbORrv}O%co2z!|#-`98{>(^CQT18o5k}lPRPg;3#C%#eA%Ni2d@? zi?&ISqtXc9kkD!U=`CZ9wNi*Q;6K(@QK%+39UJd~G))-2>1++CgTvMtREYE(`}q2HG^mNdjYlA^%&G1zsdWC({<8+9b8w?D!~C%t#@ZO2>*?hr8n>q*UlbXY!;dKpK~ zI*G|p;QpOK(J?TkAQA3k66*cKEi5kS>?pvNsvqp;2ZmlAMKIkVOFuZZ(>Gn;cT}@i zU(fWTrk!SmOwj%bI16;|GFYg1tSA_p=Z`P~<>|V%h-BMQ)+UC5O8V~65}Yq~R9~(Qb~DcGy2D-Z5Nnxj2^`50qtjg?Ai(+8O|c}h07HCY%nzHDy?hJF1LzXM>>y7K|P zNCJQ_(!b!Q{xgM;wXy$SQHhoR$9Ji$Q#P2)<=9}2R_#;|C~2q!))5T`L=b0P3LsFU z7`9IS>JpT%qm`a>OwqQ)$r^Xz$%=rYwSIx(KS&=KNq@&gRtOE$X45Pr>+iM2XA`cn z(lHokO0}nQNStW-gVj(X(Beh)A9nkec;7tHRMVK;(mu>Nvp6bPAlGt-GfH}=jCvr8pEYIoMO38rr+Cg})Lj*EB$|ImtTtvlDVqh%6NxFu%r41mv5i z@5_epqT6f6{76QDnOoTHT1*db>iPqtBrd4BM|Kck1T!y+5(6x+kE9$ zVTRW)wt3cdlqui_-Mrl6i|lc6X7YMrXIAyZX;Wrn$E8J3PTg?W$aU6i%C7p`J{()I zildBr5qb*LQ~jh7RO44P6Mdr0(aFPan||1ol$Pa}%u?uAdQr?Yfn+6NA+Gc}k_G`R z?CjK>9)WM7QZ>+y%7rbqG&kU?2tx!d4t?6JsP>Q*ax&Kn;u|^@C{AM>h{J^82!nP< z;ORiZ3-dZqNHIT;>NmuaVJ!4p=*Rk^@6%>usF~_MI48q|4Yz(XeMJq524`m*Jc~}( za4&sZr^~fmKdSKiVpvui(|>xZtBRLE&F(RrtF;KKci-L(&2m_7alBCc(yW&H(H!gD zDvPRu;(YUF`7`)&{X=|NDP^ywG{o)g+;8L_R4IH_dei7|KLm7}U=lUT?0Sk2F^YSx z1#K7CG&qc<=INyaeYh`77YViTq>Q`I(COXfyO9ebNwdRw3__s%LtMr+7#U#@D7A;fSm z55e_G>(FZaayU*fryg8rYT!-aQ)ku+5shpFX)#+=@F5g?viF?&Sad&&uxCpsRs zdr}_1jn1ugw%*ORvXBoYhy6<5kvGvxY+D z%BzTYOw!#CwEx~H45*lk`2!k-XuyW;UjpV7WCj182wa0@iCLoOFC4LTCge8{_*&S?vzJab&EbVurXDpX65zOTtL= z+ZkbwGZ&7Wf5~I$h){+MC>r$oj(fXm=B}wf34<`krIO5THvEmajDjT*Wm5DxFg>-d z7szSwy+dmtwbu@zZ(;Y&<6uC?(QbB>AZMh)qGC%(nI94oWSS^@7)1T|$;ugNHX* z&sJT@6ZKwih%w3w?PwD<2hkMg!J?+|Efk#Y49DEFHlLH}Db>s~fJ#atV3%NjbsJ;M zRI+K81yOOqg)Z-EQQ#Kkl&PtQPbCHQ;`J_BSAa z+yQWess5$U1ppfj0U0;{Wt02QQI3l3HSec~3BK~{2+&Pt{caL;u^_pMs~g0_Cx=w| zkhUUXzt+3bE+g%!+KxjBBO>s5f9BHj82H_P30~wp#AZayG^z-s%~}i9NH1iEW6N0+ zT@atO+TjQqs`Bc5GxjW$%vnpx2FB0eLx8lV+O)lh!2RP+F3_nimAPnZ$ADy>oWybWGGumqt-*?EYJElt~60%1$ z{Uk0%KW2t9ZPO*}`ilkFC05AzhRY%8IsubRh|V;KYAUORyU!)Payk+-1Gx2~LC0*J z$pGbg*-rcB=?+Ir<5DmzbY23YE@IQ_v|0@dHE_LhYn zmWcv?y)RT$MiF`>)wmIo3PWWnMN(fsP6b`el$bw=KMIT*2~|?7hZ*n0!kBeNLZ(g7 zmQs)-2B0&*ii2|3E$_?va527t%E2zr%&AdpWX_@FN2AcaP%FQJVRnLuRx|+wATtyq zoK%tnjum3OPpL(=Vjn4hE zEsBqe6S??M&<(zWk_{XJ8;K%%Tk_T-ogp#)D$9uc$m8Ld(y2nJZ z)95Yy!Y`ly{s@*IC_Kaf7VYQ&RusvtBrTdCL)>D-w#ce!CDQ_&T9257*09Jo~{x5FH{2 zEk>&DV-Le7q)2Vas#{Ag%-@D;X8VscO&u{DF7i~)ldyENxuf0#t|yU-XL$Ct+l}7L z9c42$cO!3mpE@BVW$(PtR~6OJpC}XR{dAt=Y8QsRJQ8PhAZIEar<~-D6$wy5 zyHvv!i04mhBDb{f}brnb8+TSkLe(UY4C=*_@wR>E{rqC_J^aK%jZTqq>KC-n3!;tT^e zeie0YVpq~LhF(Pxw%YP=SckY5+88RHd#!TKs(vtCOpXgGUkRBsU7rE8AxgBFnl@k5hO4g3CR$&f<)%Bx;wW z3bsWvWs&amPb`QcF3jT7RmD2@GwGmyId(Vkx&ESD~i8Hc<=hBjr0g^!5Fl1*=tD!aV> z3Nkgd2abG`NVDY@S93vBOw~%(FDiuaW>~w7)t1D8nhu%!mgP3SDuMV3y+P;*Zmw2; zVsPpH9Xu&{SC)`?$C%dR6M)r>#|6U5G@&?7(y6p*A$^T2R;J(tq;1W~t)J1z-eeeD z+sk@k53Hy3ekH zz0u&JOq6?BH=OUHhID?VN=LoV-`<9Zj|#t%*o*@YW!&&kb&2qywQFQ(R>Q|IV!N28H+Jx!%sDC!ED`KFdEOy zMxIPwRpg5||3e3f4E_D$1n{1H{ri?*(a6%s7SLP&k1cPy+6rL9In?4H0V{d7d%UTde0cA{u?0iP_xI!cG&p>nJ2)`*p z8na`ZFeGiwnV?LZ0g*}YCw>Pns(pr7;??Aa z3Vs<%{u;bBi@&&_Wx~1+eYej&+x`Tr!LLuH_F$FE)GJVO=_(LBZvY4*+uHT3EW54A znuFQf!z?XqHqd(b;3-)Uau;kQxuk-&y#N!zJ_GQ}A!a6DvAT0*Cp34LR&He{ankY@ zP^v7>_Eu|Pqt+kRY6dzQH{Pf2PTwpmx?VU6C3Z~=sK=Ny6k>PlQpFJcKy37?WX=_Q zDBeGx?sx=%9eNSbdb6RI`=2-le$(j;gD~q+SxGs+q#3GEjZRQ%#9OPu>M%W_z3A{q zqrJ%GhUZx(41Z-iI1E~Lw^~SDZm?=zSCYxeXO6jA$4~VQ4Br2v1+2YNS1$q7(5`?N z@LzUCibf89Uz4cV|8UuYuVQcUiahL54Am*^Oigp4@CjH7%n68+Zv=4n2kqBH8iM`HH$w!YEy_CmL^8xXY^NB8gI#h%fM0A;l zwM?|ZvtN#9IUU3J!&ZY4Z`j-xCfn)sf*QIj-&>Wa7T3OJ1}3w;r-y@PISxb+d$GfS zt~d&jqyT*~tn&i|t_AluM~X((33k(V&~i%b1z=O$a7ZEMsW5SBQzjo5>C0ODcKPY-?gTVArV&lmbEIu)?Q*T3^b~0T>E$OZ9}Mx9 zu+g!(nO09NAqqzEtWiKRen^Nd57?e+60BF{%dqYvUu2?VY@tkmiGeU{_blid5>+}; zfy3A*u$uoSVTTFy1*y+hX+0|ynnx%Q2RJn9GUtiG`Y1ngblWqB$J&~e@omw5A4k9# z=>c>(DtH9j`4}_DMv~+e(|@mVl3Cw?!U0WwCCb15%Vz%-Ra2?z@mI|77hc#EeVyWH z@D8!&cqyMcAp~r3ku7nFi;D2#(kd}+G~1CDvOUfAhq3eW%GBA8I@PVi*6-~p<1v2? z);)yKFuMNgJ?N)H=Ia}~zP;Yr$E8PQ_SA488u`b#0wa`ZVBZI^PD+F-(00E2M?H1v2@O%%4sqld14u5w*o> zIl}a#3px2y6 zmg>GgR^8kzYk&OC;e5TQHXe#>t^c#|kyhV%Xl3(jo=y%O5F$*GD=Kp15o8uKqhv}a z37%TKO-$$Oe0%~Ri=Ek-mS^K$-NI|3kO5^h zP_C3-fligJxJaHtyvpPZLw?jqtySDqyxGkDSj$m8dz!AAa}t+wdUnv}(|bNp%XaOe zUwXKgljx>Ylz(pc5zIX}@7oy+G_bdry7BUAYCVrUdd@04%urFfRW0s!{hn<_7N9gc z&BbZo)&#dVikpg&)HX*c&QD)%J9fqp?kC``l3edH{0k+ zycUFlug;@-E+zT_cY{`-0WBXe)?7lw2 zH#&gK_5|3-R`#`55Z4t_d`EZ0a3yX<-DxAG%}NY(-$*-pdA~{!zST#G2+U?2)xt5J zrYe+8x)FMlA06XjyZ0$&dhx6i&>G||i5oNH-yK6=9%ptvHaxS}m}ow8lrQCzc0+(W zT3L`X(vsNX3;o^aVn0q$F6K~i?;0fPWHb7b7lj2w&3EW@1`~@kxG9FsUcW{KF=cHl zpHf89PhCmirK%0U^J1$~i-iMsGTkz+oxA6K)Z>7AVB%Z^MB@tRPj!HLpmsZ+(XO|b zg+ZG&ek--Iq^?Srxmx6MRNe`cgre!SvSC2YU4Y)aofFo<1H&NU(fTQ(Dx>VeMruoHt$-8Ne2Zf-Xal?o+QN<5WEMX+v;!s6DCG|5gLewPmkbxET6>3 zToM1ag5%_U90)<0opUf~RYWtcwtW@lf&~lcAmw@Yz}6PcLKNZb_tQ*B`g7#E{wWCj}%{zWzTXk%ww(JYE@#ofM7N zsRFVHl9qkd+Z44UOml-S4&xIB)wnR)o3M^_c~xhX4;7DbY-007UFc*HOmXNkR~vWjF%q9pBB-0VGIbFc8g=ln_qwF7q?j zuYzEcq<bvE;5; z1{QQ(z#`>@vY&O-;0>C{Co@FOc6!WufHbF4Qu2Vg1w)^)g9z2s8MLemNq}2`X(PSD zT6I&iNRUvn$$pDo7__G<_=2y)!A**cn`u^bfc$3t25JN(-8+ebNv3wrI{pDbZMtDp zb8PkJ|KOh@lEM{f2Irpt`LSgFLl}`dPRb+!NJ6As_h&}tQSq`&{mJw5o4zZK@=oG< zpw)NLUX^9DXKA9zEPY%7bf&@`{@of!^lK%Bq92hgL4$^hV9)CX2_y2O4n>FwMROta zyZ(HdrY&tJPvHCM?Y;XsE~|FW zJs}Io@oJ%s5$p!1=K3w9>kxg94#whvv4r@LWYJ9d+{GIfSo0RB9!HbPVvqa!X1lT~ zuzV%&kGjPTjS}oiuRy8#^Kyas2kAU%S>@XE>I(t)%K%qIaRT$FGzo?SJD`-Bqvf~s|L;=EdRp*vN9igDggHFTO!iGDs5Ht+-z;ktpBdg7gaQ5 zHbnkTVogI!XBRY$Pezbe1}zZdYvx;sAuj{>aCVWe9)5^)StWjd%4&7ByoxH6P+Sx^ zU*UPWn{*ih`}LV82p)!xJjxrPAz~Pd(1A10#k~TM=I-qaB$#XG$#W4E6RHdoA}hJo zC|`zC4Bq8xQn2J=$dv98l6k4mF(_CzjvDo;lnH(REw6?%*-#+dD`9V0Zfl=hBXDM2 zW;=N6`0G8Yfm|U=VGtMP!o<;-+P!z$Q6Nm;CA>oq5^w%oF~Oh=t_`^8)kKprzpc5w zy%Vf`r!OH#M6rEBiGnd@PL05|$`EGmfhssIY7jKp_f}TCQ=W*GR2Sw$uKXJfhS*O% z3f&gj6x+s7M9#cK%rGQkya?XxtL_?jvK3%z%JX;=K=j9>vfQRImmhJyy!*N@2P4k8 zTOx(F;e_ay(h=x4>0gwVw!k12rr@aXGu>PqUT?T?1SRzznAqqfchjh#)mkmM4CGwQ zd@zn#JCA?A1o#Q-dA-l-u7PhZb9A-tXAF7l_bYJU(e!4zz>UVCdmIE zVec4aTeKw!r)}G|ZQHhO^QLXvw(ZQDwr$+Bc~hOQUUhw4uln_O#yCHB<`{FGwf0;Q zF(V*@)X^;-T@m0d$TU$_4_?d=Tb!Jh%O}x0rH+2)F}KE`-cd5c)LwcU93HV-OOGh6 zH@i@Yj9I|xLmEowJ!3en zKB(%A*Xe^QD!=oFhbee7NbC%7mb5|@X0aL4={nCMv(YUkIbE6v;WeK#=ofIn1EVdf zFhFuDpoAi1v42T$WenF-!ub5?N;4%1#`$D-wcr-WHRq^=DI1W6*g3weHHa8wOq`=( zX0y*ItwZb-Tky2p+ZgX1&=1>`AhXcQ;jYyI`!drIUZ`xkRsaf< zcvMYwy|}TUX+8;jl=uvgR4lHOjkajF@J{>h*oN z?CX4rlC8TdpVa~8dn_`>RO@kr_6#}HRnZX}(HkZWDcgy()Fj_GI53>sKL4_c+U1e^ z7y>)syT#`6jrPc^GFg&ZSV0(vwVcm+$XzprQ#_E7(X()wMj*!<uH<{GA(Jgy7D+` zo`)4C_p4Rzm!IO-B-dM>_C4@rN+4!V;b4WHwr7*eK_5*xdgi_wHIF^zYm%<;_jA13 zY~(Fns3welp($6UCu3{L3Cv`s1R6YUmhWy$uRE*ldl%`h$8=j`Th#xEA@mymCCdDx z(qa5j=@9>WZb1Eq7O?nFXWp9s!x+5OH$555Y0IuZp2c3asX!poBqHh;L|{Pb44by3 zisXdU#!=tRE0J_-5)0%BJeueZFAv|#mLjQiZzH7;(Y?kUy-{=nRZ_a1vsy9tr(WOa zgOWs#m7-j3)v?aIDS9CEsfs1XMN(G#pE1MJbHM`{1y znG{+wU=%4Py?_LkdME?}D24=M#u_=cIfRzK&;t-=-c0ioZj_96y~zRg}+ z9G}Yw^|=)0ZbU!zG-H^h3=lx%oABj^bi;fE|42+PY zVidZU`}w5D|B#p~WLm|r2p`Pk({gZd^YDLo@Nn_<<-bBzcUi|;3%k32-A{nK%w|@- zF?e(l+&(WzU$02rBGs_`M6A}lrIq!sIPPv#DzdHYc|Q zDJRB|tas3GbxeWE7pxmYPN~%nut?ayykzsJh;+sms?~3>Z=!I;28>&pYQa|!xF{zC zg;y92(F#X4x%X!+cIx*nOH39G@)6IcU5K5UC@ zzBANNI9>V{)kKx{Zn@*mfPU(+}xfU(2V_xL_lqQrht4?RDm=h9t zAt`jcIx;#c)k};*y9zn8czza;hO_4Enmui3_PiZsTE*G(lh)g$RbN>BwWq+X4TJtv zPAbiS)BDA|qcthKnp+!5HMtT6G|fJG=%NlKpLxoaZcYAiXW})#&}m^%ciQr1asZVm zC6zg2mrqr`dq1Us1)lSHxp#dmn8;ytz6-V#mngXu@rZc(Ch! zse`q)p9{WQvq@A38%BLiCdAnFg<-YGDpGr1)3UyiGj^s*)e8xupn8%5_aR znF{<|Xg2f;bXs|N^^PD`{fQV(Hg$BZp#Kc@gTbPDu3`O;%w8vMB>63(n0xjyyu`Las z?w+UM!fh&G)uwoz*qkspo5Ga9)&uk=6cXUbvj7rr55CM{ zb{sn;T@xpXL<#$LVrruM8_;WA4`EARCXJHpvBk^=+wQ#t=zYb?t8kn593S7+n|%8# zZf88^@O97AVeJeL*X1vG814rT?`4kLyPx_LLR@-r0owhQa~(xv{={LR2-JxV50SiT zGy7C=c$=B&28P`Y*y6yGa6%NPm3oQ$9~E`}phVHl^)NIf1w1&J$qMM}fso?#`br79 zjwVb7*o1tlw^~PnIYzG^-vUZodi13o=M968&0Q$BT32P;QO%7z%9=aq!Te=70)mEpleghBBuM0CC*wDkfr&B5l7MiQ8l6+429M@J{<16YYmRA10WuvU9Y$meAXbVy+}f z-!_|kWf^9plp*CRTf_WJTE`xf_*pRl!ktOeZKopG6T&azHA!IS>- zR60|2fc%0IfW!Q*;mgTI3j31QF=8f9W+gO23z%9uUfN0hE~Va#Cv4E`8Zh>>NAVyP z6E3v`lhX%DA+F%WeQy5RJL&9#QGTj(Ki_i*rSLdG9CXo6OM`NqZO!}$%5oU8c9rE4 z0XD(w1KPhvjCnJv-{RuctpS2;KPNmk{V&xTIZ5Z)sS)EN^Lef>{Kw8Mmhh#TJ4Vf8 zaCeo)Va6?%_k;w|xa=7bmS?(*ElWTyIb+Oh8fPE?{N~@c;YlIn>CXKOS>7_lx_)j$ zsB_l?b;=N|V^fWsI}W2lG%)$dCN9fe3=A4v8rH)HfE}yI?M!89yY_|{)y!F?ab{u`9X0l0jrqJ%yY;O6#qq~&{ z+gZ{~cj{R8-m(iVBk;rs&n^`@`Oc_Bq-{`210qTkHi~go$PKetQi6QsU>3z6!PQY# zkcsM*Uw#Qiz6(6b1-2<2ZR_nd5|j7{>bX^-NJ|XLWkY?QU=;KO1vYXXkH`Ho;4yG!+QZX3lAs7|CvF}7GM zuZ$nbv|_YrVNo>faZr)p!h-zqGeeyTgiTs%6}NbmnSsjPZjYI4yk6+HGvt1RZWDs; zdXo3*yW5}13mI7O4B5J)NW=e96mkRFoEiUSw%`upYW8Toi{8+c`ZAMB&>bV?;0mmI zvES_r6cvnoWY+)u+V?>u-(W_sV+oE_GKyE*0U^|}PbTUX>Ez1_EV62f^477ICarR; zbz{a)cRR8b<{31eeO`-wbjjse@UOfzjL^)APLr!_!qN-z%G$Yo3d}NLkUbsVCMiH% z94+->da-LN2wIA7!EH{udieSXG1@Kub~dqB0fa`RP4+l13aIArV(+L=XaKg&nbWGa z@<#Xq+`g#!_gC1>pO-1PKz-JO-t%g#VR^nB zGbZ@)0}&)^l1fNR_n!JX%IS4RKLdT6VhMDiydAgDZF|QKF6med&#CZhMY6Fpvled>GjkBI#hBo3RwO- z)|MDNIl{ZO#hN7?O0)rZ>Pza$joV7LxH`-4w^Yon{2~FSyg_8Q>H3LM*D9Vz7>?31 zz((;qo{-qpF1BE4ce18Yn-}jPA7|$=tr7;|N!M>^$gxg-b@nL~Zh4fR*07Z6nKtd& zfsH7qp^r&Z$(BVTKDvqFFyp*RWJp@@W{?2XUE!z8xg|6?p=^|c-B*` z`AE~DMDA&S{PPy5Z?pGxU{X$VZk`BnX0NSi5E{3&d^~fA|GZbX7JpUE0%BGgppPjs zV}fE6TUa!GHmmMIazB0?vS$kELpyp**QGgafvgFCq6v(oX_ly)W)SZybE6`l@Y@SF zH=x3Fanc8h0RSp+NEZ*S>($sI=G`PC9s+r-I`@u}U4d!;xc*o$&ztyZruF_{qO;{Ob$(3L-x>GWqEd@%~+%{_(c_4r#BWl^B|LZl!*~sgrbS2MwPhO5*R*oGa z%oXY;?Q(fL`-DQjsb=zUVdVr6Rl9K90M==^n}P4|Ig21?3=G5OhM+aVt*F=Xo>x!? zIp(sJtzM%KGWj&Ga9mJ>uClbrs4ABZil|@ZIV8TJ{lZqk>({V`TMTyN3#$V}Al_$ehZ1RJP?ro0?2l{FwB( z#fi5?Pe!!itZgHAK8gYcRsN^~!7rLykl=ao!`q3VyRL^-}o6A3;$*M@< zMlUMuOdkA;=?GeSxj4j6{VRUH|E@om{Aak2tipe+fv!S>)sO(pHtZL8Ohkbj@YND2 z0@O6Z*xZaLCv}U}yUXc}obXxSi;o-EBUl9a882^+@Zte@Ktk{12PHXG4|54(Ng2;1 z^L38J>uxUvm$()lcXwjxKqbXJ3=~IYv`$jk90CgwZ93d12xET}EKV)+g+n&CqsuLe zBeGwVu!YEgGyM&G)@TPuq8A!;*8MLk70;7Udb@^(jnFCy^N*wCHIP5t*x&(S)DHx(|5h4rNWDMDLc4lzEgv&G(X%z>mLn@@#2_E& zSb!{%>9!n33ausYaj~N{Fa(TyD)gdY6(aOEqH)~MNXR;4n45{%oe{?<0dIxI2Bl|u z35jvu+qpa-%Tv0`H>M%d>TmG@RfQWMZ=v}lxIyT~hXJtIEyNG8mT=`&msOPtEyC~4 zA^WJ;hEeKrZ74@EXJna&S&Er(?C+_jf4O(kRb1dz|Ex#t&w3F4n{(yA{j5`zWv#b< zGP~(7{V>J~HhC?uE#y0bg$Ou z^hk!jVj!(2S}C3?7o}DKq$YoZ$NVb-mg#sv>C;Atb2C3V1w#ab#mfQ`JpMDBY))oR zCDgW(K}Fb_r-d{-$b=@bp9ok(FM3MRHZZlALMLysw4|n0*N_GlYSMLk_;8%2g%h3x zi$}LyR#C4>XSB;vHT$pxIs1@zFG(--#(E47;0k&V(PXmO^b;lefX4K~BC2XX#?waT z<@|YW7kNHdiX9h2-1L`&nC;m2li);?O}E!m#mF2CSs%6*y^(ze1 z{^8som@4d79bP8z*~is8cQ)(*7R4=;l9Zsx2we`&S6Y_xGx`9(maop|)3--mPexTB zf!gJIPWHc83WTD5k}v!$we=4e`u|?)|J->c$^(%#-xoTB==Gtx4n1lpfP#uKIg$vJ0aXR!i;g_3=>Wh1 z@W~4Rj0LI~C`)tzY0OKBvK!Zg4<(^{1xs(uz_!RCSfr312hf%bVskpxk(BvITD2&1 z-G#m>`BBCBSYo+TF9RKi;>}ym0CX@&v??IMidlfC+C)`QLTnr5N`a<%SVq%ROePX1 z2VgDJf)JNhf6x*&ZHm|ynE-6K>Xl#bvU~E#McU8qED;o4| z^K2uS>3ic^fdw3M`N>SAyA1Y!wWsF^i5CeUhc1z_E;QBA;faOWx%k*OFcquSk^d&U zagVF!yaoQVSlsF~gOJ4p9CJ?KmsG4cY8(6MA@;)mTO&se{8AC4+51idSE6)QzgA&| zyM|y0S^@$P54iQN`nGQ=yQk0bS#t95yw2FMraPj_zaRZFYN@5R%t>Q;#Lx@);Yv%F zId!*LmgTTJ*TZgh)DghCGn?o8tBKCz6Xd^RPD1vH0xCcIzVk<7`|r-;pSdv^dqb1| zY`S99{%K&F*Zd=y2QD_23IU^j3P&WI;K3idui|; zn;Oc+{QV;@r`+1*joeg$ixGBvEzXF{$@JkxihOGR?rt9tXQ*AQqErfq)2ez71TmRa zAzvLH3>pG0Sy2$OhG+2gIniCmSRkEqYy@0;U^J@k3&f~iRo--R}L#>21CpS>`Qi+1Q7rL%ZdPQ#fhGndvK1>7 zFuv#;`(7O#UHt)0nUH76W!c_rNf}6-FPmgy6g8?w?fdm$DJhx+Gd0u%9X1n20y@@^ z%ktrC3=3Dv1}Sq~?9m8Wl_&+Xp_S%vezf=YCV~Vf3Q>T4haAW!2<>Ak3Yn8VMGj4> z2LW2-nkoxh`N3csP|)}RB~=ZVYvMtF%9azP@F){Kq zj11iMGb++yq5E57*f6f#aZV!uaUE4@x<@@tn_?y0Wne>DFkxBDnQ&!i|0 z&@Om-C?KtYoVc8KRL9Wr&G%vbAUB(h5o%M<4$*kt7S^WejDz;N0o4?8`;<1q-Q8^` z#vsc*6!;eFeO#cZV$Ea?~Z3-a#%zxpBs#w`(W~y1~w?m=`h!O=mT?nfd#PkeE zXY0C~=Lisf@2u-`b6CP?DAIK~bN&FxB<6SV+fL!j6he+=e|ZLZVwFll+gmytJBh?P z7R>JW)H20!N#_|XtM{SJ%rU+9I=xpcRF5E;b;NU$M~AFy6)D~-fApdDtUXS7xT&VT zm96Vr;WS)I3oa_9P}>&l^E9)R)pb>J3%JK>l&Kej3rSPH>3ZcwkiBzHygo1~t@pC@Q-*l3X~dS7mlz;8N~&$O7A;%#@!w8kEmkkBGpMao}9m}hE1zqX-nQ>{a-{el{U8J4;uB~vrBT9 z)$%}u`=JPm;Fhq<$$QM~7J$1XaG(;>Bccx%ljUZTQ)ypVo>yWGYXc%0MaN1enB9Kx z5?y=ruqnLnJo25(HuXH<7;8EU#Ms+wj<8zI2nk;!+Ju+M5u>1 z#*%hF*6@Zlmd^h@{c%{s)*ib9@gK3&hK2B9u3nnEfV6Xe=>&B|$2;l|2$<+7B8l?d zDWmS_I>eny%0s@r%_Xj}-H+FJQAlB=H*n$1LuYxIO@TyACNUo1TeP za6c^G&EF+ZP?y+#;Q6J>oSZe%RhL8Yz4Td56hLN{Ig`eiF8mU{6driiq37qJY5B|0 zr$Y1RZ@z}DXhQG0v|6N%9)mF+@wb{Jw|Yn={Nz?GIOEp!U zGC~O>6NBrimR9{2wR5Y2L(#$&OTuppGU30ak$C%+%Ds<}sV@&j1 z=bH5|B@FH-CLVr1F5j<@SBTu95EQj~Aq+c!7ihcZ{(GGr@YP`2ez9pP~8gn)Q$*HKxiLb(st zsw*)|hC-FR@7Ke;k0IJsF$zfjQvSK1#lxb?UP^~v_JSybB%}U5ExEiJ-S3eIfa^SX zp4dOP5!F{b8w|iHY7i-Op)hXU{knS!PR8M2bF4uUaQo|xg(oq5L(ic?{s9YgTGKcS zK0}U-nUJUXDr_=bu6Y9m2OK@Q;0e=7`8H{(*si5|4+VA!7d5XjO=4HsB~x)EIW+wB@pSz%y92AyY#Ka16LEkn zbi70u#t8T*P+bvf1nSnWxtScca{aOkfOgwT>V0p2<^CW{hhfm(k1iZwZq|@6qgYz7 z`g?J3cz$rs%a@hY51pUJo1>0DyL-s>>SS!|>gMGYgrasSpCBfcGOKd}xBcP&6<;wR zdYH?9v|->(&F_s#=4b7f#Q@$OosgFeQhu0EdzI@A`m(Lo(>vI`K=j8qMw`@0;a}F&_Z=?xNilj@Qj4ruvitfmRl9G^TkZbnsJIOS zPH1X^$@YTkH|5ktV4!h50MjYq_Eq-#%o@oC7!BUHkfsMHKa8vIvG+!6&xV zA%s{w^aE^D%qNGZ!H4gSw~chDWLeVM^^Vwcf4fulAE*#`jV#aDbX?Mkt@#A`*Krva zg7omegaSAYOj0{=0S(Jb&KQjvCo;sxM6DBZEUqe~CKLf}?Qtpq2|m)rEH2=EXIgAq zpr<&(lGB=U!Oo+eA)o=~8h#Do8j4(aMhZ}r6P+^fqXy}MIYW@7XD!-b~Iu9KnEcGC*M&A)jo7r9WH zyzn<+>D+s_-#}~HSxgVRSJt4{pvA{9OV*`LdO9h@9Pfr&N+`{8rS~$ludiqQ-fXQ( zG;v`0)q1U!T4WvlN@z`(h8V!iXX^n@qn)_?Vc%2GQBofLJA)9Tj;_PxuL+IWHU$F5 z6uI4kPFt1v#BrT7p@j$g_Lx9lW=qwgJcBqKR?emR7*<^gLY7Yp;^R|g4}(PIj3_^v z{k4pWsGzj$EBEWR2$egnbq5)UJabVQ@D*C^&QaOX3+y3B{5 zB7-H8XDkhVSGU+g$XA|E50Imte1OSI(KJaGA=ujKWhtVL3YzMV0eeFyp*(Ob5>h+E z7(bw`cNnKZm>&%>qlmwwCpyH!aHRw*w+>R2NNU%%L%PxQ62T!Y$x%`A*4FLl0(MPXj6p~dEa>vx*Dj|`l_}U2--+oLz)f|D1@YvaWgww#H(S33v%r>-@r(N8x zt@Esj*A;YwHgmx*o@ZV$0cxA4tOB2l#T!^FP3nzZyB1bTx=H211Gsh zXWpUwI@YRw;S1>!j^U0{%u1r9p~|3rHr_bc;Ru#-bC2f;p;zfBT{iG-1Np)fN6vJ$Bs5nRA>ay$G6JHM;$pO}cByblP2Tt}+92JD) z7gHs-&>cfT(>8~_x$F|=brPm>*pYCmLl61SZq0fI^d?5ZqGV_uS1V#I!2I&7$1N_^XsoOi*n24HKy8JLg{{ga3 ztN+vEPtE@Wd<7JW6C(Y^?5fcW6RF=atV9?u)G(iv%S< zGL2}*5O&*wDgv#+tBcL}37OVh=In0y>pjy-ry&z9k%mRBu|F@oux;h^ZoV?ZSuH;h zxkQ1V4dftO4WLknG4~XoI1)iivXv~8s3Zc67FrEC_C&}*%Bq>fYJ?>RQb{WwZf)1y zfQ?%QjOa}bx$Tf_(9Uit6I;cbRoNt)GIa7 zq;3~aci8o})QYOiDNfpliZqUz!`&#u#nvUebjAGP8k|lvFif3+^@VYir%|m;Q@a)yTSA@d!sBXHjI@G={juNCYPe3#f-#nx16~0b-cgbUw%P} z?1+;~0h)zXu95DllX^3Q2Ks@*+&}i4pxFQ4l1p zwE_DE5?+^>)MkVs@gl4!00ToXBO4L-(vbk7dd8Ap*l`xx5S^i6!wgITK2Uu_U8x~|41H_C`R8wM?LWt$m7h64X+u?0chg(|D7GM%ut^v(X zA8%7QRZI*Em`kb3yL|A?Bp&$zc0<8mF8%MvDhVyqHCB#$ry)tFkMlELsdnoS`)41w za}Pa3ZhS?r-kGbrKXJyu7J`|USYOEHbQ=e1<-AJ$#KdMpb`#0-!?XBe9G6vC+v4Y$ zA;)psX72Nj6&AN>IBsgaxgy{2<1Cm}b`6BzqvD&rq{3$%M7_P8c+Kv%37%QIjeg9m zPzZd|g$DYKkYpd&h?dZ$y3ihbY=0~1(}*nppSBeq{sE~EMQaMf)qBamf@@^Ik5FVg z`E#^G)%09%O&qj>I%rBJbHBDD8h5H!Znm^V_8;|_GNu^8H(h{-(&y9Fx5JVt`XK+1 zKmuN~FoKtZ|A58#Ge>o!zv4;r_gu;2HTj5Hq7EM`010yJ1u(U*rF09QHqvCd~f{8`-;=I=MSpy8Nq9ksJ>J3j-Pe z0GSN{fd2pWn7rIi0E4O1&!71}Y5QqyZRgEaq+heq-@un)c;jjo(vg)Ec1*55mON## zypG&8+nk4n5*kLbfGm)bsmk9kO#l*5Bmj|0InCM8q)2PSM)bSafl^0a?$-#!aj`ih zuSvf~4uGl5)y@`{3WMxCo}hE7wLP|99W+=37<19j()UMdHwDhDnO_ROV(FOe85oWMBt zirT`5kt0ARSk?$8RWrmE;L~Wp%&iFD-bTN71~@?U@so@Of|?{jF?t^>BIx!{Q-<;kR%`8T(<#@NyhD z2ER^Lgu=@jS)kzj#lb)&{Hde7F%G#W^SqN0BI3dbWko(Hv$OB(ix*`}&RoOS-vZ@@ z=LMtJNyxbDcvFOaNfC;XC&2IW7k?EuB6_NE;g9Le%)?dFo3SLjYLV)Pa7Na#p--3= z5jdiVFgg0s2UHPiv@Tt-xRRb}2P!}Z&rfSlh`zmJPXU&757_h%eoFMW`ufdMZl%b! zSNR1vtg`LbuAzTzdch!quIBB{nT zzQXWyefgDW(o0@(KU@rB^2skYOr*!s1!yjOI68Z|8U9ZfovE>7oTj=M+WyXDzb5YW z6s{czZ}+roT04mJc;1j|VI?V3d?6;im(r!~>pk8CB45~j(S`#Q7b}IrPSOlNT5QEm z`trm>IQr2ywZ{8_3|caO7jcC?gq^2yIkmO6Lv!VJgs7f^kPf0$hu?S*doK(cPDJ6Bi#%)h6j zwmMAJNY0!=itsvn7N=nEg+!D&NhLvx9JARj`@0Z#mi&j6S!_x*+Jh4VMu0iBLen^X zw(93!uVhS$#lCY^h;)*9g>CqJ_I(Mdg2b5u=^|v&IOxtGhmOLjpuwqR28WuY}{h`TMzXh@Bpm^>kcJmXa`hfYdurE9&Lku!_uBC*2~^NhF% zdoz65DxKLK|ElI^cC!v-$N>u`PNQ#FLPlGR9CPRsoA#D;dedKhdp`yeumK@UB4z~m_Q>(CikRSv zD!1(DYUPIz;I|RRuQV!cXidLm!oY=PFpAIO;ryJ92T51hOV|;JSJ86>4cFNj>Wyny z6M9D4S^`?$Yibucuj^JEB@_QF`Xt}Cp7t7Dlx%7_TAm%pBv95j*rDeU8cpNrCAl9* z3X-SmgT-m!*=N(_bgS7CCKK^fK&9*K~Wkdg!a(U2A#1T-^57 z9^_~Nxisbcx-NcSm*aO=!aVAEt5qLEv}EIIuJ^olvdjxHG}Z(-`*GpMVNz}~nSfH6f8 zl9-}BP;LpNM@Se3L3lK~R22j_yW_bO6y8mA^+@{ayL*;$NAHb3W8RaRyOz-7juFZB z&C9Qgln1}I2T69uPcMNJC+0u*(MA{jeJcN2!E-mxpDBAgedw4h)N#F83KO3j5s+uE zmK|Ag6SBd>^n9+;^H-_%2A@BAOOoia`;Uv<#4`oymg!rGN8!r#L^a{;Ab?!zNmf-@;8;%%5AQ1DGgSO)VU#s z@Juk}>uaG~VxfRg80wa&0e)vcpB&f9J@D=ggpGR7ta1P@nNZ#~ODM{SJ-JNT(QgAfcEw!0+weSJ^+E^Ry5ltC8$z zH^S%Jkbh(s3{KtBHpw4?0KHyP?ak^ouPyp*ii4%!r$1(5?PyIr;`|pX3uNH;UcKx~ z)C*_B6+b>H>|X%O?JQ}en*_Q^ODI70Dm~&T*RtZEOcv0;-vgO~BcR{b#gid2A4@Je z=_RW2Fb02Ru%ChjY`wqKdwpu1YImD29H-Dj7khM{Gkv7Xs&Fe9$qd_{Q@g2Z(5_~E z0Qv3jegpn*`sjc5=IH;k$#(q@9@pt#cwhj-yE+Xh0Dw$l004@A|ImLh!D^;X&i^}= zxJA>}esc`*3-2F%6Og+Kk+R$M-{Hg%j@GUA`pbT$M6|H{{PL9FIQlBr3ypIRem7IS z3DOCz&Z3aOOzwJaX3rVx>&Ijee(-8AgEV)ZkGxsTdGOy5kA>-mn4tq55{GNLnqCV7Wcw#20}uX#7M)VXyes;lN5Q~SM3pVB*=!Mx-raK&nJ-;rrETrCb%ePywO z*X_aTm~67l1cHVU=nAx(?cd=1&IH`8XV4O}0sKza5k@MWPjm#7*7=2B8ZAk7HYBpx zUArWKQ$OV-(U>imOm}RxUnn%ACfFOkkdmx=7*BhQEnDc4gj8|rs}Rn5zOR`0d9ixf zS2^GvjY-M<9A}yDcWb3Qbx0A+0LKyLe7_fUBDhwMqMKEN7!Caj&j|;h3jPnFb z-!M32kzWppw9UT6BqqCvvRkH$tt17{u6rB0uJhC_n5KQc7o1pLwymy|1O)gEvF-LF z^X{uYLk88NV0G70>Lt1O4uu|>Ef-Yvcm-f@eMJ0L-za2vp1|&+QsE$|wjt620Tvy~ zuYyMs0F|Bu2V-6ojlxFkQd2kHu?{J3*x+Xq>K3okdc{Z$zZdF8UihNW2r5kd|N3g2 z$|Nwb9;P8(p2ij|_?s)JbmG$v2)8OrL~(@jfBCOU=kXd8x3AX71j)~cB$TPm{T5p% zcz~_W;RkA5&c^JV5xGA$?cMa`&Au=Rw-nTooe`=0VxVa=Tk(g z;FP9m&NvZm=?6@hfH4^Y2S_61auV<=AbMrK;V-pU*7c>~+QXb|Jybcl z+KsEJsYJB#>|+%%H4U74LZOArPwinTfB*#oU_P4Uld$ zW(!DdQVu>gm-KC$R8Lt$f>gRIGgAp_ByYhgaaf#cK2k_x4y#6deAH|%h2@9SSRO8q zuvXKd8ohKQ)0N8*YO(8XvM2{!DUYv-?qKlvKgw_Bmu8j~AO?=l5;RQ34j$AW9s&!+7) z!%R9wh4LSMS2kmTfMBcjwOcSIIl) zhnI2h2Zpa!vo1E9pv701R1@Y`=jwxodWDj38TxJ<^WYPaTEiHG9k?h;<-ndoJU$wg z&Z8mB!{xY?1=CB2!j+txguqz0H!VE>)W1(*&hWBNEY>P&N?x2$(`ZbcnQX~C-r=~X zI3X5uea6)OfhpVsuheceT9Q_?ERnKpA8i&`%19gHoU8`w6@nX+)SO|8d zB`kxeGp6W@>6iocWT0!TPZ}Gx_?2NTZb`7?=JbMb(!NDl8N1RZ0nD{fL%Mm8L>S@Q z-OlM)(&_lqI#fY2R&YI0>3A}`hsBSaHoAy)P4Hiu4V;5T<*&}SyQ5a1z9&EfO&w0ZO10z1|GxYBo%Gx0G_--!YtR0j5;rUz<)ue%rKxbuv z^fup>eO+2t=M4t#bQX^?>F!ho*VGY)xcXmoy;FE4VcIU7j&0kvZKGpn#kP%(la9@f zZQHi(bZlFHzHj#IYxevz2kWfrq-wqO;1&&JOeg>F?6qk1yyvC^H07sM+G%Y|Bbe4( zhOjx0=VgTrG0vxo_5;N_#iCM!8|rieN}C2ZTRyO@+}1JAN{H>Aovi&)9n%gk49RM| z9Z796YmuOlv9kdOa#>XdN5!#5EfWFLk2_jLx9$5FUFLGpb@94%&;{pB2&UXdN2ll$ zd~+(m=7Xvu3?wxW;|d2ylZkmY5MrTI6l}UKR2O(Gl?z|`qYNU(gbu>f7;_7SNp)%Z zz!*;jA6I7v$8RjHerrzxyR1pXrvv1TkzfLI+F!AwAm#dZ9Ewd0IAm>PcOBH_gZ|;Gc|-u8TP2> zhr3aC`NLFPN(A0Xj}hze;SCWzX*eBI-6#MkO`7w)46p}d^~4FJic-TMu~MEqo{ec6 zS9#1B`@XAN-L{K@iAmi3j;@i)P^=kk4sQnBZ=vH5Q zzm|TTz^q<=KtzF30J!m&;8g6W66Cr|ki@P{PbKD*2W2rUuCYP-?%G^4;q`()?pu(g zWGnH3m}KQwT^OLE-V+KotNA;~(obqT0qf$XMD60Kb62Iu5;^@(m$j2FJ5jyEj|Q63^%| z$bajA8shy64X`aP^AX8Ev-M)l=;zsndR*s7#TX~cVoFTJ<>B{yI^!5dkp<-0`|#-y z5eeF>@=nK+T+SCu$y+qKohl$Hn!c{%vWVY3?35InmNWxCK4H$w0nI?XUcq;={fqXY zqPy$e3jv33d2XkM<49FTmx?}3F`H@FrbYU}4num3c0Ox9CbQXdstg+YF_oInPkR4s zY5#%m84n=f z<^sl}XmJahNbmOw_cv)q(UUVVcZH6!oVsX&?=g75Rp1A%%XwK0QOSNbnx}0os{(F> zq-=J7lOUUU$ZvI`CIRLb&{*y3D76;oB4u&t!DjHIpp+7~XI3K?^q&d+bhGsO52~sX zd7d(V)?ZVtU#-4li^!}|AXTxVqk4;XkhdY zHJDATp3L_{9NdQafIm`Q&#vrTn3yeOTtjLis>c^`EK6-a#W>o*er z?brz`rE0jd-5|Wf-6rig+KXHl;sBGyLTnwKrks2vb!Xz;7zV^WcIa;28FI;ja^yWD z?l23AX+Wc_w7t0;ZW@9{s6%2KGQzBlwD8CqU=~2|I=Z9rCA=hERQ#BAlc#-n+;FLA z97XGxDY44yTSO5teLl-agfQ z_73#V7x4cd%Kn3?gNw6;^}kJIs?=uITHnlEw(qIzKZINS?;Zaq(L&hT&d5sA#QNKy z{(ph(C^eawbxznW1jaA_kz9LI5QH|b^@c(H;u8>?HnDjzgh71Fw4bbTWa{zr;1Tan zh3}Gd^68=}Bd7xLdHnHIiq`gGgtBqmFZ#)eZAt}6DVCl-E`n+`WGCMO@zHUuTX zHLt;;Hx@SF(G5x?S2%MBNU7y(#ORXxE?2Qm`!p;EWYveSVC3hE zh3vh2RMlk2z#xOCgd~=C3Zr(q5z&AW)okMc-0*1+PNj-M+EUZ#TaG`;A$aFM#4u2^ zQ@oFhDs$V#RFji4-vZP^1C3RfM5L@KaiVbac^fFy7#FSJQwrx5-=2Vrpl zc9`p36hJXw==y{)SGUEr1$l_~m@6ruxkX}4l^LS)DOYf?cFSkt^Y5bb#pk;P+P) z2^Oy%C{&q~aV&LyvcVP+;Wf=#mhYOfmef~yEp0CO^Y``DdJD(D%!W0QEI^q2a00f= zhdE1-BsJLW{mo$1J|!}g%T5gvwVsx>3jV7lt}xq_VYivRip2G?w%}`ZTl+R?QTFvW zJo}^Im||kI8r{*{>B(Y-&pN?cnLrM>SbypK{fF_QA1~ri0S^cd=N^RslFv%XhRK5cpuECwEPjc zm}1PAXfiWA&#W6JTG@~Knybl)n79i9e~^~L)la{F9_oLTCBiHRl+SNCQ|$YE{S1eOV__s>ZQ$heFJhQYtuwoIPUJ7$oG*|wkS52BF*w zq2!a)a9Rr~>MHGhzwWeMkwnq;%}c&tEWiQb@AXnj-ty+BK>JeAmK=<6ZX+kB`KqXAzKlmIa-T@&UH zvIL64uAeO3^H|LGW_`{eTGx zSFB?ZyYwB}xPy(57pZQK2zwzqO;%k5SxsQ!q81i6yudh@IVqaVHO_`Hntg)x59v~- zu|E#t?}r0+Tat>p+*$73$%|2`POelQMGhvt0ugDHL0bh4L0gjSP=kCQOOTVAL&=ET zvWe&MR#Dau$Xi0CFB|8ro0v?w4=zP11&`G0HFa~=fKjU^@WLn}cMlR{)hc(XLuFnF zl*v_VklSMjO7RUfO{o7V5wTSrBiLblqlp@-U+;Gb-Kh~AI@DoMkEA{U802nO3zHRy zt(#Lad+~%VE9yB$kz0}SyTRl;uHiQ^H#N3!AX#e3?!wuPs2uvrMXaJGQ*A^O(elMd zN5yu<4DwU(`M`Q;t7I8YWb`sSc{Aes+6_v8MY$j9ARz=ny7=og8j8pPeyC0xrkN?Q zBnXkMyXpRadR|MrulV&Sr%1$K=551A-Iu4#R8_AljIXx3y!^O3IXy}56ZlxB>&Lr30a{wL1c$Xbw_ueH# zr-jOk#OpoG$b+QZStQbzN_la|grq7>e=Nl3PHw)8*xV(YutTD0H_fvA6^1PbAacjt zDDj|22d0hESQ1M>mzwi8IFmJ{sXs(YO92|DcdL+;%-rh{soRAVJ)|fBvCwFmSc)|) z8+EE$$Rk<~-8o8q2*ypl=Fsm%|NX`r$+c04P&3p|&b18smr~%maB&&QAax#t80X8* z`s>TU&ihOo$1>n2cH>egEOAD0o2TES6LZn@yfJP8m&x8)zzc2)Hm<-a6I<$u`jgRc z;>6_)|E)Kov7X~IG+1n|l(;EDJ_z@a2hxM5Jzze*K!J8c9Qeg6pt&>R)q1d)CC@)^4u4I9<4iU&?3cKQKP z`TEyyv?g>7nZ_miH;&QIza6DkQ2rl837E*#SZpR;`!8(SF+)ha3OFrrAHmPS@iV3? z7;D1Uz|vwVw+eG@5ylmS6+D9^RhlYtTrsN27&a!OAr=CZ$^b&7Yr)bp)RTQ`cS;8t zjj60xVeNmF6@_&0IEa%s1uyrS@48oSH3x! z7%yopJR#hzonIE`uy8r7ZD(~3d0`q%?eh?R5e71$*k8h&&8lr0%uXA3C9pX7eMHEZ z_Qx7k(vwGWZ3oD9z#@OVAQOoPAm>7yDpM$5ii7pqnXW9;l+kPDkAo^3GM1e9xk1jL z2s^V1V5z1w`7Sw!JV60HEA1tO1AgG4eXsZ&Gp@6vdY3RT2rhlp3t(Un^ut0eh|+&b z5Yno%R!pAqJu<2koVRjG2VX=Uvb$$kiN-oRVOEt~qTje?%0HvHlFulzQlLmos3I#* zU7RqNKIo@-O?6C+z{73mn5L%cnlSoe%L0RbFlrcX3;=FjzL(N5CwMkxq^�ig8Vb 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ℌS}Ayjq*{1xu|7cnS83I>S^^ zw)9ND)s%${!zj^D6vr=1P1O&v3OU>=A*EU8Wtslc(Al0~p5!@Hn8sCtFCdsTFJj!} zM~duD@H7nd&JZIU5Tg#%6oDpN=MaYGJHQ1QC@PEUAGPpqMJS<61A(g3h`Swg5B`dw zofo(ApQ|V;;y<_A)!g5S2EjTcBW40neC@b*3Gp!JL+$zxdJs#zicI>0E2&Y#lo7cv z$3jL6U#~L|ah4f!tm49gC%f*HMMFd6T&oxIVvfeV&Vu(RQ-+YF#?p263SsqVXjx5G z+6Rd!A_h&juAo$5{$^E$#(Nnr=x|i~ER}rh`T3Ac9zZWjcQOTcegazau&9Bt$ykac zs}B=gCfvX?uEhKp9-UKH;Zv>Jf9BD(%9v?FfJBmqRi~etU>=;0gNq@E{ zTnP_8O8hMJ6V*ug6CVwXq>Z=a5ibGh;l`u771&5WyZ_HQKN5pVlIhGt7qSYtxKU2S zlbFxa`qs3iD&m9n(wdg2B{FR~r@V58<6(1J4Gfb}n~V}N>{0!w@}R|ZFOOvweDN6a z{aj{DjbMUiRG`*LV9s3%_PldLqpc)8WMX@69)9K9$sGq-Uioq*lsN536ycyp z+Iq93$>_tU)Qdgz&6M6udn>NELv`!{;r=jU) zY;*6IEt4B|vN+!@Ub+5TJvDJ-=?teGPv=(`0(2tV6*vE-M{L>o=5CIY9c9zl8+u`g zWVugXZL!D?bkuYuqi=qcK7*Zn;HQNp#6fl5P;5;f>(;YsB}}Addq@1x1GNCYtIbvj zY9%&DVi#^ulC)u26g_qRfv6Jzro%T%nl-8$Lc=~^)g;I5T-H2mXrBV!aDpk}%nd7| z%Fzt|g5YjH0&nKG-9{HUx|k(E0KY^0LD}OYT#G%Tmx_wQTB9LyA>ly)H)Scyh>WMG zm36N(0(>%sU%&FJQ%|k)Sj-hhR32CPAag3`^PPa~THT%1C9KtJ^ICU|=N1D!JSNIo zLb!9~=VKrAF%MZjQX^FJ0>*$^7xmp`2kQ~~3onFnFFO(jZoc`*ZtCe^T1l$R$0m4yD;eX#aJ}jSup7ZoqvTrrz(1iD7d|Tq#1*>9X=z zGu#NQaCNnTr?h3U7e%>PfK9#Es8-CAhqn*w(l3Sav)kk}DddYEn<8U;JM_Wr zSm>yiSC+F1YQwZpP8u%0+9qjw9{jHV`Zx2$E6m^OLfZHSBuYt3i!lE}D)YEcwoh0197*Gu}?LE^{5W8J%q{a|!(jyBCIimG88YDRSg z@vg~c$$o&%5gJ z6=~s!yfw)@eWANNO>pZi7;>_4NX8}_0*ziu`pQ%-H7o@cV|dwL_~;xubWmh$izg20aS+zDo zCR43x+KPMJt%g!s5+K0EU?KDyn$X_!@$i|&LkK<_4=!9H6;;-s#T{zE1e*OwtB##I zk?0v4U>iK}sGI5Yxp({APX$S{O76?I-YL@cBc)b{aWQO8aQ@_=WMf<1G~tlBgr~0| zj+T|kUfKGG;LV0(`h{Unm~RE4S$6GS5y8~5Y8=)dxM!iXN#qLPDS!xM%D~buL#vyJ zQD{aw8n)vb4^<)4#EZlHu6v_^Yq8v4SP_I#=nT>|U~@1j4VI%my1#{5M{b($lxo3H z7}&OT5km*)PughQrU>n9_~j9e+~Ct8Rneq9N-3A=MVehJ9NGF4Vf3)TO@JvV9JeWF zsDK#sTvxiDUN_`%^d|Au@YJIq-kruA*HFh;z%~nz<;rS+4byB+a}%N2P7Z81kchKa zRIXgQ)@2=n33raPC!UxpNE%<^mijA13jMtV;@PeAVl&a>qtJs4BW?Miz-jK299*L1%;5ioBp+s*=YLhH1&U2G`1|GATe;`$K#)D=#EZVtv+ycn z`eI>h=gSH4QP1aA68t$)mc7&u9lnD zkmFP`kdU57!0kSihxH3ZleE-_>4sp&lIOBdWkjzDKFFFVdgLMtU&KJ9oxZv9N&LiA zS7C)3XG(2W2tf0*xfqmaF=Xn;I1-smPFd2abT8FTe$L8L``j>+l`(7~3v8;VqieqS zsM0kS+Imw@LMxWx-A0tX;*%9iM^Ql4eRQ#BY_DEhu&p_0bcyuY{iP^u1u6IGmN$lH z>TbU~v8iVgum9?B&movfUlFCSL^=|sBSNjhg^JM?XwP{|WNb5u)DY0~OfO`_$bz}3 zO8@RPnjtTKKxG+Q#w7ibo@SY=9aNOjqlnQw3Nt>g-A2Q)PH7pugnN91<)SIzc=YFb zyx_~w#VLEuiOmz|_(tg*E2tfBCbR;DW_{w(2CgQG<6x?;>)--D5iZZY$xu!Z@K)Iz z2~{OCd4dIJ*)?k=6;GKc>1R~#*=eR_YKp1Kweck^=}t@UT`W(48atJ#D16Rp-aGoe z8=jq4oP$~HPI8aI_^wa4SL9>a{j^fgK!PQ6vrD%gyK6D%s+`hS=!;PQxzcCo&?*!b z!hN&-RI zi-V8v{DkJsX+th$+Ni(FE$nVwzXBN6h0ec-cES2rE}V4xc1L*qZD5x1-~D>0pAkxK zD~pqUQwkVw@cx(e)?I8EN^QjQQ$j3qa`OH9etx%%)eK$5-9&-yR=U;Aa*x&BYOi)Y z&ph1YtO&yZF&_8yi0ZvhB>0+L(+*JQb6lan>P4-~cuHeAUE9kiwKXN(?g7n3vl_%4 z`#BZ{D{W>OBWDQP-0<+R7@A6&pA{1(F}5~uK@4NkjLq^GJOD(y)_F`GWPd~y2NcPL zk0`N=&~(@?hfqF*J)xxc!dMuv;dxVdLhzB@(3T6+Q7weyX@Q&*3Mq_= z{MqLNBZAG#c2IRnS!#G?vp~ckVj=Bh-6SGroybbf3=)1TV-s<1*v!$E&9!Ls1WrJWFkjREM5;;^$Fp znCvZkuJyI~!Md23)wb=)MDwtBi$n7hF2%mt zl*1mlFJxt}D$BB&K#te>5H(NQ3{(7m9&Rs}k?+w>yxC*@%a+ei|3(KXUj(i&_-5~v ze^WyK+gSeHhR9ktIh)x2A09|$oSaO*AY#as|9j{U25fsPA$eU-<(a?|w=~iO=k-b3 zmDL8+n{J+r7%ia)VW-vebCv|3>;{dBT5?LAe2r?IpTF0IU4$~$S)~#*lMA7YuiHp9 z=HVj`1(SKraYocN5ObJp#}!7>$5}&m2qCL7mJ~$T&9y}gV$(2nz&?1>$aauLMBRR6 z4b39K{}d~Mz*q?`yz6Omuv@;%$Za8-Ueio1FVF1}y%ucW$Yr>iO%8cq_P=XnURSkA zY_h>v02Mb(Cbvn!0pOCx-wjh8c{Kn51wwi-x8ySp6e91#LuQ?Zd96xFR8pAcM2V_j zJMO`X+8 zV02vmUY{6D1K4SiV4N;6!O+}Fkz5?D6c-)vmshKKL?#%Q3Ir1Fq!-JTg=Fx_k7m%) z36%avN4aoC3nh&qv;RqmawKaE=EG+KO<*v0l~LK2vtlJ48WSDHy$yLbjfA7lW`VIqza<9!SM#!;FoJ zr^GdwWAPBOangzioTCI&EV1C(Txo9ip%#B$)orHYp_HQOv9Vk?=)U|>bgf@hs3!yU z3)i>^XgN?>%5Y}>r}yj#CI%$xsYzev+RG(`_Y!+c{+~^m(4AfTKP6){r%yj+mljZv zqC?efQ46j6DI>0#U(g1%xz*p3Ypre zk)8GC`JWxblNRxIdPtqGi>sVKrE9*siMjBmXo!!^Y`%R?V0Z-UL+P*3fEEwEVzf zH1Kb=OJQl&5ec0E8{QlKs+b%bn(xuRQvV|Wbm6DddwL`A@o%OvbP(BveBYLFf#08o z|KNoGze_tM6H{vwBj<1B&cAH#Hnp~$<~b34ZOvWo@^crFkJy9qVX^MynGqu$sZv4q|N?9onHxNN!8Zu)5EZ@^z3TxQon(|c) zo_A#(khn)171h-JhummCffW{LjolZ1*HJuoq#g&;>^PJ5AmC?1OFEIuC9OsqX#g;W zXwEI^q!c(w@0|B(1fRON{BDlclir>i@GY^xBhxi9lDaMt zqg)E>Q;z@qgR>B3+PFG_Kwqs^JUVJHD37A+WegO@-czn*CT)J6aVv6}X-ngtz)+#- zjb)s??;Bc?%6s(P;*&p)DrU&sEDw(b^Gxhdc_N1T3D~PhTYLYzFlO{zGpD$Nz`(mc z!9y7AVkv2g+1_hWIS!ygaJHIwzs%m+!JI9?^jsu7xGiFSE}>|c>pm_wCcJ^3QGnNz z{zLt=*%DCfIm27<+m9OXx~Rvix1%go$t~Zc;k@9WquMJnc7j zi98KWuW!?C5lR`0N=)T>pgsp1j3<%0T@;Na>f%*wc9-kKr~gez__z^`_HcBzgQ9UF z;S=;w&9x+bzAs<9lz^7S5y9; z(UgvR$>JrpG)nZfDmgQ<&W{Ha@RA)5`*Y)3_L9s%kU$hpQFqpSK4@Ovcp^~}V zTIttUmE`w(T@h)}k_i|-BTj_z8T@TUPwvOoEG%Pac}51D(`n+Vs7L0EWF=C*bUTjQ z^HhhC67+*<3Lgp5ZB3)X&Sm*Fu~wrA#1N*NC^Ce6Aav%Fc}ka>vVN8w+zyBpyW_v- zj*`bDL7utLU&flQJIVg-1PSO|O4R7Df%go?#aYF1>LJHEeXWT$O)ocS-yfN+M7ZEY z;|o7bC;}+;b3KL?6|;?~DaK2^hi8)RGZi!2%U#c?3^5(>Qn54_xo9&|E3yJ))Hrg0 zeC19bH=@}F5#MqGN@{(0PN}`(cwiBlHKILe7-K2e)VzXx$q_e%?X?dfb=P$=Dl6TG zth@v=LzlhPfkZm}YhJAiJG%nTd89zI+yhG=mg5^9oBZR?xeuJ@3-jZf)MG3Q9J<}M z50XUpy87FFer>u9SO7>1+-sP?Zj`sB=l?rEQo| zm9X3e*#?=R<@Q=yE~QRqqO6M}nH zQkLv?DHZqXs*h5AeqV*KdDD>JQDorl8q&`7R6aWc_X=4)x~==HwR15V9=EWyW+G4a zMGoPK`i#UPyV9nySq4u89cEMr#+9!lyO_yuaTHHTxjnxQV3HbhpHr82tMRHYH_14& zh4cE+;`!XfvQ{OqVplz{)!oNlj26n1NfmY~UvE(`{eC-K3AKdz^*cXf2}X@}9;yp> zyQThe!u3zY#)tL7Gg-NkVeyLJ$60D+Sc<=9MTKaJ%}dEW_}`53+NI@1sF{=k8<~RS z^tBAN;SdTKgT{__x{$1lPA!cnTW#oaN;rFyX5oWP`Q=1m2qYSVa+X}S_KG!eyagnu z^rlK*>38V zu%dE=0zVj>CN`u%g2Mu+tE>(i2McFgPZf+%$L=WY#TzYcd%F6v2Z#OgD&hG8DYuYv z$g0nOizK@#P?G%p-TE1Q*Wmxw{wbR{JOAJI??P+cc8?v=2O-ukRgQofLYM4hYX)3s z{<089zm_VtsTzzrGQeonKNTZ2%i`<%myyhY-)n&AXg??r^X3B zTxUSbJDvsqj5(Z!YoKBP0`2FYpyZ!ZiLSDs0nqnqh2;5H^r>Mcv zll5sRhNxJvBXXf|KlQr(F~};qvd+!T3%ZryrwU1@Dj_E$QHLr6SFrc`U9sO+Jri6N z;KK1Nl|Li|OZSyD5~S}c#(KH6?O9Sv!AXQ1@GaTJbCvc$3OOqlpx+%|4Kqi+*lHs1lc|H1-4#ZJT&V4NF|#FW#k0XMJ3szSMuDKtQ~`G5C6WT<_LI93y0M_FMDJ;YMPn<%DES1|3-ZR;}@Lm3`h=D$VY40f$x zWzlX*x4cz+M*9467)8|<1eXW-jdy6(t4UuEL|j*uZw)Q3>WzEMpfxV4&y1_Z^QVw` zAS__ypin(MlywgsO*~}q>H}>~-^Nq94S}67+T~>RBSfP!+$Bg2GosnNMwZB^b;z*? zVSx;N9L_zxPj)P`zOM~i#(L6lV_^izcoHv8XaOq{!w1=<{6=p$OhRxIxU|^6O_;Zj zY`nadxphaK&EtM7$!T~1zB+2didAGV>@J!TPf>=7HXahg9yrjq*oKlwdt>2jN!1t* z#uuuadv645Se#pa*0=-O4~HT!?q2&&KKxa`*I≧BAL(`)rnb5wF6DkA*Iw9K;6E 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 r=vQ={H@9EQeRMf&@loa1{sTBIi literal 0 HcmV?d00001 diff --git a/src/com/sijobe/spc/ModSpc.java b/src/com/sijobe/spc/ModSpc.java new file mode 100644 index 0000000..29cb9e1 --- /dev/null +++ b/src/com/sijobe/spc/ModSpc.java @@ -0,0 +1,97 @@ +package com.sijobe.spc; + +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.Mod.EventHandler; +import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLServerStartingEvent; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent.Phase; +import cpw.mods.fml.common.gameevent.TickEvent.PlayerTickEvent; +import cpw.mods.fml.relauncher.Side; + +import com.google.common.eventbus.Subscribe; + +import com.sijobe.spc.core.Constants; +import com.sijobe.spc.core.HookManager; +import com.sijobe.spc.core.IHook; +import com.sijobe.spc.util.DynamicClassLoader; +import com.sijobe.spc.wrapper.Block; +import com.sijobe.spc.wrapper.Item; +import com.sijobe.spc.wrapper.Player; +import com.sijobe.spc.core.IPlayerMP; +import com.sijobe.spc.core.IPlayerSP; +import com.sijobe.spc.core.ICUIEventHandler; +import com.sijobe.spc.hooks.InitialiseCommands; + +@Mod(useMetadata=true, modid="spc", version="2.0") +public class ModSpc +{ + protected HookManager hookManager; + protected InitialiseCommands commands; + + public ModSpc() + { + this.hookManager = new HookManager(); + this.commands = new InitialiseCommands(); + } + + @EventHandler + public void init(FMLInitializationEvent event) + { + Block.init(); + Item.init(); + this.hookManager.loadHooks(IPlayerMP.class); + this.hookManager.loadHooks(IPlayerSP.class); + this.hookManager.loadHooks(ICUIEventHandler.class); + MinecraftForge.EVENT_BUS.register(this); + FMLCommonHandler.instance().bus().register(this); + } + + @EventHandler + public void onServerStarting(FMLServerStartingEvent event) + { + System.out.println("loading spc commands..."); + this.commands.loadCommands(); + } + + @SubscribeEvent + public void onPlayerTick(PlayerTickEvent event) + { + if(event.phase == Phase.START && event.side == Side.SERVER) + { + if(event.player instanceof EntityPlayerSP) + { + Player player = new Player((EntityPlayer) event.player); + boolean moved = event.player.posX != event.player.prevPosX || event.player.posY != event.player.prevPosY || event.player.posZ != event.player.prevPosZ; + for(IPlayerSP hook : this.hookManager.getHooks(IPlayerSP.class)) + { + if(hook.isEnabled()) + { + hook.onTick(player); + if(moved) + { + hook.movePlayer(player, player.getMovementForward(), player.getMovementStrafe(), event.player.getAIMoveSpeed()); + } + } + } + } + else if(event.player instanceof EntityPlayerMP) + { + Player player = new Player((EntityPlayer) event.player); + for(IPlayerMP hook : this.hookManager.getHooks(IPlayerMP.class)) + { + if(hook.isEnabled()) + { + hook.onTick(player); + } + } + } + } + } +} diff --git a/src/com/sijobe/spc/command/Ascend.java b/src/com/sijobe/spc/command/Ascend.java index d37d7d5..68e1924 100644 --- a/src/com/sijobe/spc/command/Ascend.java +++ b/src/com/sijobe/spc/command/Ascend.java @@ -13,6 +13,7 @@ * * @author simo_415 * @version 1.0 + * @status broken through 1.7.2 update -> fixed */ @Command ( name = "ascend", diff --git a/src/com/sijobe/spc/command/BlockReach.java b/src/com/sijobe/spc/command/BlockReach.java index 9faefb3..7807a90 100644 --- a/src/com/sijobe/spc/command/BlockReach.java +++ b/src/com/sijobe/spc/command/BlockReach.java @@ -8,7 +8,7 @@ import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.Player; -import net.minecraft.src.EntityPlayerMP; +import net.minecraft.entity.player.EntityPlayerMP; import java.util.List; @@ -17,6 +17,7 @@ * * @author q3hardcore * @version 1.0 + * @status broken through 1.7.2 update */ @Command ( name = "blockreach", @@ -53,7 +54,7 @@ public void execute(CommandSender sender, List params) throws CommandExceptio throw new CommandException("Reach distance must be between 4.5 and 255."); } ForgeHelper.setBlockReachDistance(playerEntity.theItemInWorldManager, newReach); - Minecraft.getMinecraft().thePlayer.setClientReach(newReach); + //Minecraft.getMinecraft().thePlayer.setClientReach(newReach); //removed since spc 1.7.2 update now needs forge anyway sender.sendMessageToPlayer("Set block reach distance to: " + newReach); } } diff --git a/src/com/sijobe/spc/command/Bring.java b/src/com/sijobe/spc/command/Bring.java index 928747b..dd42f6f 100644 --- a/src/com/sijobe/spc/command/Bring.java +++ b/src/com/sijobe/spc/command/Bring.java @@ -8,7 +8,7 @@ import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Entity; import com.sijobe.spc.wrapper.Player; -import net.minecraft.src.EntityPlayerMP; +import net.minecraft.entity.player.EntityPlayerMP; import java.util.List; @@ -18,6 +18,7 @@ * * @author q3hardcore * @version 1.0 + * @status survived 1.7.2 update */ @Command ( @@ -65,14 +66,14 @@ public void execute(CommandSender sender, List params) throws CommandExceptio if(radius <=0 || radius > 256) { throw new CommandException("Radius should be between 0 and 256."); } - List foundEntities = Entity.findEntities(entityType, player.getPosition(), player.getWorld(), radius); - net.minecraft.src.Vec3 vec3d = player.getMinecraftPlayer().getLook(1.0F); + List foundEntities = Entity.findEntities(entityType, player.getPosition(), player.getWorld(), radius); + net.minecraft.util.Vec3 vec3d = player.getMinecraftPlayer().getLook(1.0F); double d = 5.0D; double offsetY = player.getMinecraftPlayer().posY + player.getMinecraftPlayer().getEyeHeight(); double d1 = player.getMinecraftPlayer().posX + vec3d.xCoord * d; double d2 = offsetY + vec3d.yCoord * d; double d3 = player.getMinecraftPlayer().posZ + vec3d.zCoord * d; - for(net.minecraft.src.Entity entity : foundEntities) { + for(net.minecraft.entity.Entity entity : foundEntities) { if(entity == player.getMinecraftPlayer()) { continue; // don't allow the player to bring themselves } diff --git a/src/com/sijobe/spc/command/Cannon.java b/src/com/sijobe/spc/command/Cannon.java index e6d5828..82b89b6 100644 --- a/src/com/sijobe/spc/command/Cannon.java +++ b/src/com/sijobe/spc/command/Cannon.java @@ -8,14 +8,15 @@ import java.util.List; -import net.minecraft.src.EntityTNTPrimed; -import net.minecraft.src.MathHelper; +import net.minecraft.entity.item.EntityTNTPrimed; +import net.minecraft.util.MathHelper; /** * Shoots a piece of cannon in the direction the player is facing * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "cannon", diff --git a/src/com/sijobe/spc/command/Cheats.java b/src/com/sijobe/spc/command/Cheats.java index 527f022..f1eee97 100644 --- a/src/com/sijobe/spc/command/Cheats.java +++ b/src/com/sijobe/spc/command/Cheats.java @@ -14,6 +14,7 @@ * * @author q3hardcore * @version 1.0 + * @status broken through 1.7.2 update */ @Command ( name = "cheats", diff --git a/src/com/sijobe/spc/command/ClearDrops.java b/src/com/sijobe/spc/command/ClearDrops.java index 7ef03e1..8ad76c8 100644 --- a/src/com/sijobe/spc/command/ClearDrops.java +++ b/src/com/sijobe/spc/command/ClearDrops.java @@ -8,16 +8,17 @@ import java.util.List; -import net.minecraft.src.AxisAlignedBB; -import net.minecraft.src.Entity; -import net.minecraft.src.EntityItem; -import net.minecraft.src.World; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.world.World; /** * Command to clear item drops * * @author q3hardcore * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "cleardrops", diff --git a/src/com/sijobe/spc/command/Damage.java b/src/com/sijobe/spc/command/Damage.java index d05a7ec..d28d30c 100644 --- a/src/com/sijobe/spc/command/Damage.java +++ b/src/com/sijobe/spc/command/Damage.java @@ -12,6 +12,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "damage", diff --git a/src/com/sijobe/spc/command/Descend.java b/src/com/sijobe/spc/command/Descend.java index f525b87..b8b2065 100644 --- a/src/com/sijobe/spc/command/Descend.java +++ b/src/com/sijobe/spc/command/Descend.java @@ -13,6 +13,7 @@ * * @author simo_415 * @version 1.0 + * @status broken through 1.7.2 update -> fixed */ @Command ( name = "descend", diff --git a/src/com/sijobe/spc/command/Difficulty.java b/src/com/sijobe/spc/command/Difficulty.java index 2eb8a44..f65920f 100644 --- a/src/com/sijobe/spc/command/Difficulty.java +++ b/src/com/sijobe/spc/command/Difficulty.java @@ -8,6 +8,8 @@ import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.World; +import net.minecraft.world.EnumDifficulty; + import java.util.List; /** @@ -15,6 +17,7 @@ * * @author simo_415 * @version 1.0 + * @status broken through 1.7.2 update */ @Command ( name = "difficulty", @@ -40,23 +43,34 @@ public class Difficulty extends StandardCommand { @Override public void execute(CommandSender sender, List params) throws CommandException { World world = super.getSenderAsPlayer(sender).getWorld(); + int change; if (params.size() > 0) { - world.setDifficulty((Integer)params.get(0)); + switch((Integer)params.get(0)) + { + case 0: + world.setDifficulty(EnumDifficulty.PEACEFUL); + case 1: + world.setDifficulty(EnumDifficulty.EASY); + case 2: + world.setDifficulty(EnumDifficulty.NORMAL); + case 3: + world.setDifficulty(EnumDifficulty.HARD); + } } else { - world.setDifficulty((world.getDifficulty() + 1) % 4); + world.setDifficulty(EnumDifficulty.getDifficultyEnum((world.getDifficulty().getDifficultyId() + 1) % 4)); } String difficulty = ""; switch (world.getDifficulty()) { - case 0: + case PEACEFUL: difficulty = FontColour.GREEN + "peaceful"; break; - case 1: + case EASY: difficulty = FontColour.YELLOW + "easy"; break; - case 2: + case NORMAL: difficulty = FontColour.ORANGE + "normal"; break; - case 3: + case HARD: difficulty = FontColour.RED + "hard"; break; } diff --git a/src/com/sijobe/spc/command/DoDrops.java b/src/com/sijobe/spc/command/DoDrops.java index 42c67ea..64a085d 100644 --- a/src/com/sijobe/spc/command/DoDrops.java +++ b/src/com/sijobe/spc/command/DoDrops.java @@ -16,6 +16,7 @@ * * @author q3hardcore * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "dodrops", diff --git a/src/com/sijobe/spc/command/Effect.java b/src/com/sijobe/spc/command/Effect.java index 838f04e..8981855 100644 --- a/src/com/sijobe/spc/command/Effect.java +++ b/src/com/sijobe/spc/command/Effect.java @@ -17,6 +17,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 updaets */ @Command ( name = "effect", diff --git a/src/com/sijobe/spc/command/Enchant.java b/src/com/sijobe/spc/command/Enchant.java index c5a22c7..da9e6f4 100644 --- a/src/com/sijobe/spc/command/Enchant.java +++ b/src/com/sijobe/spc/command/Enchant.java @@ -17,6 +17,7 @@ * * @author simo_415 * @version 1.0 + * @survived 1.7.2 update */ @Command ( name = "enchant", diff --git a/src/com/sijobe/spc/command/EnderChest.java b/src/com/sijobe/spc/command/EnderChest.java index 5fd3935..0da2843 100644 --- a/src/com/sijobe/spc/command/EnderChest.java +++ b/src/com/sijobe/spc/command/EnderChest.java @@ -3,7 +3,7 @@ import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; -import net.minecraft.src.EntityPlayer; +import net.minecraft.entity.player.EntityPlayer; import java.util.List; @@ -12,6 +12,7 @@ * * @author q3hardcore * @version 1.4.2 + * @status survived 1.7.2 update */ @Command ( name = "enderchest", diff --git a/src/com/sijobe/spc/command/EnderCrystal.java b/src/com/sijobe/spc/command/EnderCrystal.java index fdca101..96cfcfb 100644 --- a/src/com/sijobe/spc/command/EnderCrystal.java +++ b/src/com/sijobe/spc/command/EnderCrystal.java @@ -13,6 +13,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "endercrystal", diff --git a/src/com/sijobe/spc/command/Explode.java b/src/com/sijobe/spc/command/Explode.java index 14ef90a..7023a23 100644 --- a/src/com/sijobe/spc/command/Explode.java +++ b/src/com/sijobe/spc/command/Explode.java @@ -16,6 +16,7 @@ * * @author simo_415 * @version 1.0 + * @survived 1.7.2 update */ @Command ( name = "explode", diff --git a/src/com/sijobe/spc/command/Firework.java b/src/com/sijobe/spc/command/Firework.java index 0811c80..0c3a754 100644 --- a/src/com/sijobe/spc/command/Firework.java +++ b/src/com/sijobe/spc/command/Firework.java @@ -9,10 +9,11 @@ import com.sijobe.spc.wrapper.Player; /** - * Creates an endercrystal where the player is pointing + * Creates an endercrystal where the player is pointing //TODO why does it say endercrystal? * * @author simo_415 * @version 1.0 + * @status broken through 1.7.2 update (worked before?) */ @Command ( name = "firework", diff --git a/src/com/sijobe/spc/command/Fly.java b/src/com/sijobe/spc/command/Fly.java index a63952b..9f93978 100644 --- a/src/com/sijobe/spc/command/Fly.java +++ b/src/com/sijobe/spc/command/Fly.java @@ -9,6 +9,11 @@ import java.util.List; +/** + * TODO add doc + * @status survived 1.7.2 update + */ + @Command ( name = "fly", description = "Enables and disables the ability to fly for the player", diff --git a/src/com/sijobe/spc/command/Gamemode.java b/src/com/sijobe/spc/command/Gamemode.java index 427a8c5..b6efa45 100644 --- a/src/com/sijobe/spc/command/Gamemode.java +++ b/src/com/sijobe/spc/command/Gamemode.java @@ -15,6 +15,7 @@ * * @author simo_415 * @version 1.0 + * @survived 1.7.2 update */ @Command ( name = "gamemode", diff --git a/src/com/sijobe/spc/command/Give.java b/src/com/sijobe/spc/command/Give.java index 7d54ece..7208954 100644 --- a/src/com/sijobe/spc/command/Give.java +++ b/src/com/sijobe/spc/command/Give.java @@ -15,6 +15,7 @@ * * @author simo_415 * @version 1.0 + * @status broken through 1.7.2 update */ @Command ( name = "give", @@ -54,16 +55,9 @@ public void execute(CommandSender sender, List params) throws CommandExceptio } } - // Get the item id - int code = -1; - try { - code = Integer.parseInt(split[0]); - } catch (NumberFormatException e) { - code = -1; - } - if (code <= 0) { - code = Item.getItemId((split[0]).replace('_', ' ')); - } + // Get the item + Item code = null; + code = Item.getItem((split[0])); if (!Item.isValidItem(code)) { throw new CommandException("Cannot find specified item: " + split[0]); } @@ -72,7 +66,7 @@ public void execute(CommandSender sender, List params) throws CommandExceptio int quantity = params.size() > 1 ? (Integer)params.get(1) : 0; damage = params.size() > 2 ? (Integer)params.get(2) : damage; if (quantity == 0) { - super.getSenderAsPlayer(sender).givePlayerItem(code); + super.getSenderAsPlayer(sender).givePlayerItemWithDrop(code); } else if (damage == 0) { super.getSenderAsPlayer(sender).givePlayerItem(code, quantity); } else { diff --git a/src/com/sijobe/spc/command/Heal.java b/src/com/sijobe/spc/command/Heal.java index e569d69..828ea9f 100644 --- a/src/com/sijobe/spc/command/Heal.java +++ b/src/com/sijobe/spc/command/Heal.java @@ -13,6 +13,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "heal", diff --git a/src/com/sijobe/spc/command/Health.java b/src/com/sijobe/spc/command/Health.java index de8502e..69963b7 100644 --- a/src/com/sijobe/spc/command/Health.java +++ b/src/com/sijobe/spc/command/Health.java @@ -15,6 +15,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update but infinite option doesn't work */ @Command ( name = "health", diff --git a/src/com/sijobe/spc/command/Help.java b/src/com/sijobe/spc/command/Help.java index 5b83ff7..5cf3bc0 100644 --- a/src/com/sijobe/spc/command/Help.java +++ b/src/com/sijobe/spc/command/Help.java @@ -16,6 +16,7 @@ * * @author simo_415 * @version 1.1 + * @status survived 1.7.2 update */ @Command ( name = "help", diff --git a/src/com/sijobe/spc/command/Home.java b/src/com/sijobe/spc/command/Home.java index 3077b0a..e1dc42d 100644 --- a/src/com/sijobe/spc/command/Home.java +++ b/src/com/sijobe/spc/command/Home.java @@ -11,6 +11,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "home", diff --git a/src/com/sijobe/spc/command/Hunger.java b/src/com/sijobe/spc/command/Hunger.java index 9001abe..78fce8e 100644 --- a/src/com/sijobe/spc/command/Hunger.java +++ b/src/com/sijobe/spc/command/Hunger.java @@ -15,6 +15,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "hunger", diff --git a/src/com/sijobe/spc/command/Ignite.java b/src/com/sijobe/spc/command/Ignite.java index 914da0e..7f9a8e8 100644 --- a/src/com/sijobe/spc/command/Ignite.java +++ b/src/com/sijobe/spc/command/Ignite.java @@ -1,5 +1,7 @@ package com.sijobe.spc.command; +import com.sijobe.spc.wrapper.Block; +import com.sijobe.spc.wrapper.Blocks; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Coordinate; @@ -8,11 +10,13 @@ import java.util.List; + /** * Ignites the top of the block that the player is pointing at * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "ignite", @@ -25,7 +29,7 @@ public class Ignite extends StandardCommand { /** * The block ID of fire */ - public static final int BLOCK_FIRE = 51; + public static final Block BLOCK_FIRE = Blocks.fire; /** * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) @@ -38,7 +42,7 @@ public void execute(CommandSender sender, List params) throws CommandExceptio throw new CommandException("No block within range."); } Coordinate fire = new Coordinate(block.getBlockX(), block.getBlockY() + 1, block.getBlockZ()); - if (player.getWorld().getBlockId(fire) == 0) { + if (player.getWorld().getBlock(fire) == Blocks.air) { player.getWorld().setBlock(fire, BLOCK_FIRE); } } diff --git a/src/com/sijobe/spc/command/InstantMine.java b/src/com/sijobe/spc/command/InstantMine.java index bb3976f..9570e73 100644 --- a/src/com/sijobe/spc/command/InstantMine.java +++ b/src/com/sijobe/spc/command/InstantMine.java @@ -9,13 +9,14 @@ import java.util.List; -import net.minecraft.src.EntityPlayerMP; +import net.minecraft.entity.player.EntityPlayerMP; /** * Command to toggle instant mining * * @author q3hardcore * @version 1.0 + * @status broken through 1.7.2 update */ @Command ( name = "instantmine", diff --git a/src/com/sijobe/spc/command/Jump.java b/src/com/sijobe/spc/command/Jump.java index dd0cabb..d915f51 100644 --- a/src/com/sijobe/spc/command/Jump.java +++ b/src/com/sijobe/spc/command/Jump.java @@ -8,11 +8,12 @@ import java.util.List; /** - * Sets the players spawn based on the player position or the arguments + * Sets the players spawn based on the player position or the arguments //TODO make doc correct * provided * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "jump", diff --git a/src/com/sijobe/spc/command/Kill.java b/src/com/sijobe/spc/command/Kill.java index fb64fd6..ef9f0c0 100644 --- a/src/com/sijobe/spc/command/Kill.java +++ b/src/com/sijobe/spc/command/Kill.java @@ -3,7 +3,7 @@ import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Player; -import net.minecraft.src.DamageSource; +import net.minecraft.util.DamageSource; import java.util.List; @@ -12,6 +12,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "kill", diff --git a/src/com/sijobe/spc/command/KillAll.java b/src/com/sijobe/spc/command/KillAll.java index da02026..8ec4e54 100644 --- a/src/com/sijobe/spc/command/KillAll.java +++ b/src/com/sijobe/spc/command/KillAll.java @@ -8,7 +8,7 @@ import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Entity; import com.sijobe.spc.wrapper.Player; -import net.minecraft.src.EntityPlayerMP; +import net.minecraft.entity.player.EntityPlayerMP; import java.util.List; @@ -18,6 +18,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( @@ -65,7 +66,7 @@ public void execute(CommandSender sender, List params) throws CommandExceptio if(radius <=0 || radius > 256) { throw new CommandException("Radius should be between 0 and 256."); } - List removedEntities = + List removedEntities = Entity.killEntities(entityType, player.getPosition(), player.getWorld(), radius); sender.sendMessageToPlayer(removedEntities.size() + " entity(s) removed."); } diff --git a/src/com/sijobe/spc/command/Light.java b/src/com/sijobe/spc/command/Light.java index 9030cca..289623d 100644 --- a/src/com/sijobe/spc/command/Light.java +++ b/src/com/sijobe/spc/command/Light.java @@ -14,6 +14,7 @@ * * @author q3hardcore * @version 1.4 + * @status survived 1.7.2 update */ @Command ( name = "light", diff --git a/src/com/sijobe/spc/command/LongerLegs.java b/src/com/sijobe/spc/command/LongerLegs.java index 8b5b18d..f79e099 100644 --- a/src/com/sijobe/spc/command/LongerLegs.java +++ b/src/com/sijobe/spc/command/LongerLegs.java @@ -16,6 +16,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "longerlegs", diff --git a/src/com/sijobe/spc/command/Macro.java b/src/com/sijobe/spc/command/Macro.java index c6377c4..7b962ae 100644 --- a/src/com/sijobe/spc/command/Macro.java +++ b/src/com/sijobe/spc/command/Macro.java @@ -19,6 +19,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "macro", diff --git a/src/com/sijobe/spc/command/MovePlayer.java b/src/com/sijobe/spc/command/MovePlayer.java index 38fd095..454f53a 100644 --- a/src/com/sijobe/spc/command/MovePlayer.java +++ b/src/com/sijobe/spc/command/MovePlayer.java @@ -17,6 +17,7 @@ * * @author simo_415 * @version 1.0 + * @status broken through 1.7.2 update */ @Command ( name = "moveplayer", diff --git a/src/com/sijobe/spc/command/Noclip.java b/src/com/sijobe/spc/command/Noclip.java index c105e7c..efee43c 100644 --- a/src/com/sijobe/spc/command/Noclip.java +++ b/src/com/sijobe/spc/command/Noclip.java @@ -12,15 +12,18 @@ import java.util.List; +import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.server.MinecraftServer; -import net.minecraft.src.EntityPlayerMP; -import net.minecraft.src.NetServerHandler; +import net.minecraft.util.ChatComponentText; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.NetHandlerPlayServer; /** * Command for disabling clipping * * @author q3hardcore * @version 1.2 + * @status survived 1.7.2 update but can't see anything while inside blocks */ @Command ( name = "noclip", @@ -71,7 +74,7 @@ public Parameters getParameters() { private static boolean hasXCommands() { try { - NetServerHandler.class.getDeclaredField("clientHasXCommands"); + NetHandlerPlayServer.class.getDeclaredField("clientHasXCommands"); return true; } catch (Throwable t) { return false; @@ -87,7 +90,7 @@ private static void updateServerHandler(EntityPlayerMP playerEntity) { return; } - NetServerHandler handler = playerEntity.playerNetServerHandler; + NetHandlerPlayServer handler = playerEntity.playerNetServerHandler; if(playerEntity.noClip) { if(!(handler instanceof ONetServerHandler)) { @@ -96,7 +99,7 @@ private static void updateServerHandler(EntityPlayerMP playerEntity) { } } else { if(handler instanceof ONetServerHandler) { - NetServerHandler oldInstance = ((ONetServerHandler)handler).getOldInstance(); + NetHandlerPlayServer oldInstance = ((ONetServerHandler)handler).getOldInstance(); if(oldInstance != null) { handler.netManager.setNetHandler(oldInstance); playerEntity.playerNetServerHandler = oldInstance; @@ -109,7 +112,7 @@ public static void checkSafe(EntityPlayerMP player) { if(player.noClip && !player.capabilities.isFlying) { player.noClip = false; Minecraft.getMinecraft().thePlayer.noClip = false; - player.addChatMessage("Noclip auto-disabled. (Player not flying)"); + player.addChatMessage(new ChatComponentText("Noclip auto-disabled. (Player not flying)")); updateServerHandler(player); ascendPlayer(new Player(player)); } diff --git a/src/com/sijobe/spc/command/Path.java b/src/com/sijobe/spc/command/Path.java index 37770be..d0854d4 100644 --- a/src/com/sijobe/spc/command/Path.java +++ b/src/com/sijobe/spc/command/Path.java @@ -1,10 +1,13 @@ package com.sijobe.spc.command; import com.sijobe.spc.core.IPlayerMP; +import com.sijobe.spc.util.PathData; import com.sijobe.spc.validation.Parameter; import com.sijobe.spc.validation.ParameterInteger; import com.sijobe.spc.validation.ParameterString; import com.sijobe.spc.validation.Parameters; +import com.sijobe.spc.wrapper.Block; +import com.sijobe.spc.wrapper.Blocks; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Coordinate; @@ -14,13 +17,14 @@ import java.util.HashMap; import java.util.List; -import net.minecraft.src.MathHelper; +import net.minecraft.util.MathHelper; /** * Creates a path with the specified size. * * @author q3hardcore * @version 1.4 + * @status broken through 1.7.2 update */ @Command ( name = "path", @@ -43,7 +47,7 @@ public class Path extends StandardCommand implements IPlayerMP { /** * A hashmap containing path settings for each player */ - private static HashMap playerConfig = new HashMap(); + private static HashMap playerConfig = new HashMap(); /** * Name of the current world @@ -61,25 +65,25 @@ public void execute(CommandSender sender, List params) throws CommandExceptio if (params.size() >= 1) { String args[] = ((String)params.get(0)).split("(\\^|:)"); - int block = -1; + Block block; int size = 3; int meta = 0; try { - block = Integer.parseInt(args[0]); + block = Block.fromId(Integer.parseInt(args[0])); } catch (NumberFormatException e) { - block = -1; + block = null; } - if (block == -1) { - block = Item.getItemId((args[0]).replace('_', ' ')); + if (block == null) { + block = (Block) Block.blockRegistry.getObject(args[0]); } if (args[0].equalsIgnoreCase("air")) { - block = 0; + block = null; } - if (!player.getWorld().isValidBlockType(block) && block != 0) { // isValidBlockType should be static + if (!player.getWorld().isValidBlockType(block) && block != null) { // isValidBlockType should be static throw new CommandException("Unknown block: " + args[0]); } @@ -108,17 +112,17 @@ public void execute(CommandSender sender, List params) throws CommandExceptio } if(playerConfig.containsKey(playerName)) { - int[] plrData = playerConfig.get(playerName); - if(plrData[0] == block && plrData[1] == meta && plrData[2] == size) { + PathData plrData = playerConfig.get(playerName); + if(plrData.block == block && plrData.meta == meta && plrData.size == size) { throw new CommandException("Already making specified type of path!"); } } sender.sendMessageToPlayer("Path mode enabled."); - playerConfig.put(playerName, new int[]{block, meta, size, -1, -1, -1}); - } else if(playerConfig.containsKey(playerName) && playerConfig.get(playerName)[0] > -1) { + playerConfig.put(playerName, new PathData(block, meta, size)); + } else if(playerConfig.containsKey(playerName) && playerConfig.get(playerName).block != null) { sender.sendMessageToPlayer("Path mode disabled."); - playerConfig.get(playerName)[0] = -1; + playerConfig.get(playerName).block = null; } else { throw new CommandException("Must specify block."); } @@ -157,7 +161,7 @@ public void onTick(Player player) { checkWorld(player); String playerName = player.getPlayerName(); if (playerConfig.containsKey(playerName)) { - int[] plrData = playerConfig.get(playerName); + PathData plrData = playerConfig.get(playerName); makePath(player, plrData); } else { return; @@ -171,30 +175,30 @@ public void onTick(Player player) { * @param player - The player that is making a path * @param data - Path data for player */ - private void makePath(Player player, int[] data) { - if (data[0] >= 0) { // block + private void makePath(Player player, PathData data) { + if (data.block != null) { // block Coordinate position = player.getPosition(); int x = MathHelper.floor_double(position.getX()); int y = MathHelper.floor_double(position.getY()); // used to take away 1 int z = MathHelper.floor_double(position.getZ()); - if (x != data[3] || y != data[4] || z != data[5]) { // prevx, prevy, prevz - int start = data[2] * -1 + 1; // size + if (x != data.prevx || y != data.prevy || z != data.prevz) { // prevx, prevy, prevz + int start = data.size * -1 + 1; // size - for (int i = start; i < data[2]; i++) { - for (int j = -1; j < data[2]; j++) { - for (int k = start; k < data[2]; k++) { + for (int i = start; i < data.size; i++) { + for (int j = -1; j < data.size; j++) { + for (int k = start; k < data.size; k++) { if (j == -1) { - this.setBlock(player, x + i, y + j, z + k, data[0], data[1]); + this.setBlock(player, x + i, y + j, z + k, data.block, data.meta); } else { - this.setBlock(player, x + i, y + j, z + k, 0, 0); + this.setBlock(player, x + i, y + j, z + k, Blocks.air, 0); } } } } - data[3] = x; - data[4] = y; - data[5] = z; + data.prevx = x; + data.prevy = y; + data.prevz = z; } } } @@ -211,7 +215,7 @@ private void makePath(Player player, int[] data) { * @param k - The Z position of the block * @param type - The type (ID) of the block */ - private void setBlock(Player player, int i, int j, int k, int type, int meta) { + private void setBlock(Player player, int i, int j, int k, Block type, int meta) { //player.getWorld().getMinecraftWorld().func_94575_c(i, j, k, type); player.getWorld().setBlockDataWithMeta(new Coordinate(i, j, k), type, meta); } diff --git a/src/com/sijobe/spc/command/Platform.java b/src/com/sijobe/spc/command/Platform.java index 14e2639..e8bb09f 100644 --- a/src/com/sijobe/spc/command/Platform.java +++ b/src/com/sijobe/spc/command/Platform.java @@ -1,10 +1,13 @@ package com.sijobe.spc.command; +import com.sijobe.spc.wrapper.Block; +import com.sijobe.spc.wrapper.Blocks; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Coordinate; import com.sijobe.spc.wrapper.Player; + import java.util.List; /** @@ -14,6 +17,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "platform", @@ -26,7 +30,7 @@ public class Platform extends StandardCommand { /** * The block ID of glass */ - public static final int BLOCK_GLASS = 20; + public static final Block BLOCK_GLASS = Blocks.glass; /** * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) diff --git a/src/com/sijobe/spc/command/Repair.java b/src/com/sijobe/spc/command/Repair.java index 89ced34..dc750e8 100644 --- a/src/com/sijobe/spc/command/Repair.java +++ b/src/com/sijobe/spc/command/Repair.java @@ -15,6 +15,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "repair", diff --git a/src/com/sijobe/spc/command/SPC.java b/src/com/sijobe/spc/command/SPC.java index 848dfc1..c48de20 100644 --- a/src/com/sijobe/spc/command/SPC.java +++ b/src/com/sijobe/spc/command/SPC.java @@ -15,6 +15,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "spc", diff --git a/src/com/sijobe/spc/command/Scuba.java b/src/com/sijobe/spc/command/Scuba.java index 8d6ac91..7852609 100644 --- a/src/com/sijobe/spc/command/Scuba.java +++ b/src/com/sijobe/spc/command/Scuba.java @@ -15,6 +15,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "scuba", diff --git a/src/com/sijobe/spc/command/SetSpawn.java b/src/com/sijobe/spc/command/SetSpawn.java index 1652ff7..b337068 100644 --- a/src/com/sijobe/spc/command/SetSpawn.java +++ b/src/com/sijobe/spc/command/SetSpawn.java @@ -17,6 +17,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "setspawn", diff --git a/src/com/sijobe/spc/command/SetSpeed.java b/src/com/sijobe/spc/command/SetSpeed.java index 1467aa4..1c34bc7 100644 --- a/src/com/sijobe/spc/command/SetSpeed.java +++ b/src/com/sijobe/spc/command/SetSpeed.java @@ -21,6 +21,7 @@ * * @author simo_415 * @version 1.1 + * @status broken through 1.7.2 update */ @Command ( name = "setspeed", diff --git a/src/com/sijobe/spc/command/Skin.java b/src/com/sijobe/spc/command/Skin.java index a06bacc..638cef2 100644 --- a/src/com/sijobe/spc/command/Skin.java +++ b/src/com/sijobe/spc/command/Skin.java @@ -14,6 +14,7 @@ * * @author simo_415 * @version 1.0 + * @status disabled */ @Command ( name = "skin", diff --git a/src/com/sijobe/spc/command/Spawn.java b/src/com/sijobe/spc/command/Spawn.java index 7aeacbf..cb2c02e 100644 --- a/src/com/sijobe/spc/command/Spawn.java +++ b/src/com/sijobe/spc/command/Spawn.java @@ -17,7 +17,10 @@ * the player is looking at. If no position it specified the mobs will spawn * nearby (under 5 blocks from) the player. * + * note: spawning falling sand crashes game * @author simo_415 + * @status survived 1.7.2 update + * @deprecated use summon command instead */ @Command ( name = "spawn", diff --git a/src/com/sijobe/spc/command/SpawnPortal.java b/src/com/sijobe/spc/command/SpawnPortal.java index e7f42ad..7befdc2 100644 --- a/src/com/sijobe/spc/command/SpawnPortal.java +++ b/src/com/sijobe/spc/command/SpawnPortal.java @@ -8,10 +8,10 @@ import com.sijobe.spc.wrapper.Coordinate; import com.sijobe.spc.wrapper.Player; import java.lang.reflect.Method; -import net.minecraft.src.EntityDragon; -import net.minecraft.src.EntityPlayerMP; -import net.minecraft.src.MathHelper; -import net.minecraft.src.Teleporter; +import net.minecraft.entity.boss.EntityDragon; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.MathHelper; +import net.minecraft.world.Teleporter; import java.util.List; @@ -20,6 +20,7 @@ * * @author q3hardcore * @version 1.0 + * @survived 1.7.2 update but end portal doesn't work */ @Command ( name = "spawnportal", diff --git a/src/com/sijobe/spc/command/Sudo.java b/src/com/sijobe/spc/command/Sudo.java index 695a25e..4de7543 100644 --- a/src/com/sijobe/spc/command/Sudo.java +++ b/src/com/sijobe/spc/command/Sudo.java @@ -16,6 +16,7 @@ * * @author simo_415 * @version 1.0 + * @survived 1.7.2 update */ @Command ( name = "sudo", diff --git a/src/com/sijobe/spc/command/SuperHeat.java b/src/com/sijobe/spc/command/SuperHeat.java index d2dd511..8927e9b 100644 --- a/src/com/sijobe/spc/command/SuperHeat.java +++ b/src/com/sijobe/spc/command/SuperHeat.java @@ -5,19 +5,21 @@ import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; +import com.sijobe.spc.wrapper.Item; import com.sijobe.spc.wrapper.Player; import java.util.List; import java.util.Map; -import net.minecraft.src.FurnaceRecipes; -import net.minecraft.src.ItemStack; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraft.item.ItemStack; /** * Cooks player's current item or all items * * @author q3hardcore * @version 1.0 + * @status broken through 1.7.2 update -> fixed */ @Command ( name = "superheat", @@ -58,13 +60,13 @@ public void execute(CommandSender sender, List params) throws CommandExceptio if (oldStack == null) { continue; } - int key = oldStack.itemID; - if (smelt.containsKey(key) && smelt.get(key) != null) { + + net.minecraft.item.Item key = oldStack.getItem(); + ItemStack newStack = FurnaceRecipes.smelting().getSmeltingResult(oldStack); + if (newStack != null) { int amt = oldStack.stackSize; - ItemStack temp = smelt.get(key); - int id = temp.itemID; - int damage = temp.getItemDamage(); - ItemStack item = new ItemStack(id, amt, damage); + int damage = newStack.getItemDamage(); + ItemStack item = new ItemStack(newStack.getItem(), amt, damage); mainInventory[i] = item; } } diff --git a/src/com/sijobe/spc/command/Teleport.java b/src/com/sijobe/spc/command/Teleport.java index e1a3a97..c87caf1 100644 --- a/src/com/sijobe/spc/command/Teleport.java +++ b/src/com/sijobe/spc/command/Teleport.java @@ -16,6 +16,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "teleport", diff --git a/src/com/sijobe/spc/command/Time.java b/src/com/sijobe/spc/command/Time.java index 8d3ca55..e87e8b1 100644 --- a/src/com/sijobe/spc/command/Time.java +++ b/src/com/sijobe/spc/command/Time.java @@ -14,6 +14,7 @@ * Provides methods of changing the current Minecraft time * * @author simo_415 + * @status survived 1.7.2 update */ @Command ( name = "time", diff --git a/src/com/sijobe/spc/command/UsePortal.java b/src/com/sijobe/spc/command/UsePortal.java index 45427ab..a55fe34 100644 --- a/src/com/sijobe/spc/command/UsePortal.java +++ b/src/com/sijobe/spc/command/UsePortal.java @@ -14,6 +14,7 @@ * * @author simo_415 * @version 1.0 + * @status broken through 1.7.2 update */ @Command ( name = "useportal", diff --git a/src/com/sijobe/spc/command/Waypoint.java b/src/com/sijobe/spc/command/Waypoint.java index 7bafcda..395fbe9 100644 --- a/src/com/sijobe/spc/command/Waypoint.java +++ b/src/com/sijobe/spc/command/Waypoint.java @@ -19,6 +19,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ public class Waypoint extends MultipleCommands { diff --git a/src/com/sijobe/spc/command/Weather.java b/src/com/sijobe/spc/command/Weather.java index 86d6e13..af6e957 100644 --- a/src/com/sijobe/spc/command/Weather.java +++ b/src/com/sijobe/spc/command/Weather.java @@ -22,6 +22,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "weather", diff --git a/src/com/sijobe/spc/core/Constants.java b/src/com/sijobe/spc/core/Constants.java index 4b946dd..c3e5019 100644 --- a/src/com/sijobe/spc/core/Constants.java +++ b/src/com/sijobe/spc/core/Constants.java @@ -14,11 +14,10 @@ * @version 1.0 */ public class Constants { - - /** + /** * Contains the version string of the current Minecraft version */ - public static final String VERSION = "4.9"; + public static final String VERSION = "1.7.2"; /** * The name of the mod @@ -28,7 +27,7 @@ public class Constants { /** * The current version of the mod */ - public static final ModVersion SPC_VERSION = new ModVersion(NAME, VERSION, new Date(1374315917859L)); // 2013-07-20 20:25:17 + public static final ModVersion SPC_VERSION = new ModVersion(NAME, VERSION, new Date(1415419100)); // November 7, 2014 9:58 pm /** * The directory that the mod saves/loads global settings from diff --git a/src/com/sijobe/spc/hooks/InitialiseCommands.java b/src/com/sijobe/spc/hooks/InitialiseCommands.java index 7d38e62..ff61847 100644 --- a/src/com/sijobe/spc/hooks/InitialiseCommands.java +++ b/src/com/sijobe/spc/hooks/InitialiseCommands.java @@ -6,7 +6,6 @@ import com.sijobe.spc.core.SPCLoader; import com.sijobe.spc.util.DynamicClassLoader; import com.sijobe.spc.util.FontColour; -import com.sijobe.spc.worldedit.WorldEditEvents; import com.sijobe.spc.wrapper.CommandBase; import com.sijobe.spc.wrapper.CommandManager; import com.sijobe.spc.wrapper.Player; @@ -17,10 +16,14 @@ import java.util.List; /** + * back in 1.6.2... + * * Initialises SPC by adding the commands to the system. The class is * dynamically loaded by the HookManager when hooks of type PlayerMP are * loaded, this is done by the Minecraft class EntityPlayerMP when it is * first referenced using static invokes. + * + * Now this happens through ModSpc.init * * @author simo_415 * @version 1.0 @@ -41,15 +44,22 @@ public class InitialiseCommands extends PlayerMP { * The welcome message to send */ private static final String WELCOME_MESSAGE = FontColour.GREY + - "Single Player Commands (" + Constants.VERSION + ") - " + FontColour.ORANGE + "http://bit.ly/spcmod"; + "Single Player Commands (" + Constants.VERSION + ") - " + FontColour.ORANGE + "http://bit.ly/spcmod <-- link to simo_415 website, not the updater's\n" + + FontColour.WHITE + + "This version of SPC is untested and may contain bugs\n" + + "or cause minecraft to crash.\n" + + "Use at your own risk\n" + + "Also, SPC will not notify you if there is another update;\n" + + "you must check manually.\n" + + "Now SPC does not contain World Edit;\n" + + "you must download it manually."; /** * Pending messages */ - private static final List pendingMessages = new ArrayList(); + public static final List pendingMessages = new ArrayList(); public InitialiseCommands() { - loadCommands(); } @Override @@ -71,14 +81,17 @@ public void onTick(Player player) { * Sends the startup message when the mod has loaded */ private void sendStartupMessage(Player player) { - player.sendChatMessage(WELCOME_MESSAGE); + for(String line : WELCOME_MESSAGE.split("\n")) + { + player.sendChatMessage(line); + } } /** * Loads standard and multiple commands into the game. This method is run * as a thread to keep execution time to a minimum. */ - private void loadCommands() { + public void loadCommands() { (new Thread() { @Override public void run() { @@ -88,17 +101,6 @@ public void run() { // Load Commands Sets loadMultipleCommands(); - try { - if(com.sijobe.spc.worldedit.WorldEditCommandSet.getCurrentInstance() == null) { - Class.forName("com.sk89q.worldedit.WorldEdit"); - System.out.println("SPCommands: Forcing command re-load."); - loadMultipleCommands(); - } - } catch (Throwable t) { - WorldEditEvents.disableHandleEvents(); - pendingMessages.add("WorldEdit.jar not found in .minecraft/bin - WE unavailable."); - } - // Load Standard Commands loadStandardCommands(); IS_LOADED = true; @@ -120,9 +122,11 @@ private void loadStandardCommands() { if (!cmd.isEnabled()) { continue; } + if (doesCommandExist(cmd)) { // TODO: review this System.out.println("Overwriting existing command named: " + cmd.getName()); } + CommandManager.registerCommand(cmd); } catch (Exception e) { System.err.println("There was an issue initialising class " + diff --git a/src/com/sijobe/spc/hooks/WorldEditCUI.java b/src/com/sijobe/spc/hooks/WorldEditCUI.java index f2b2414..b1f6950 100644 --- a/src/com/sijobe/spc/hooks/WorldEditCUI.java +++ b/src/com/sijobe/spc/hooks/WorldEditCUI.java @@ -8,7 +8,6 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import net.minecraft.src.BaseMod; public class WorldEditCUI implements ICUIEventHandler { @@ -99,12 +98,17 @@ private Object getWorldEditCUIMod() { if(WorldEditCUIMod == null && hasModLoader) { try { Method method = mlClass.getMethod("getLoadedMods"); - List mods = (List)method.invoke(null); - for(BaseMod mod : mods) { - if(mod.getName().equals("mod_WorldEditCUI")) { - loadedWorldEditCUI = true; - return mod; - } + List mods = (List)method.invoke(null); + for(Object mod : mods) { + if(mod.getClass().getName() == "BaseMod") + { + Method meth = mod.getClass().getMethod("getName"); + if(meth.invoke(mod).equals("mod_WorldEditCUI")) + { + loadedWorldEditCUI = true; + return mod; + } + } } } catch (Throwable t) { t.printStackTrace(); diff --git a/src/com/sijobe/spc/overwrite/ONetServerHandler.java b/src/com/sijobe/spc/overwrite/ONetServerHandler.java index ba9a836..7beb31a 100644 --- a/src/com/sijobe/spc/overwrite/ONetServerHandler.java +++ b/src/com/sijobe/spc/overwrite/ONetServerHandler.java @@ -8,13 +8,13 @@ import java.lang.reflect.Field; import java.util.HashMap; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.play.client.C03PacketPlayer; import net.minecraft.server.MinecraftServer; -import net.minecraft.src.AxisAlignedBB; -import net.minecraft.src.EntityPlayerMP; -import net.minecraft.src.INetworkManager; -import net.minecraft.src.NetServerHandler; -import net.minecraft.src.Packet10Flying; -import net.minecraft.src.WorldServer; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.world.WorldServer; /** * Custom server handler to allow noclip @@ -24,9 +24,9 @@ * @author q3hardcore * @version 1.4 */ -public final class ONetServerHandler extends NetServerHandler { +public final class ONetServerHandler extends NetHandlerPlayServer { - private final NetServerHandler oldInstance; + private final NetHandlerPlayServer oldInstance; private final MinecraftServer mcServer; private int ticksForFloatKick; private double lastPosX; @@ -45,7 +45,7 @@ public final class ONetServerHandler extends NetServerHandler { fieldMappings.put("hasMoved", new String[]{"q", "field_72587_r"}); } - public ONetServerHandler(MinecraftServer par1, INetworkManager par2, EntityPlayerMP par3, NetServerHandler instance) { + public ONetServerHandler(MinecraftServer par1, NetworkManager par2, EntityPlayerMP par3, NetHandlerPlayServer instance) { super(par1, par2, par3); if(instance instanceof ONetServerHandler) { @@ -54,10 +54,10 @@ public ONetServerHandler(MinecraftServer par1, INetworkManager par2, EntityPlaye oldInstance = instance; mcServer = par1; - connectionClosed = oldInstance.connectionClosed; + //connectionClosed = oldInstance.connectionClosed; //probably unnecessary for 1.7.2 } - public NetServerHandler getOldInstance() { + public NetHandlerPlayServer getOldInstance() { return oldInstance; } @@ -92,10 +92,10 @@ private void setPosition(double x, double y, double z) { } @Override - public void handleFlying(Packet10Flying par1Packet10Flying) + public void processPlayer(C03PacketPlayer packet) //don't know equivalant packet in 1.7.2 { // we use Forge's handleFlying method - if(!ForgeHelper.HAS_FORGE) { + if(!ForgeHelper.HAS_FORGE) { //TODO remove this updateHasMoved(); updatePosition(); } @@ -104,10 +104,11 @@ public void handleFlying(Packet10Flying par1Packet10Flying) // Forge has Noclip support if(ForgeHelper.HAS_FORGE) { - super.handleFlying(par1Packet10Flying); + super.processPlayer(packet); return; } - + + /* removed since spc now needs forge WorldServer var2 = this.mcServer.worldServerForDimension(oldInstance.playerEntity.dimension); if (!oldInstance.playerEntity.playerConqueredTheEnd) @@ -116,9 +117,9 @@ public void handleFlying(Packet10Flying par1Packet10Flying) if (!hasMoved) { - var3 = par1Packet10Flying.yPosition - lastPosY; + var3 = packet.yPosition - lastPosY; - if (par1Packet10Flying.xPosition == lastPosX && var3 * var3 < 0.01D && par1Packet10Flying.zPosition == lastPosZ) + if (packet.xPosition == lastPosX && var3 * var3 < 0.01D && packet.zPosition == lastPosZ) { setHasMoved(true); hasMoved = true; @@ -143,26 +144,26 @@ public void handleFlying(Packet10Flying par1Packet10Flying) double var35 = 0.0D; var13 = 0.0D; - if (par1Packet10Flying.rotating) + if (packet.rotating) { - var34 = par1Packet10Flying.yaw; - var4 = par1Packet10Flying.pitch; + var34 = packet.yaw; + var4 = packet.pitch; } - if (par1Packet10Flying.moving && par1Packet10Flying.yPosition == -999.0D && par1Packet10Flying.stance == -999.0D) + if (packet.moving && packet.yPosition == -999.0D && packet.stance == -999.0D) { - if (Math.abs(par1Packet10Flying.xPosition) > 1.0D || Math.abs(par1Packet10Flying.zPosition) > 1.0D) + if (Math.abs(packet.xPosition) > 1.0D || Math.abs(packet.zPosition) > 1.0D) { - System.err.println(oldInstance.playerEntity.getUsername() + " was caught trying to crash the server with an invalid position."); + System.err.println(oldInstance.playerEntity.getGameProfile().getName() + " was caught trying to crash the server with an invalid position."); this.kickPlayerFromServer("Nope!"); return; } - var35 = par1Packet10Flying.xPosition; - var13 = par1Packet10Flying.zPosition; + var35 = packet.xPosition; + var13 = packet.zPosition; } - this.playerEntity.onGround = par1Packet10Flying.onGround; + this.playerEntity.onGround = packet.onGround; this.playerEntity.onUpdateEntity(); this.playerEntity.moveEntity(var35, 0.0D, var13); this.playerEntity.setPositionAndRotation(var5, var7, var9, var34, var4); @@ -172,14 +173,14 @@ public void handleFlying(Packet10Flying par1Packet10Flying) /*TODO if (this.playerEntity.ridingEntity != null) { var2.uncheckedUpdateEntity(this.playerEntity.ridingEntity, true); - }*/ + }* if (this.playerEntity.ridingEntity != null) { this.playerEntity.ridingEntity.updateRiderPosition(); } - this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); + this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); //can't find equivalant function in 1.7.2 lastPosX = this.playerEntity.posX; lastPosY = this.playerEntity.posY; lastPosZ = this.playerEntity.posZ; @@ -207,36 +208,36 @@ public void handleFlying(Packet10Flying par1Packet10Flying) float var11 = this.playerEntity.rotationYaw; float var12 = this.playerEntity.rotationPitch; - if (par1Packet10Flying.moving && par1Packet10Flying.yPosition == -999.0D && par1Packet10Flying.stance == -999.0D) + if (packet.moving && packet.yPosition == -999.0D && packet.stance == -999.0D) { - par1Packet10Flying.moving = false; + packet.moving = false; } - if (par1Packet10Flying.moving) + if (packet.moving) { - var5 = par1Packet10Flying.xPosition; - var7 = par1Packet10Flying.yPosition; - var9 = par1Packet10Flying.zPosition; - var13 = par1Packet10Flying.stance - par1Packet10Flying.yPosition; + var5 = packet.xPosition; + var7 = packet.yPosition; + var9 = packet.zPosition; + var13 = packet.stance - packet.yPosition; if (!this.playerEntity.isPlayerSleeping() && (var13 > 1.65D || var13 < 0.1D)) { this.kickPlayerFromServer("Illegal stance"); - this.mcServer.getLogAgent().logWarning(this.playerEntity.getUsername() + " had an illegal stance: " + var13); + this.mcServer.logWarning(this.playerEntity.getCommandSenderName() + " had an illegal stance: " + var13); return; } - if (Math.abs(par1Packet10Flying.xPosition) > 3.2E7D || Math.abs(par1Packet10Flying.zPosition) > 3.2E7D) + if (Math.abs(packet.xPosition) > 3.2E7D || Math.abs(packet.zPosition) > 3.2E7D) { this.kickPlayerFromServer("Illegal position"); return; } } - if (par1Packet10Flying.rotating) + if (packet.rotating) { - var11 = par1Packet10Flying.yaw; - var12 = par1Packet10Flying.pitch; + var11 = packet.yaw; + var12 = packet.pitch; } this.playerEntity.onUpdateEntity(); @@ -256,9 +257,9 @@ public void handleFlying(Packet10Flying par1Packet10Flying) double var23 = Math.min(Math.abs(var17), Math.abs(this.playerEntity.motionZ)); double var25 = var19 * var19 + var21 * var21 + var23 * var23; - if (var25 > 100.0D && (!this.mcServer.isSinglePlayer() || !this.mcServer.getServerOwner().equals(this.playerEntity.getUsername()))) + if (var25 > 100.0D && (!this.mcServer.isSinglePlayer() || !this.mcServer.getServerOwner().equals(this.playerEntity.getCommandSenderName()))) { - this.mcServer.getLogAgent().logWarning(this.playerEntity.getUsername() + " moved too quickly! " + var13 + "," + var15 + "," + var17 + " (" + var19 + ", " + var21 + ", " + var23 + ")"); + this.mcServer.logWarning(this.playerEntity.getCommandSenderName() + " moved too quickly! " + var13 + "," + var15 + "," + var17 + " (" + var19 + ", " + var21 + ", " + var23 + ")"); this.setPlayerLocation(lastPosX, lastPosY, lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch); return; } @@ -266,13 +267,13 @@ public void handleFlying(Packet10Flying par1Packet10Flying) float var27 = 0.0625F; boolean var28 = var2.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.boundingBox.copy().contract(var27, var27, var27)).isEmpty(); - if (this.playerEntity.onGround && !par1Packet10Flying.onGround && var15 > 0.0D) + if (this.playerEntity.onGround && !packet.onGround && var15 > 0.0D) { this.playerEntity.addExhaustion(0.2F); } this.playerEntity.moveEntity(var13, var15, var17); - this.playerEntity.onGround = par1Packet10Flying.onGround; + this.playerEntity.onGround = packet.onGround; this.playerEntity.addMovementStat(var13, var15, var17); double var29 = var15; var13 = var5 - this.playerEntity.posX; @@ -290,7 +291,7 @@ public void handleFlying(Packet10Flying par1Packet10Flying) if (var25 > 0.0625D && !this.playerEntity.isPlayerSleeping() && !this.playerEntity.theItemInWorldManager.isCreative()) { var31 = true; - this.mcServer.getLogAgent().logWarning(this.playerEntity.getUsername() + " moved wrongly!"); + this.mcServer.logWarning(this.playerEntity.getCommandSenderName() + " moved wrongly!"); } this.playerEntity.setPositionAndRotation(var5, var7, var9, var11, var12); @@ -315,7 +316,7 @@ else if (var28 && (var31 || !var32) && !this.playerEntity.isPlayerSleeping()) if (ticksForFloatKick > 80) { - this.mcServer.getLogAgent().logWarning(this.playerEntity.getUsername() + " was kicked for floating too long!"); + this.mcServer.logWarning(this.playerEntity.getCommandSenderName() + " was kicked for floating too long!"); this.kickPlayerFromServer("Flying is not enabled on this server"); return; } @@ -326,10 +327,11 @@ else if (var28 && (var31 || !var32) && !this.playerEntity.isPlayerSleeping()) ticksForFloatKick = 0; } - this.playerEntity.onGround = par1Packet10Flying.onGround; - this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); - this.playerEntity.updateFlyingState(this.playerEntity.posY - var3, par1Packet10Flying.onGround); + this.playerEntity.onGround = packet.onGround; + this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); //can't find equivalant function in 1.7.2 + this.playerEntity.updateFlyingState(this.playerEntity.posY - var3, packet.onGround); } } + */ } } diff --git a/src/com/sijobe/spc/util/CommandBlockHelper.java b/src/com/sijobe/spc/util/CommandBlockHelper.java index 8a75d83..53fe8cb 100644 --- a/src/com/sijobe/spc/util/CommandBlockHelper.java +++ b/src/com/sijobe/spc/util/CommandBlockHelper.java @@ -4,20 +4,21 @@ import java.util.List; import net.minecraft.server.MinecraftServer; -import net.minecraft.src.CommandBase; -import net.minecraft.src.CommandDifficulty; -import net.minecraft.src.CommandEffect; -import net.minecraft.src.CommandEnchant; -import net.minecraft.src.CommandException; -import net.minecraft.src.CommandGameMode; -import net.minecraft.src.CommandGive; -import net.minecraft.src.CommandHelp; -import net.minecraft.src.CommandTime; -import net.minecraft.src.CommandWeather; -import net.minecraft.src.EntityPlayerMP; -import net.minecraft.src.EnumChatFormatting; -import net.minecraft.src.ICommandSender; -import net.minecraft.src.StatCollector; +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandDifficulty; +import net.minecraft.command.CommandEffect; +import net.minecraft.command.CommandEnchant; +import net.minecraft.command.CommandException; +import net.minecraft.command.CommandGameMode; +import net.minecraft.command.CommandGive; +import net.minecraft.command.CommandHelp; +import net.minecraft.command.CommandTime; +import net.minecraft.command.CommandWeather; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.StatCollector; /** * Helper to make command blocks execute vanilla commands @@ -42,7 +43,7 @@ public static boolean handleCommand(String cmdName, ICommandSender sender, Strin for(EntityPlayerMP plr : players) { if(plr.canCommandSenderUseCommand(2, "") && plr.capabilities.isCreativeMode) { String cmdErr = StatCollector.translateToLocalFormatted(ce.getMessage(), ce.getErrorOjbects()); - plr.addChatMessage(EnumChatFormatting.RED + cmdErr); + plr.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + cmdErr)); } } } diff --git a/src/com/sijobe/spc/util/DynamicClassLoader.java b/src/com/sijobe/spc/util/DynamicClassLoader.java index fcb4465..e7f57e7 100644 --- a/src/com/sijobe/spc/util/DynamicClassLoader.java +++ b/src/com/sijobe/spc/util/DynamicClassLoader.java @@ -150,7 +150,7 @@ private static Vector> getSPCClasses() throws Exception { System.out.println("SPC: " + root); tempSPCClasses = loadSPCClassesFromJAR(root); } else { - File dynamicClassLoader = new File(location.getFile()); + File dynamicClassLoader = new File(location.getFile().replace("%20", " ")); //added replace for paths with spaces File parentDir = getSPCParent(dynamicClassLoader); if(parentDir == null) { System.out.println("SPC: Not loading."); diff --git a/src/com/sijobe/spc/util/ForgeHelper.java b/src/com/sijobe/spc/util/ForgeHelper.java index 32f079c..2f8698d 100644 --- a/src/com/sijobe/spc/util/ForgeHelper.java +++ b/src/com/sijobe/spc/util/ForgeHelper.java @@ -5,16 +5,16 @@ import java.lang.reflect.Method; import java.util.ArrayList; -import net.minecraft.src.ChunkCoordIntPair; -import net.minecraft.src.ChunkCoordinates; -import net.minecraft.src.DamageSource; -import net.minecraft.src.Entity; -import net.minecraft.src.EntityItem; -import net.minecraft.src.EntityLiving; -import net.minecraft.src.EntityPlayer; -import net.minecraft.src.EntityPlayerMP; -import net.minecraft.src.ItemInWorldManager; -import net.minecraft.src.WorldProvider; +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.DamageSource; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.management.ItemInWorldManager; +import net.minecraft.world.WorldProvider; /** * Helper for compatiblity with Minecraft Forge diff --git a/src/com/sijobe/spc/util/PathData.java b/src/com/sijobe/spc/util/PathData.java new file mode 100644 index 0000000..96ace35 --- /dev/null +++ b/src/com/sijobe/spc/util/PathData.java @@ -0,0 +1,23 @@ +package com.sijobe.spc.util; + +import com.sijobe.spc.wrapper.Block; + +public class PathData +{ + public Block block; + public int meta; + public int size; + public int prevx; + public int prevy; + public int prevz; + + public PathData(Block block, int meta, int size) + { + this.block = block; + this.meta = meta; + this.size = size; + this.prevx = -1; + this.prevy = -1; + this.prevz = -1; + } +} diff --git a/src/com/sijobe/spc/worldedit/LocalPlayer.java b/src/com/sijobe/spc/worldedit/LocalPlayer.java deleted file mode 100644 index cdb32f4..0000000 --- a/src/com/sijobe/spc/worldedit/LocalPlayer.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.sijobe.spc.worldedit; - -import com.sijobe.spc.core.ICUIEventHandler; -import com.sijobe.spc.util.FontColour; -import com.sijobe.spc.util.WorldEditCUIHelper; -import com.sijobe.spc.wrapper.Coordinate; -import com.sijobe.spc.wrapper.Player; -import com.sk89q.worldedit.ServerInterface; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.WorldVector; -import com.sk89q.worldedit.bags.BlockBag; -import com.sk89q.worldedit.cui.CUIEvent; - -public class LocalPlayer extends com.sk89q.worldedit.LocalPlayer { - - private Player player; - - protected LocalPlayer(Player player, ServerInterface server) { - super(server); - this.player = player; - } - - @Override - public String[] getGroups() { - // TODO Auto-generated method stub - return null; - } - - @Override - public BlockBag getInventoryBlockBag() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getItemInHand() { - return player.getCurrentItem(); - } - - @Override - public String getName() { - return player.getPlayerName(); - } - - @Override - public double getPitch() { - return player.getPitch(); - } - - @Override - public WorldVector getPosition() { - Coordinate c = player.getPosition(); - return new WorldVector(getWorld(), c.getX(), c.getY(), c.getZ()); - } - - @Override - public com.sk89q.worldedit.LocalWorld getWorld() { - return new LocalWorld(player.getWorld()); - } - - @Override - public double getYaw() { - return player.getYaw(); - } - - @Override - public void giveItem(int type, int quantity) { - player.givePlayerItem(type, quantity); - } - - @Override - public boolean hasPermission(String arg0) { - // TODO Check permissions - return true; - } - - @Override - public void print(String message) { - player.sendChatMessage(message); - } - - @Override - public void printDebug(String message) { - System.out.println("WORLDEDIT-DEBUG: " + message); - } - - @Override - public void printError(String message) { - player.sendChatMessage(FontColour.RED + message); - } - - @Override - public void printRaw(String message) { // TODO: Fix - player.sendChatMessage(message); - } - - @Override - public void setPosition(Vector pos, float pitch, float yaw) { - player.setPosition(new Coordinate(pos.getX(),pos.getY(),pos.getZ())); - player.setPitch(pitch); - player.setYaw(yaw); - } - - @Override - public boolean equals(Object object) { - if (object != null && object instanceof LocalPlayer) { - return ((LocalPlayer)object).getName().equals(getName()); - } - return false; - } - - @Override - public void dispatchCUIEvent(CUIEvent event) { - for (ICUIEventHandler hook : WorldEditCUIHelper.getCUIHooks()) { - if (hook.isEnabled()) { - hook.handleCUIEvent(event.getTypeId(), event.getParameters()); - } - } - } -} diff --git a/src/com/sijobe/spc/worldedit/LocalWorld.java b/src/com/sijobe/spc/worldedit/LocalWorld.java deleted file mode 100644 index 6dcf9e1..0000000 --- a/src/com/sijobe/spc/worldedit/LocalWorld.java +++ /dev/null @@ -1,302 +0,0 @@ -package com.sijobe.spc.worldedit; - -import com.sijobe.spc.wrapper.Coordinate; -import com.sijobe.spc.wrapper.World; -import com.sk89q.worldedit.BiomeType; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.EntityType; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.Vector2D; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.regions.Region; - -// q3 code ;) -import java.util.List; -import net.minecraft.server.MinecraftServer; -import net.minecraft.src.AxisAlignedBB; -import net.minecraft.src.DamageSource; -import net.minecraft.src.Entity; -import net.minecraft.src.EntityAnimal; -import net.minecraft.src.EntityLiving; -import net.minecraft.src.EntityMob; -import net.minecraft.src.EntityPig; -import net.minecraft.src.EntityPlayer; -import net.minecraft.src.EntityPlayerMP; -import net.minecraft.src.EntityTameable; -import net.minecraft.src.EntityVillager; -import net.minecraft.src.BiomeGenBase; -import net.minecraft.src.Chunk; - -/** - * Implements the WorldEdit local world class that provides necessary methods - * required to edit the world. - * - * TODO: (can this still happen?) - * java.util.ConcurrentModificationException - at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) - at java.util.AbstractList$Itr.next(AbstractList.java:343) - at net.minecraft.src.PlayerManager.func_72693_b(PlayerManager.java:49) - at net.minecraft.src.WorldServer.tick(WorldServer.java:123) - at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:613) - at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:555) - at net.minecraft.src.IntegratedServer.tick(IntegratedServer.java:121) - at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:464) - at net.minecraft.src.ThreadServerApplication.run(ThreadServerApplication.java:17) - * - * @author simo_415 - * @version 1.2 - */ -public class LocalWorld extends com.sk89q.worldedit.LocalWorld { - - /** - * The world instance that the editing is carried out on - */ - private World world; - - /** - * Default constructor allows the world to be specified - * - * @param world - The world that the editing should be done on - */ - public LocalWorld(World world) { - this.world = world; - } - - @Override - public boolean clearContainerBlockContents(Vector pos) { - return world.emptyContainer(getCoordinate(pos)); - } - - @Override - public boolean copyFromWorld(Vector pos, BaseBlock type) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean copyToWorld(Vector pos, BaseBlock type) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void dropItem(Vector pos, BaseItemStack item) { - // TODO Auto-generated method stub - - } - - @Override - public boolean equals(Object world) { - if (world instanceof LocalWorld) { - return ((LocalWorld)world).getName().equals(getName()); - } - return false; - } - - @Override - public BiomeType getBiome(Vector2D arg0) { - BiomeGenBase biome = this.world.getMinecraftWorld().getBiomeGenForCoords(arg0.getBlockX(), arg0.getBlockZ()); // world.getWorldChunkManager().getBiomeGenAt - try { - return MinecraftBiomeType.valueOf(biome.biomeName.toUpperCase(java.util.Locale.ENGLISH)); // name - } catch(IllegalArgumentException e) { - // e.printStackTrace(); - return BiomeType.UNKNOWN; - } - } - - /** - * TODO: Implements a custom block tile entity if required - * @see https://github.com/sk89q/worldedit/blob/master/src/main/java/com/sk89q/worldedit/bukkit/NmsBlock.java - * @see https://github.com/sk89q/worldedit/blob/master/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java#L962 - * - * @see com.sk89q.worldedit.LocalWorld#getBlock(com.sk89q.worldedit.Vector) - */ - @Override - public BaseBlock getBlock(Vector pos) { - try { - return new BaseBlock(getBlockType(pos), getBlockData(pos)); - } catch (Exception e) { - return null; - } - } - - @Override - public boolean isValidBlockType(int type) { - if (type == 0) { - return true; - } - return world.isValidBlockType(type); - } - - @Override - public int getBlockData(Vector pos) { - return world.getBlockData(getCoordinate(pos)); - } - - @Override - public int getBlockLightLevel(Vector pos) { - return world.getBlockLightLevel(getCoordinate(pos)); - } - - @Override - public int getBlockType(Vector pos) { - return world.getBlockId(getCoordinate(pos)); - } - - @Override - public String getName() { - return world.getName(); - } - - @Override - public int hashCode() { - return world.getName().hashCode(); - } - - @Override - public boolean regenerate(Region arg0, EditSession arg1) { - // TODO Auto-generated method stub - return false; - } - - @Override - public int removeEntities(EntityType entity, Vector pos, int area) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void setBiome(Vector2D arg0, BiomeType arg1) { - if(arg1 instanceof MinecraftBiomeType) { - int biomeId = ((MinecraftBiomeType) arg1).getBiomeID(); - - int x = arg0.getBlockX(); - int z = arg0.getBlockZ(); - - if(this.world.getMinecraftWorld().blockExists(x, 0, z)) { // blockExists - Chunk chunk = this.world.getMinecraftWorld().getChunkFromBlockCoords(x, z); // Chunk, getChunkFromBlockCoords - if(chunk != null) { - byte[] biomevals = chunk.getBiomeArray(); // getBiomeArray - biomevals[((z & 0xF) << 4 | x & 0xF)] = (byte)biomeId; - // work around for biome data not being updated on client - com.sijobe.spc.wrapper.Minecraft.getMinecraft().thePlayer.worldObj.getChunkFromBlockCoords(x, z).setBiomeArray(biomevals); - } else { - System.err.println("Can't set biome for null chunk."); - } - } else { - System.err.println("Not setting biome."); - } - } - } - - @Override - @Deprecated - public void setBlockData(Vector pos, int block) { - world.setBlockData(getCoordinate(pos), block); - } - - @Override - @Deprecated - public void setBlockDataFast(Vector pos, int block) { - world.setBlockData(getCoordinate(pos), block); - } - - @Override - @Deprecated - public boolean setBlockType(Vector pos, int block) { - return world.setBlock(getCoordinate(pos), block); - } - - @Override - @Deprecated - public boolean generateBigTree(EditSession session, Vector pos) { - return world.generateBigTree(getCoordinate(pos)); - } - - @Override - @Deprecated - public boolean generateTree(EditSession session, Vector pos) { - return world.generateTree(getCoordinate(pos)); - } - - @Override - @Deprecated - public boolean generateTallRedwoodTree(EditSession session, Vector pos) { - return world.generateTallRedwoodTree(getCoordinate(pos)); - } - - @Override - @Deprecated - public boolean generateRedwoodTree(EditSession session, Vector pos) { - return world.generateRedwoodTree(getCoordinate(pos)); - } - - @Override - @Deprecated - public boolean generateBirchTree(EditSession session, Vector pos) { - return world.generateBirchTree(getCoordinate(pos)); - } - - @SuppressWarnings("unchecked") - public int killMobsDo(Vector pos, double radius, boolean withLightning, boolean killAnimals, boolean killNPCs, boolean killPets) { - List entities = this.world.getMinecraftWorld().getEntitiesWithinAABBExcludingEntity(null, - AxisAlignedBB.getBoundingBox(pos.getX() - (double)radius, pos.getY() - (double)radius, pos.getZ() - (double)radius, - pos.getX() + (double)radius, pos.getY() + (double)radius, pos.getZ() + (double)radius)); - int count = 0; - EntityPlayerMP owner; - try { - String firstPlayer = MinecraftServer.getServer().getServerOwner(); - owner = MinecraftServer.getServer().getConfigurationManager().getPlayerForUsername(firstPlayer); - } catch (Exception e) { - owner = null; - e.printStackTrace(); - } - for(Entity entity : entities) { - if(entity instanceof EntityLiving) { - if(entity instanceof EntityPlayer) { - continue; // don't 'kill' players (it causes issues..) - } - if(!killAnimals && entity instanceof EntityAnimal) { - continue; - } - if(!killNPCs && entity instanceof EntityVillager) { - continue; - } - if(!killPets && entity instanceof EntityTameable) { - continue; - } - boolean isPig = entity instanceof EntityPig; - Coordinate entityPos = new Coordinate(entity.posX, entity.posY, entity.posZ); - if(withLightning && !isPig) { - world.useLightning(entityPos); - } - ((EntityLiving)entity).setEntityHealth(0); - if(owner != null) { - owner.destroyedItemsNetCache.add(entity.entityId); - } - count++; - } - } - return count; - } - - @Override - public int killMobs(Vector origin, double radius, int flags) { - boolean killPets = (flags & 0x1) != 0; - boolean killNPCs = (flags & 0x2) != 0; - boolean killAnimals = (flags & 0x4) != 0; - boolean withLightning = (flags & 0x100000) != 0; - return killMobsDo(origin, radius, withLightning, killAnimals, killNPCs, killPets); - } - - /** - * Gets the coordinate object that the specified Vector object represents - * - * @param pos - The position of the coordinate - * @return The matching coordinate object - */ - private Coordinate getCoordinate(Vector pos) { - return new Coordinate(pos.getX(), pos.getY(), pos.getZ()); - } -} diff --git a/src/com/sijobe/spc/worldedit/MinecraftBiomeType.java b/src/com/sijobe/spc/worldedit/MinecraftBiomeType.java deleted file mode 100644 index 1adf6d6..0000000 --- a/src/com/sijobe/spc/worldedit/MinecraftBiomeType.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.sijobe.spc.worldedit; - -import java.lang.reflect.Field; -import java.util.Locale; -import com.sk89q.worldedit.BiomeType; -import net.minecraft.src.BiomeGenBase; - -public enum MinecraftBiomeType implements BiomeType { - - OCEAN(BiomeGenBase.biomeList[0]), - PLAINS(BiomeGenBase.biomeList[1]), - DESERT(BiomeGenBase.biomeList[2]), - EXTREMEHILLS(BiomeGenBase.biomeList[3]), - FOREST(BiomeGenBase.biomeList[4]), - TAIGA(BiomeGenBase.biomeList[5]), - SWAMPLAND(BiomeGenBase.biomeList[6]), - RIVER(BiomeGenBase.biomeList[7]), - HELL(BiomeGenBase.biomeList[8]), - SKY(BiomeGenBase.biomeList[9]), - FROZENOCEAN(BiomeGenBase.biomeList[10]), - FROZENRIVER(BiomeGenBase.biomeList[11]), - ICEPLAINS(BiomeGenBase.biomeList[12]), - ICEMOUNTAINS(BiomeGenBase.biomeList[13]), - MUSHROOMISLAND(BiomeGenBase.biomeList[14]), - MUSHROOMISLANDSHORE(BiomeGenBase.biomeList[15]), - BEACH(BiomeGenBase.biomeList[16]), - DESERTHILLS(BiomeGenBase.biomeList[17]), - FORESTHILLS(BiomeGenBase.biomeList[18]), - TAIGAHILLS(BiomeGenBase.biomeList[19]), - EXTREMEHILLSEDGE(BiomeGenBase.biomeList[20]), - JUNGLE(BiomeGenBase.biomeList[21]), - JUNGLEHILLS(BiomeGenBase.biomeList[22]); - - private BiomeGenBase biome; - - private MinecraftBiomeType(BiomeGenBase biome) { - this.biome = biome; - } - - @Override - public String getName() { - return name().toLowerCase(Locale.ENGLISH); - } - - /* - public BiomeGenBase getSPCBiome() { - return biome; - } - */ - - public int getBiomeID() { - return biome.biomeID; - } - - /* - public String getBiomeName() { - return biome.biomeName; - } - */ - -} diff --git a/src/com/sijobe/spc/worldedit/MinecraftBiomeTypes.java b/src/com/sijobe/spc/worldedit/MinecraftBiomeTypes.java deleted file mode 100644 index 7ff0dd7..0000000 --- a/src/com/sijobe/spc/worldedit/MinecraftBiomeTypes.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.sijobe.spc.worldedit; - -// Obfuscated references: 0 - -import com.sk89q.worldedit.BiomeType; -import com.sk89q.worldedit.BiomeTypes; -import com.sk89q.worldedit.UnknownBiomeTypeException; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -public class MinecraftBiomeTypes implements BiomeTypes { - - @Override - public boolean has(String name) { - try { - MinecraftBiomeType.valueOf(name.toUpperCase(Locale.ENGLISH)); - return true; - } catch (IllegalArgumentException var3) { - return false; - } - } - - @Override - public BiomeType get(String name) throws UnknownBiomeTypeException { - try { - return MinecraftBiomeType.valueOf(name.toUpperCase(Locale.ENGLISH)); - } catch (IllegalArgumentException var3) { - throw new UnknownBiomeTypeException(name); - } - } - - @Override - public List all() { - return Arrays.asList(MinecraftBiomeType.values()); - } -} diff --git a/src/com/sijobe/spc/worldedit/PropertiesConfiguration.java b/src/com/sijobe/spc/worldedit/PropertiesConfiguration.java deleted file mode 100644 index aaa56bf..0000000 --- a/src/com/sijobe/spc/worldedit/PropertiesConfiguration.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sijobe.spc.worldedit; - -import com.sijobe.spc.core.Constants; - -import java.io.File; - -public class PropertiesConfiguration extends com.sk89q.worldedit.util.PropertiesConfiguration { - - /** - * Initialises the class - */ - public PropertiesConfiguration() { - super(new File(Constants.MOD_DIR,"worldedit.properties")); - } - - /** - * @see com.sk89q.worldedit.LocalConfiguration#getWorkingDirectory() - */ - @Override - public File getWorkingDirectory() { - return Constants.MOD_DIR; - } -} diff --git a/src/com/sijobe/spc/worldedit/ServerInterface.java b/src/com/sijobe/spc/worldedit/ServerInterface.java deleted file mode 100644 index 035718a..0000000 --- a/src/com/sijobe/spc/worldedit/ServerInterface.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.sijobe.spc.worldedit; - -import com.sk89q.worldedit.BiomeTypes; - - -public class ServerInterface extends com.sk89q.worldedit.ServerInterface { - - private BiomeTypes biomes; - - /** - * Initialises the class - */ - public ServerInterface() { - super(); - biomes = new MinecraftBiomeTypes(); - } - - @Override - public BiomeTypes getBiomes() { - // TODO Auto-generated method stub - return biomes; - } - - @Override - public boolean isValidMobType(String arg0) { - // TODO Auto-generated method stub - return true; - } - - @Override - public void reload() { - // TODO Auto-generated method stub - - } - - @Override - public int resolveItem(String arg0) { - // TODO Auto-generated method stub - return 0; - } -} diff --git a/src/com/sijobe/spc/worldedit/WorldEditCommandSet.java b/src/com/sijobe/spc/worldedit/WorldEditCommandSet.java deleted file mode 100644 index 659aa1c..0000000 --- a/src/com/sijobe/spc/worldedit/WorldEditCommandSet.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.sijobe.spc.worldedit; - -import com.sijobe.spc.command.MultipleCommands; -import com.sijobe.spc.core.IHook; -import com.sijobe.spc.util.WorldEditCUIHelper; -import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Coordinate; -import com.sijobe.spc.wrapper.MinecraftServer; -import com.sijobe.spc.wrapper.Player; - -import java.util.List; - -/** - * The class that provides connection to WorldEdit. - * - * @author simo_415 - * @version 1.2 - */ -public class WorldEditCommandSet extends MultipleCommands { - - /*static { - DynamicClassLoader.addFile(new File(Minecraft.getMinecraftDirectory(),"bin/WorldEdit.jar")); - }*/ - - /** - * The WorldEdit object that the class communicates to WorldEdit with - */ - public static com.sk89q.worldedit.WorldEdit WORLDEDIT; - /** - * The server interface that WorldEdit is using - */ - public static ServerInterface SERVER; - /** - * The configuration that WorldEdit is using - */ - public static PropertiesConfiguration CONFIGURATION; - - /** - * Stores the last instance of this class that was created - */ - private static WorldEditCommandSet INSTANCE; - - /** - * Used to store the last time (in ms) that a left-click was sent - */ - private long leftClick; - /** - * Used to store the last time (in ms) that a right-click was sent - */ - private long rightClick; - - private long leftBlock; - private long rightBlock; - - /** - * Provides a delay between sending mouse updates to WorldEdit - */ - private static final int CLICK_DELAY = 200; - - public WorldEditCommandSet(String name) { - super(name); - - CONFIGURATION = new PropertiesConfiguration(); - CONFIGURATION.load(); - - SERVER = new ServerInterface(); - - WORLDEDIT = new com.sk89q.worldedit.WorldEdit(SERVER, CONFIGURATION); - - leftClick = rightClick = leftBlock = rightBlock = System.currentTimeMillis(); - - INSTANCE = this; - } - - /** - * Gets the currently constructed instance of the class. This allows reuse - * of the same class by multiple implementing classes without having to - * create new instances and deal with that. - * - * @return The current instance of this class - */ - public static WorldEditCommandSet getCurrentInstance() { - return INSTANCE; - } - - @Override - public String[] getCommands() { - return WORLDEDIT.getCommands().keySet().toArray(new String[]{}); - } - - @Override - public String getDescription() { - return WORLDEDIT.getCommands().get(getName()); - } - - @Override - public void execute(CommandSender sender, List params) { - String command[] = null; - if (params.size() == 1) { - String split[] = ((String)params.get(0)).split(" "); - command = new String[split.length + 1]; - for (int i = 1; i < command.length; i++) { - command[i] = split[i - 1]; - } - command[0] = "/" + getName(); - } else { - command = new String[] { "/" + getName() }; - } - handleCommand(getSenderAsPlayer(sender), command); - } - - /** - * Handles a command that is sent to a WorldEdit command - * - * @param player - The player that executed the command - * @param command - The arguments (command) that the player sent - */ - public void handleCommand(Player player, String command[]) { - LocalPlayer localPlayer = getLocalPlayer(player); - WORLDEDIT.handleCommand(localPlayer, command); - } - - private static LocalPlayer getLocalPlayer(Player player) { - LocalPlayer localPlayer = new LocalPlayer(player, SERVER); - if(player.getPlayerName().equals(MinecraftServer.getMinecraftServer().getServerOwner())) { - if(hasCUIHooks()) { - WORLDEDIT.getSession(localPlayer).setCUISupport(true); - WORLDEDIT.getSession(localPlayer).dispatchCUISetup(localPlayer); - } - } - return localPlayer; - } - - private static boolean hasCUIHooks() { - int cuiHooks = 0; - for(IHook hook : WorldEditCUIHelper.getCUIHooks()) { - if(hook.isEnabled()) { - cuiHooks++; - } - } - return (cuiHooks > 0); - } - - /** - * Handles a player arm swing event - * - * @param player - The player the event occurred on - */ - public void handleArmSwing(Player player) { - if (leftClick + CLICK_DELAY < System.currentTimeMillis()) { - LocalPlayer localPlayer = getLocalPlayer(MinecraftServer.getPlayerByUsername(player.getPlayerName())); - WORLDEDIT.handleArmSwing(localPlayer); - leftClick = System.currentTimeMillis(); - } - } - - /** - * Handles a player right-click event - * - * @param player - The player the event occurred on - */ - public void handleRightClick(Player player) { - if (rightClick + CLICK_DELAY < System.currentTimeMillis()) { - LocalPlayer localPlayer = getLocalPlayer(MinecraftServer.getPlayerByUsername(player.getPlayerName())); - WORLDEDIT.handleRightClick(localPlayer); - rightClick = System.currentTimeMillis(); - } - } - - /** - * Handles a player left clicking a block - * - * @param player - The player the event occurred on - * @param block - The block that the player clicked - */ - public void handleBlockLeftClick(Player player, Coordinate block) { - if (leftBlock + CLICK_DELAY < System.currentTimeMillis()) { - LocalPlayer localPlayer = getLocalPlayer(MinecraftServer.getPlayerByUsername(player.getPlayerName())); - com.sk89q.worldedit.WorldVector vector = new com.sk89q.worldedit.WorldVector(localPlayer.getWorld(), block.getBlockX(), block.getBlockY(), block.getBlockZ()); - WORLDEDIT.handleBlockLeftClick(localPlayer, vector); - leftBlock = System.currentTimeMillis(); - } - } - - /** - * Handles a player right clicking a block - * - * @param player - The player the event occurred on - * @param block - The block that the player clicked - */ - public void handleBlockRightClick(Player player, Coordinate block) { - if (rightBlock + CLICK_DELAY < System.currentTimeMillis()) { - LocalPlayer localPlayer = getLocalPlayer(MinecraftServer.getPlayerByUsername(player.getPlayerName())); - com.sk89q.worldedit.WorldVector vector = new com.sk89q.worldedit.WorldVector(localPlayer.getWorld(), block.getBlockX(), block.getBlockY(), block.getBlockZ()); - WORLDEDIT.handleBlockRightClick(localPlayer, vector); - rightBlock = System.currentTimeMillis(); - } - } -} diff --git a/src/com/sijobe/spc/worldedit/WorldEditEvents.java b/src/com/sijobe/spc/worldedit/WorldEditEvents.java deleted file mode 100644 index aa53540..0000000 --- a/src/com/sijobe/spc/worldedit/WorldEditEvents.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.sijobe.spc.worldedit; - -import com.sijobe.spc.core.PlayerSP; -import com.sijobe.spc.wrapper.Coordinate; -import com.sijobe.spc.wrapper.Minecraft; -import com.sijobe.spc.wrapper.Player; - -import java.util.HashMap; -import java.util.Map; - -import org.lwjgl.input.Mouse; - -/** - * Handles the client-side events that occur such as mouse events for - * WorldEdit. When the events are detected they are passed to the - * WorldEditCommandSet class. - * - * @author simo_415 - * @version 1.0 - */ -public class WorldEditEvents extends PlayerSP { - - private Map left; - private Map right; - private String lastCrash = ""; - private static boolean handleEvents = true; - - /** - * The max range that the mouse methods trace the blocks for - */ - private static final int TRACE_RANGE = 128; - - public WorldEditEvents() { - left = new HashMap(); - right = new HashMap(); - } - - /* - * Disable WorldEdit event handling. This is done when WorldEdit - * hasn't been loaded, so that possible exceptions are avoided. - */ - public static void disableHandleEvents() { - handleEvents = false; - } - - /** - * Returns whether or not WorldEdit event handling is enabled - * - * @return True if WE event handling enabled, false otherwise - */ - public static boolean getHandleEvents() { - return handleEvents; - } - - @Override - public void onTick(Player player) { - if (Minecraft.isGuiScreenOpen()) { - return; - } - if(!handleEvents) { - return; - } - try { - // Check left button down - checkLeftButton(player); - - // Check right button down - checkRightButton(player); - } catch (Throwable t) { - String currentCrash = t.toString(); - if(currentCrash.equals(lastCrash)) { - return; - } else { - lastCrash = currentCrash; - } - t.printStackTrace(); - } - } - - /** - * Checks if the left mouse button was pressed, if so then it will call the - * appropriate WorldEdit method for arm swinging or block hitting if they - * occur. - * - * @param player - The player that triggered the mouse button - */ - private void checkLeftButton(Player player) { - if (Mouse.isButtonDown(0)) { - Coordinate hit = null; - if ((hit = player.trace(TRACE_RANGE)) != null) { - WorldEditCommandSet.getCurrentInstance().handleArmSwing(player); - if (!hit.equals(left.get(player.getPlayerName()))) { - left.put(player.getPlayerName(), hit); - WorldEditCommandSet.getCurrentInstance().handleBlockLeftClick(player, hit); - } - } - } - } - - /** - * Checks if the right mouse button was pressed, if so then it will call the - * appropriate WorldEdit method for arm swinging or block hitting if they - * occur. - * - * @param player - The player that triggered the mouse button - */ - private void checkRightButton(Player player) { - if (Mouse.isButtonDown(1)) { - Coordinate hit = null; - if ((hit = player.trace(TRACE_RANGE)) != null) { - WorldEditCommandSet.getCurrentInstance().handleRightClick(player); - if (!hit.equals(right.get(player.getPlayerName()))) { - right.put(player.getPlayerName(), hit); - WorldEditCommandSet.getCurrentInstance().handleBlockRightClick(player, hit); - } - } - } - } -} diff --git a/src/com/sijobe/spc/wrapper/Block.java b/src/com/sijobe/spc/wrapper/Block.java new file mode 100644 index 0000000..37ff114 --- /dev/null +++ b/src/com/sijobe/spc/wrapper/Block.java @@ -0,0 +1,52 @@ +package com.sijobe.spc.wrapper; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import net.minecraft.util.RegistryNamespaced; + +public class Block +{ + public static final RegistryNamespaced blockRegistry = new RegistryNamespaced(); + public static final Map conversionRegistry = new HashMap(); + public static final RegistryNamespaced realBlockRegistry = net.minecraft.block.Block.blockRegistry; + + public static void init() + { + /*registers blocks*/ + for(Object i : realBlockRegistry) + { + net.minecraft.block.Block block = (net.minecraft.block.Block) i; + Block wrapped = new Block(block); + blockRegistry.putObject(realBlockRegistry.getNameForObject(block), wrapped); + conversionRegistry.put(block, wrapped); + } + Blocks.init(); + } + + /*returns the block with the given id*/ + public static Block fromId(int id) + { + return (Block) blockRegistry.getObject(realBlockRegistry.getNameForObject(realBlockRegistry.getObjectById(id))); + } + + /*converts a minecraft block to a wrapped block. opposite of Block.convert()*/ + public static Block fromMinecraftBlock(net.minecraft.block.Block block) + { + return conversionRegistry.get(block); + } + + protected net.minecraft.block.Block block; + + public Block(net.minecraft.block.Block block) + { + this.block = block; + } + + /*returns the equivant minecraft block*/ + public net.minecraft.block.Block convert() + { + return this.block; + } +} diff --git a/src/com/sijobe/spc/wrapper/Blocks.java b/src/com/sijobe/spc/wrapper/Blocks.java new file mode 100644 index 0000000..ccb5af7 --- /dev/null +++ b/src/com/sijobe/spc/wrapper/Blocks.java @@ -0,0 +1,15 @@ +package com.sijobe.spc.wrapper; + +public class Blocks +{ + public static Block air; + public static Block fire; + public static Block glass; + + static void init() + { + air = (Block) Block.blockRegistry.getObject("minecraft:air"); + fire = (Block) Block.blockRegistry.getObject("minecraft:fire"); + glass = (Block) Block.blockRegistry.getObject("minecraft:glass"); + } +} diff --git a/src/com/sijobe/spc/wrapper/CommandBase.java b/src/com/sijobe/spc/wrapper/CommandBase.java index da0dcf7..c16f8ba 100644 --- a/src/com/sijobe/spc/wrapper/CommandBase.java +++ b/src/com/sijobe/spc/wrapper/CommandBase.java @@ -15,9 +15,9 @@ import java.util.List; import java.util.Map; -import net.minecraft.src.ChatMessageComponent; -import net.minecraft.src.EntityPlayerMP; -import net.minecraft.src.ICommandSender; +import net.minecraft.util.ChatComponentText; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.command.ICommandSender; /** * Provides a base class for all custom commands to extend. All non-abstract @@ -29,7 +29,7 @@ * @author simo_415 * @version 1.3 */ -public abstract class CommandBase extends net.minecraft.src.CommandBase { +public abstract class CommandBase extends net.minecraft.command.CommandBase { /** * A map containing all settings managers that have been loaded for worlds @@ -104,7 +104,7 @@ public void processCommand(final ICommandSender sender, String[] args) { if(sender.getCommandSenderName().equals("@")) { if(args.length >= 1) { if(getName().equals("sudo")) { - args[0] = func_82359_c(sender, args[0]).getCommandSenderName(); + args[0] = getPlayer(sender, args[0]).getCommandSenderName(); } else { String cmd = getCommandName(); for(String part : args) { @@ -114,8 +114,8 @@ public void processCommand(final ICommandSender sender, String[] args) { System.out.println("SPC/CommandBlock: " + cmd); EntityPlayerMP player; try { - player = func_82359_c(sender, args[0]); - } catch (net.minecraft.src.PlayerNotFoundException pnfe) { + player = getPlayer(sender, args[0]); + } catch (net.minecraft.command.PlayerNotFoundException pnfe) { System.out.println("SPC/CommandBlock: Warning - " + getCommandName() + " is a player command."); throw pnfe; } @@ -150,7 +150,7 @@ public void processCommand(final ICommandSender sender, String[] args) { } private void sendChatMessage(ICommandSender sender, String message) { - sender.sendChatToPlayer(ChatMessageComponent.func_111066_d(message)); + sender.addChatMessage(new ChatComponentText(message)); } /** diff --git a/src/com/sijobe/spc/wrapper/CommandManager.java b/src/com/sijobe/spc/wrapper/CommandManager.java index 913fdde..0d0a61b 100644 --- a/src/com/sijobe/spc/wrapper/CommandManager.java +++ b/src/com/sijobe/spc/wrapper/CommandManager.java @@ -4,8 +4,8 @@ import java.util.List; import java.util.Map; -import net.minecraft.src.ICommand; -import net.minecraft.src.ServerCommandManager; +import net.minecraft.command.ICommand; +import net.minecraft.command.ServerCommandManager; /** * Provides methods to allow easy access to the server command manager and its diff --git a/src/com/sijobe/spc/wrapper/CommandSender.java b/src/com/sijobe/spc/wrapper/CommandSender.java index 97e142a..1baa9a0 100644 --- a/src/com/sijobe/spc/wrapper/CommandSender.java +++ b/src/com/sijobe/spc/wrapper/CommandSender.java @@ -1,9 +1,9 @@ package com.sijobe.spc.wrapper; -import net.minecraft.src.ChatMessageComponent; -import net.minecraft.src.EntityPlayer; -import net.minecraft.src.ICommandSender; -import net.minecraft.src.StatCollector; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.StatCollector; /** * Provides a wrapper around the ICommandSender interface @@ -57,7 +57,7 @@ public boolean canUseCommand(String command) { * @param message - The message to display */ public void sendMessageToPlayer(String message) { - sender.sendChatToPlayer(ChatMessageComponent.func_111066_d(message)); + sender.addChatMessage(new ChatComponentText(message)); } /** diff --git a/src/com/sijobe/spc/wrapper/Entity.java b/src/com/sijobe/spc/wrapper/Entity.java index 96be054..afdd2c3 100644 --- a/src/com/sijobe/spc/wrapper/Entity.java +++ b/src/com/sijobe/spc/wrapper/Entity.java @@ -5,11 +5,11 @@ import java.util.List; import java.util.Map; -import net.minecraft.src.DamageSource; -import net.minecraft.src.EntityList; -import net.minecraft.src.EntityLiving; -import net.minecraft.src.EntityLivingData; -import net.minecraft.src.EntityPlayer; +import net.minecraft.util.DamageSource; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.player.EntityPlayer; /** * Contains methods that manage entities within the game @@ -136,10 +136,10 @@ public static boolean spawnEntity(String entity, Coordinate location, World worl Class entityClass = getEntityClass(entity); try { if (entityClass != null) { - net.minecraft.src.Entity entityInstance = (net.minecraft.src.Entity)entityClass.getConstructor(net.minecraft.src.World.class).newInstance(world.getMinecraftWorld()); + net.minecraft.entity.Entity entityInstance = (net.minecraft.entity.Entity)entityClass.getConstructor(net.minecraft.world.World.class).newInstance(world.getMinecraftWorld()); entityInstance.setPosition(location.getX(), location.getY() + 1, location.getZ()); if(entityInstance instanceof EntityLiving) { - ((EntityLiving)entityInstance).func_110161_a((EntityLivingData)null); + ((EntityLiving)entityInstance).onSpawnWithEgg((IEntityLivingData)null); //func_110161_a in 1.6.2, I don't know if I changed it to the right method } world.getMinecraftWorld().spawnEntityInWorld(entityInstance); if(entityInstance instanceof EntityLiving) { @@ -153,15 +153,15 @@ public static boolean spawnEntity(String entity, Coordinate location, World worl return false; } - public static List killEntities(String entity, Coordinate location, World world, double distance) { - List removedEntities = new ArrayList(); + public static List killEntities(String entity, Coordinate location, World world, double distance) { + List removedEntities = new ArrayList(); Class entityClass = getEntityClass(entity); int count = 0; try { if (entityClass != null) { - List toremove = new ArrayList(); - List entities = getLoadedEntities(world); - for (net.minecraft.src.Entity loaded : entities) { + List toremove = new ArrayList(); + List entities = getLoadedEntities(world); + for (net.minecraft.entity.Entity loaded : entities) { if(!(entityClass.isInstance(loaded))) { continue; } @@ -169,7 +169,7 @@ public static List killEntities(String entity, Coordin toremove.add(loaded); } } - for (net.minecraft.src.Entity remove : toremove) { + for (net.minecraft.entity.Entity remove : toremove) { if(remove instanceof EntityPlayer) { continue; } @@ -189,15 +189,15 @@ public static List killEntities(String entity, Coordin return removedEntities; } - public static List findEntities(String entity, Coordinate location, World world, double distance) { - List foundEntities = new ArrayList(); + public static List findEntities(String entity, Coordinate location, World world, double distance) { + List foundEntities = new ArrayList(); Class entityClass = getEntityClass(entity); int count = 0; try { if (entityClass != null) { - List found = new ArrayList(); - List entities = getLoadedEntities(world); - for (net.minecraft.src.Entity loaded : entities) { + List found = new ArrayList(); + List entities = getLoadedEntities(world); + for (net.minecraft.entity.Entity loaded : entities) { if(!(entityClass.isInstance(loaded))) { continue; } @@ -205,7 +205,7 @@ public static List findEntities(String entity, Coordin found.add(loaded); } } - for (net.minecraft.src.Entity foundEntity : found) { + for (net.minecraft.entity.Entity foundEntity : found) { // we don't currently exclude any entities foundEntities.add(foundEntity); count++; @@ -223,7 +223,7 @@ public static List findEntities(String entity, Coordin * @param world - The world to get the loaded entities from * @return A List of loaded entities */ - private static List getLoadedEntities(World world) { + private static List getLoadedEntities(World world) { return world.getMinecraftWorld().loadedEntityList; } } diff --git a/src/com/sijobe/spc/wrapper/Item.java b/src/com/sijobe/spc/wrapper/Item.java index b1139cf..6c6d27b 100644 --- a/src/com/sijobe/spc/wrapper/Item.java +++ b/src/com/sijobe/spc/wrapper/Item.java @@ -2,29 +2,48 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; -import net.minecraft.src.Enchantment; -import net.minecraft.src.ItemStack; -import net.minecraft.src.StatCollector; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.item.ItemStack; +import net.minecraft.util.RegistryNamespaced; +import net.minecraft.util.StatCollector; public class Item { /** * A list of item names that are loaded in the game */ - private static final List ITEM_NAMES; - static { - ITEM_NAMES = new ArrayList(); - for (net.minecraft.src.Item item : net.minecraft.src.Item.itemsList) { - if (item != null) { - ITEM_NAMES.add(StatCollector.translateToLocal(item.getUnlocalizedName())); - } else { - ITEM_NAMES.add(null); - } - } + public static final RegistryNamespaced itemRegistry = new RegistryNamespaced(); + public static final Map conversionRegistry = new HashMap(); + public static final RegistryNamespaced realItemRegistry = net.minecraft.item.Item.itemRegistry; + + public static void init() + { + for (Object i : net.minecraft.item.Item.itemRegistry) + { + net.minecraft.item.Item item = (net.minecraft.item.Item) i; + Item wrapped = new Item(item); + itemRegistry.putObject(realItemRegistry.getNameForObject(item), wrapped); + conversionRegistry.put(item, wrapped); + } + } + + protected net.minecraft.item.Item item; + + public Item(net.minecraft.item.Item item) + { + this.item = item; } - + + /*convert a wrapped item into a minecraft item*/ + public net.minecraft.item.Item convert() + { + return this.item; + } + /** * Translates the item code name into the item display name * @@ -35,14 +54,27 @@ public class Item { return StringTranslate.getInstance().translateNamedKey(toTranslate).toString().trim(); }*/ - /** +/** * Gets the item id of the specified item denoted by the string name * * @param itemName - The name of the item - * @return the id of the item. If the item doesn't exist -1 is returned + * @return the id of the item. If the item doesn't exist null is returned */ - public static int getItemId(String itemName) { - return ITEM_NAMES.indexOf(itemName.toLowerCase()); + public static Item getItem(String itemName) { + if(itemRegistry.containsKey(itemName)) + { + return (Item) itemRegistry.getObject(itemName); + } + else + { + return null; + } + } + + /*returns the converts the item to a minecraft item*/ + public static Item getItem(net.minecraft.item.Item item) + { + return conversionRegistry.get(item); } /** @@ -51,24 +83,18 @@ public static int getItemId(String itemName) { * @param id - The id of the item to check * @return true is returned if the id is valid, false otherwise */ - public static boolean isValidItem(int id) { - if (id < 0 || id > ITEM_NAMES.size()) { - return false; - } - return ITEM_NAMES.get(id) != null; + public static boolean isValidItem(Item item) { + return itemRegistry.containsKey(item); } - /** + /**TODO: remove arguement * Gets the maximum stack size of the specified item * - * @param id - The id of the item + * @param id - does nothing * @return The stack size of the item, or 0 if not valid */ - public static int getMaxStack(int id) { - if (isValidItem(id)) { - return net.minecraft.src.Item.itemsList[id].getItemStackLimit(); - } - return 0; + public int getMaxStack(Item id) { + return this.item.getItemStackLimit(); } /** diff --git a/src/com/sijobe/spc/wrapper/Minecraft.java b/src/com/sijobe/spc/wrapper/Minecraft.java index b969814..0a8944a 100644 --- a/src/com/sijobe/spc/wrapper/Minecraft.java +++ b/src/com/sijobe/spc/wrapper/Minecraft.java @@ -24,8 +24,8 @@ public static File getMinecraftDirectory() { * * @return The Minecraft instance */ - public static net.minecraft.src.Minecraft getMinecraft() { - return net.minecraft.src.Minecraft.getMinecraft(); + public static net.minecraft.client.Minecraft getMinecraft() { + return net.minecraft.client.Minecraft.getMinecraft(); } /** diff --git a/src/com/sijobe/spc/wrapper/MinecraftServer.java b/src/com/sijobe/spc/wrapper/MinecraftServer.java index e3794c1..02cd6de 100644 --- a/src/com/sijobe/spc/wrapper/MinecraftServer.java +++ b/src/com/sijobe/spc/wrapper/MinecraftServer.java @@ -80,7 +80,7 @@ public static Player getPlayerByUsername(String username) { * @see CommandManager#runCommand(CommandSender, String) */ public static String runCommand(String command) { - return getMinecraftServer().executeCommand(command); + return getMinecraftServer().handleRConCommand(command); } /** diff --git a/src/com/sijobe/spc/wrapper/Player.java b/src/com/sijobe/spc/wrapper/Player.java index 488a2ef..3d26b9b 100644 --- a/src/com/sijobe/spc/wrapper/Player.java +++ b/src/com/sijobe/spc/wrapper/Player.java @@ -1,13 +1,16 @@ package com.sijobe.spc.wrapper; -import net.minecraft.src.EntityClientPlayerMP; -import net.minecraft.src.EntityPlayer; -import net.minecraft.src.EntityPlayerMP; -import net.minecraft.src.EnumGameType; -import net.minecraft.src.ItemStack; -import net.minecraft.src.MovingObjectPosition; -import net.minecraft.src.PotionEffect; -import net.minecraft.src.Vec3; +import net.minecraft.client.entity.EntityClientPlayerMP; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.world.WorldSettings.GameType; + + +import net.minecraft.item.ItemStack; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.Vec3; /** * Provides a wrapper around the Minecraft player classes. @@ -103,7 +106,7 @@ public World getWorld() { * @param message - The message to send to the user */ public void sendChatMessage(String message) { - player.addChatMessage(message); + player.addChatMessage(new ChatComponentText(message)); } /** @@ -111,8 +114,8 @@ public void sendChatMessage(String message) { * * @param id - The item id */ - public void givePlayerItem(int id) { - givePlayerItem(id, Item.getMaxStack(id)); + public void givePlayerItem(Item item) { + givePlayerItem(item, item.getMaxStack(item)); } /** @@ -121,7 +124,7 @@ public void givePlayerItem(int id) { * @param id - The item id * @param quantity - The quantity of the item */ - public void givePlayerItem(int id, int quantity) { + public void givePlayerItem(Item id, int quantity) { givePlayerItem(id, quantity, 0); } @@ -132,12 +135,21 @@ public void givePlayerItem(int id, int quantity) { * @param quantity - The quantity of the item * @param damage - The "damage" (metadata) value of the item */ - public void givePlayerItem(int id, int quantity, int damage) { - ItemStack itemStack = new ItemStack(id, quantity, damage); + public void givePlayerItem(Item item, int quantity, int damage) { + ItemStack itemStack = new ItemStack(item.convert(), quantity, damage); if (!player.inventory.addItemStackToInventory(itemStack)) { - player.dropPlayerItem(itemStack); + player.dropPlayerItemWithRandomChoice(itemStack, false); } } + + /*in 1.6.2 givePlayerItem(Item) + * gives the player the item but the player will drop something their inventory is full*/ + public void givePlayerItemWithDrop(Item item) { + ItemStack itemStack = new ItemStack(item.convert()); + if (!player.inventory.addItemStackToInventory(itemStack)) { + player.dropPlayerItemWithRandomChoice(itemStack, false); + } + } /** * Gets the players current health @@ -145,7 +157,7 @@ public void givePlayerItem(int id, int quantity, int damage) { * @return The value of the players health */ public float getHealth() { - return player.func_110143_aJ(); + return player.getHealth(); } /** @@ -154,7 +166,7 @@ public float getHealth() { * @param health - The health amount */ public void setHealth(float health) { - player.setEntityHealth(health); + player.setHealth(health); } /** @@ -212,17 +224,17 @@ public void setDamage(boolean damage) { * @param damage - The item "damage" value * @return True if the slot was correctly set, false otherwise */ - public boolean setInventorySlot(int slot, int id, int quantity, int damage) { + public boolean setInventorySlot(int slot, Item item, int quantity, int damage) { if (slot < 0 || slot >= player.inventory.mainInventory.length) { return false; - } else if (!Item.isValidItem(id)) { - if (id == 0) { + } else if (!Item.isValidItem(item)) { + if (item == null) { player.inventory.mainInventory[slot] = null; return true; } return false; } - player.inventory.mainInventory[slot] = new ItemStack(id, quantity, damage); + player.inventory.mainInventory[slot] = new ItemStack(item.convert(), quantity, damage); return true; } @@ -244,10 +256,11 @@ public Coordinate trace(double distance) { } public MovingObjectPosition rayTrace(double distance, float partialTickTime) { + //was this rayTrace supposed to include liquids or not? //probably not liquids Vec3 positionVec = getPositionVec(partialTickTime); Vec3 lookVec = player.getLook(partialTickTime); Vec3 hitVec = positionVec.addVector(lookVec.xCoord * distance, lookVec.yCoord * distance, lookVec.zCoord * distance); - return player.worldObj.rayTraceBlocks_do_do(positionVec, hitVec, false, true); // TODO: Validate correct params + return player.worldObj.rayTraceBlocks(positionVec, hitVec, false); // TODO: Validate correct params } /** @@ -275,8 +288,8 @@ public Vec3 getPositionVec(float partialTickTime) { * @return True if the specified gametype was found */ public boolean setGameType(String gametype) { - EnumGameType chosen = null; - if ((chosen = EnumGameType.getByName(gametype)) == null) { + GameType chosen = null; + if ((chosen = GameType.getByName(gametype)) == null) { return false; } player.setGameType(chosen); @@ -289,7 +302,7 @@ public boolean setGameType(String gametype) { * @return The players name */ public String getPlayerName() { - return player.getEntityName(); + return player.getCommandSenderName(); } /** @@ -297,11 +310,11 @@ public String getPlayerName() { * * @return The ID of the currently held item */ - public int getCurrentItem() { + public Item getCurrentItem() { try { - return player.inventory.mainInventory[getCurrentSlot()].itemID; + return new Item(player.inventory.mainInventory[getCurrentSlot()].getItem()); } catch (NullPointerException e) { - return 0; + return null; } } @@ -355,9 +368,9 @@ public Coordinate getMotion() { * @return True if the player can stand in the specified location */ public boolean isClear(Coordinate location) { - return getWorld().getBlockId(location.getBlockX(), location.getBlockY(), location.getBlockZ()) == 0 - && getWorld().getBlockId(location.getBlockX(), location.getBlockY() + 1, location.getBlockZ()) == 0 - && !(getWorld().getBlockId(location.getBlockX(), location.getBlockY() - 1, location.getBlockZ()) == 0); + return getWorld().getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ()) == Blocks.air + && getWorld().getBlock(location.getBlockX(), location.getBlockY() + 1, location.getBlockZ()) == Blocks.air + && !(getWorld().getBlock(location.getBlockX(), location.getBlockY() - 1, location.getBlockZ()) == Blocks.air); } /** @@ -372,9 +385,9 @@ && getWorld().getBlockId(location.getBlockX(), location.getBlockY() + 1, locatio * @return True if the player can fall in the specified location */ public boolean isClearBelow(Coordinate location) { - return getWorld().getBlockId(location.getBlockX(), location.getBlockY(), location.getBlockZ()) == 0 - && getWorld().getBlockId(location.getBlockX(), location.getBlockY() + 1, location.getBlockZ()) == 0 - && getWorld().getBlockId(location.getBlockX(), location.getBlockY() - 1, location.getBlockZ()) == 0; + return getWorld().getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ()) == Blocks.air + && getWorld().getBlock(location.getBlockX(), location.getBlockY() + 1, location.getBlockZ()) == Blocks.air + && getWorld().getBlock(location.getBlockX(), location.getBlockY() - 1, location.getBlockZ()) == Blocks.air; } /** @@ -386,9 +399,9 @@ && getWorld().getBlockId(location.getBlockX(), location.getBlockY() + 1, locatio */ public float getMovementForward() { if (player instanceof EntityPlayerMP) { - return ((EntityPlayerMP) player).getMoveForwardField(); + return ((EntityPlayerMP) player).moveForward; } else if (player instanceof EntityClientPlayerMP) { - return ((EntityClientPlayerMP) player).getMovementForward(); + return ((EntityClientPlayerMP) player).moveForward; } else { return 0F; } @@ -403,9 +416,9 @@ public float getMovementForward() { */ public float getMovementStrafe() { if (player instanceof EntityPlayerMP) { - return ((EntityPlayerMP) player).getMoveStrafingField(); + return ((EntityPlayerMP) player).moveStrafing; } else if (player instanceof EntityClientPlayerMP) { - return ((EntityClientPlayerMP) player).getMovementStrafe(); + return ((EntityClientPlayerMP) player).moveStrafing; } else { return 0F; } @@ -537,9 +550,9 @@ public boolean isCreativeMode() { */ public String getUsername() { if (player instanceof EntityClientPlayerMP) { - return ((EntityClientPlayerMP) player).getUsername(); + return ((EntityClientPlayerMP) player).getCommandSenderName(); } else if (player instanceof EntityPlayerMP) { - ((EntityPlayerMP) player).getUsername(); + ((EntityPlayerMP) player).getCommandSenderName(); } return ""; } diff --git a/src/com/sijobe/spc/wrapper/Potion.java b/src/com/sijobe/spc/wrapper/Potion.java index cf8c962..1b0e55f 100644 --- a/src/com/sijobe/spc/wrapper/Potion.java +++ b/src/com/sijobe/spc/wrapper/Potion.java @@ -14,9 +14,9 @@ public class Potion { */ private static Map retrievePotions() { Map potions = new HashMap(); - for (int i = 0; i < net.minecraft.src.Potion.potionTypes.length; i++) { - if (net.minecraft.src.Potion.potionTypes[i] != null) { - potions.put(net.minecraft.src.StatCollector.translateToLocal(net.minecraft.src.Potion.potionTypes[i].getName()).replace(' ', '_').toLowerCase(), i); + for (int i = 0; i < net.minecraft.potion.Potion.potionTypes.length; i++) { + if (net.minecraft.potion.Potion.potionTypes[i] != null) { + potions.put(net.minecraft.util.StatCollector.translateToLocal(net.minecraft.potion.Potion.potionTypes[i].getName()).replace(' ', '_').toLowerCase(), i); } } return potions; diff --git a/src/com/sijobe/spc/wrapper/Stats.java b/src/com/sijobe/spc/wrapper/Stats.java index daca12d..136c151 100644 --- a/src/com/sijobe/spc/wrapper/Stats.java +++ b/src/com/sijobe/spc/wrapper/Stats.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Map; -import net.minecraft.src.Achievement; -import net.minecraft.src.AchievementList; +import net.minecraft.stats.Achievement; +import net.minecraft.stats.AchievementList; /** * Contains methods that interact with the Minecraft statistics engine diff --git a/src/com/sijobe/spc/wrapper/World.java b/src/com/sijobe/spc/wrapper/World.java index c8bec2c..57b34be 100644 --- a/src/com/sijobe/spc/wrapper/World.java +++ b/src/com/sijobe/spc/wrapper/World.java @@ -3,16 +3,17 @@ import java.lang.reflect.Field; import java.util.Random; -import net.minecraft.src.Block; -import net.minecraft.src.EntityLightningBolt; -import net.minecraft.src.IInventory; -import net.minecraft.src.NBTTagCompound; -import net.minecraft.src.WorldGenBigTree; -import net.minecraft.src.WorldGenForest; -import net.minecraft.src.WorldGenTaiga1; -import net.minecraft.src.WorldGenTaiga2; -import net.minecraft.src.WorldGenTrees; -import net.minecraft.src.WorldInfo; + +import net.minecraft.entity.effect.EntityLightningBolt; +import net.minecraft.inventory.IInventory; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.world.gen.feature.WorldGenBigTree; +import net.minecraft.world.gen.feature.WorldGenForest; +import net.minecraft.world.gen.feature.WorldGenTaiga1; +import net.minecraft.world.gen.feature.WorldGenTaiga2; +import net.minecraft.world.gen.feature.WorldGenTrees; +import net.minecraft.world.storage.WorldInfo; /** * Provides methods that interact with the Minecraft world @@ -24,7 +25,7 @@ public class World { /** * The world instance this class wraps around */ - private final net.minecraft.src.World world; + private final net.minecraft.world.World world; /** * A random instance provides random numbers for methods */ @@ -35,7 +36,7 @@ public class World { * * @param world - The world instance to wrap around */ - public World(net.minecraft.src.World world) { + public World(net.minecraft.world.World world) { this.world = world; random = new Random(); } @@ -46,10 +47,10 @@ public World(net.minecraft.src.World world) { * @param x - The X coordinate of the block to get * @param y - The Y coordinate of the block to get * @param z - The Z coordinate of the block to get - * @return The ID of the block + * @return the block at (x, y, z) */ - public int getBlockId(int x, int y, int z) { - return world.getBlockId(x, y, z); + public Block getBlock(int x, int y, int z) { + return Block.fromMinecraftBlock(this.getMinecraftWorld().getBlock(x, y, z)); } /** @@ -58,8 +59,8 @@ public int getBlockId(int x, int y, int z) { * @param coord - The coordinate of the block to get * @return The ID of the block */ - public int getBlockId(Coordinate coord) { - return world.getBlockId(coord.getBlockX(), coord.getBlockY(), coord.getBlockZ()); + public Block getBlock(Coordinate coord) { + return this.getBlock(coord.getBlockX(), coord.getBlockY(), coord.getBlockZ()); } /** @@ -127,7 +128,7 @@ private void changeWorldInfo(String key, Object value) { } WorldInfo info = new WorldInfo(nbt); try { - Field fields[] = net.minecraft.src.World.class.getDeclaredFields(); + Field fields[] = net.minecraft.world.World.class.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); if (field.get(this.world) instanceof WorldInfo) { @@ -145,7 +146,7 @@ private void changeWorldInfo(String key, Object value) { * * @return The difficulty of the world */ - public int getDifficulty() { + public EnumDifficulty getDifficulty() { return world.difficultySetting; } @@ -154,7 +155,7 @@ public int getDifficulty() { * * @param difficulty - The difficulty of the world */ - public void setDifficulty(int difficulty) { + public void setDifficulty(EnumDifficulty difficulty) { world.difficultySetting = difficulty; } @@ -165,8 +166,8 @@ public void setDifficulty(int difficulty) { * @param type - The BlockID to change the specified location to * @return True if the data was set correctly */ - public boolean setBlock(Coordinate coord, int type) { - return world.setBlock(coord.getBlockX(), coord.getBlockY(), coord.getBlockZ(), type, 0, 2); + public boolean setBlock(Coordinate coord, Block type) { + return world.setBlock(coord.getBlockX(), coord.getBlockY(), coord.getBlockZ(), type.convert(), 0, 2); } /** @@ -188,8 +189,8 @@ public boolean setBlockData(Coordinate coord, int type) { * @param meta - The metadata to set on the block * @return True if the data was set correctly */ - public boolean setBlockDataWithMeta(Coordinate coord, int type, int meta) { - return world.setBlock(coord.getBlockX(), coord.getBlockY(), coord.getBlockZ(), type, meta, 2); + public boolean setBlockDataWithMeta(Coordinate coord, Block type, int meta) { + return world.setBlock(coord.getBlockX(), coord.getBlockY(), coord.getBlockZ(), type.convert(), meta, 2); // 2 = setblock, 3 = notify } @@ -287,7 +288,7 @@ public int getBlockLightLevel(Coordinate coordinate) { */ public boolean emptyContainer(Coordinate coordinate) { try { - IInventory i = (IInventory)world.getBlockTileEntity(coordinate.getBlockX(), coordinate.getBlockY(), coordinate.getBlockZ()); + IInventory i = (IInventory)world.getTileEntity(coordinate.getBlockX(), coordinate.getBlockY(), coordinate.getBlockZ()); for (int j = 0; j < i.getSizeInventory(); j++) { i.setInventorySlotContents(j, null); } @@ -345,7 +346,8 @@ public boolean generateTree(Coordinate coordinate) { * @return True if the generation was successful, false otherwise */ public boolean generateBirchTree(Coordinate coordinate) { - return (new WorldGenForest(true)).generate(world, random, coordinate.getBlockX(), coordinate.getBlockY(), coordinate.getBlockZ()); + //second arg for WorldGenForest constructor might need to be true + return (new WorldGenForest(true, false)).generate(world, random, coordinate.getBlockX(), coordinate.getBlockY(), coordinate.getBlockZ()); } /** @@ -389,11 +391,8 @@ public void createExplosion(Player player, Coordinate coordinate, int size) { * @param type - The type of block * @return True if it is a valid block type */ - public boolean isValidBlockType(int type) { - if (type < 0 || type >= Block.blocksList.length) { - return false; - } - return Block.blocksList[type] != null; + public boolean isValidBlockType(Block type) { + return Block.blockRegistry.containsKey(type); } /** @@ -401,7 +400,7 @@ public boolean isValidBlockType(int type) { * * @return The Minecraft World object */ - public net.minecraft.src.World getMinecraftWorld() { + public net.minecraft.world.World getMinecraftWorld() { return world; } } From 049d695c77e18c6f45dfeabed35693b2a118fd42 Mon Sep 17 00:00:00 2001 From: aucguy Date: Tue, 11 Nov 2014 21:53:24 -0600 Subject: [PATCH 02/20] Fixed BlockReach, cheats, difficulty and give commands --- src/com/sijobe/spc/ModSpc.java | 2 +- .../sijobe/spc/asm/CustomClassVisitor.java | 33 ++++++++ src/com/sijobe/spc/asm/MethodOverwriter.java | 77 +++++++++++++++++++ src/com/sijobe/spc/asm/Replacer.java | 13 ++++ src/com/sijobe/spc/asm/SpcCoreMod.java | 39 ++++++++++ src/com/sijobe/spc/asm/Transformer.java | 40 ++++++++++ src/com/sijobe/spc/asm/make/Make.java | 9 +++ src/com/sijobe/spc/command/BlockReach.java | 9 ++- src/com/sijobe/spc/command/Cheats.java | 8 +- src/com/sijobe/spc/command/Difficulty.java | 14 +--- src/com/sijobe/spc/command/Enchant.java | 2 +- src/com/sijobe/spc/command/Explode.java | 2 +- src/com/sijobe/spc/command/Give.java | 2 +- src/com/sijobe/spc/command/Hardcore.java | 1 + src/com/sijobe/spc/command/InstantMine.java | 6 -- .../sijobe/spc/command/StandardCommand.java | 4 - src/com/sijobe/spc/wrapper/Item.java | 2 +- src/com/sijobe/spc/wrapper/World.java | 7 +- 18 files changed, 237 insertions(+), 33 deletions(-) create mode 100644 src/com/sijobe/spc/asm/CustomClassVisitor.java create mode 100644 src/com/sijobe/spc/asm/MethodOverwriter.java create mode 100644 src/com/sijobe/spc/asm/Replacer.java create mode 100644 src/com/sijobe/spc/asm/SpcCoreMod.java create mode 100644 src/com/sijobe/spc/asm/Transformer.java create mode 100644 src/com/sijobe/spc/asm/make/Make.java diff --git a/src/com/sijobe/spc/ModSpc.java b/src/com/sijobe/spc/ModSpc.java index 29cb9e1..f35e9cd 100644 --- a/src/com/sijobe/spc/ModSpc.java +++ b/src/com/sijobe/spc/ModSpc.java @@ -29,7 +29,7 @@ import com.sijobe.spc.core.ICUIEventHandler; import com.sijobe.spc.hooks.InitialiseCommands; -@Mod(useMetadata=true, modid="spc", version="2.0") +@Mod(useMetadata=true, modid="spc", version="5.0") public class ModSpc { protected HookManager hookManager; diff --git a/src/com/sijobe/spc/asm/CustomClassVisitor.java b/src/com/sijobe/spc/asm/CustomClassVisitor.java new file mode 100644 index 0000000..b4d73d1 --- /dev/null +++ b/src/com/sijobe/spc/asm/CustomClassVisitor.java @@ -0,0 +1,33 @@ +package com.sijobe.spc.asm; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Opcodes; + +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; + +public class CustomClassVisitor extends ClassVisitor +{ + String clazz; + + public CustomClassVisitor(String clazz, ClassWriter writer) + { + super(Opcodes.ASM4, writer); + this.clazz = clazz; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) + { + MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); + String id = this.clazz+":"+name+":"+desc; + if(MethodOverwriter.replacers.containsKey(id)) + { + return (MethodVisitor) new MethodOverwriter(mv, id); + } + else + { + return mv; + } + } +} diff --git a/src/com/sijobe/spc/asm/MethodOverwriter.java b/src/com/sijobe/spc/asm/MethodOverwriter.java new file mode 100644 index 0000000..c1ef149 --- /dev/null +++ b/src/com/sijobe/spc/asm/MethodOverwriter.java @@ -0,0 +1,77 @@ +package com.sijobe.spc.asm; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +public class MethodOverwriter extends MethodVisitor +{ + static Set clazzes; + static Map replacers; + + static void init() + { + clazzes = new HashSet(); + replacers = new HashMap(); + for(Method method : MethodOverwriter.class.getDeclaredMethods()) + { + if(method.isAnnotationPresent(Replacer.class)) + { + String annotation = method.getAnnotation(Replacer.class).value(); + System.out.println("found replacement for "+annotation); + String clazz = annotation.split(":", 2)[0]; + if(!clazzes.contains(clazz)) + { + clazzes.add(clazz); + } + replacers.put(annotation, method); + } + } + } + + MethodVisitor writer; + String id; + + public MethodOverwriter(MethodVisitor writer, String id) + { + super(Opcodes.ASM4); + this.writer = writer; + this.id = id; + } + + @Override + public void visitCode() + { + try { + replacers.get(this.id).invoke(this); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Replacer("net.minecraft.client.multiplayer.PlayerControllerMP:getBlockReachDistance:()F") + protected void getBlockReachDistance() + { + MethodVisitor mv = this.writer; + mv.visitCode(); + mv.visitFieldInsn(Opcodes.GETSTATIC, "com/sijobe/spc/command/BlockReach", "reachDistance", "F"); + mv.visitInsn(Opcodes.FRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } +} diff --git a/src/com/sijobe/spc/asm/Replacer.java b/src/com/sijobe/spc/asm/Replacer.java new file mode 100644 index 0000000..33a4d6c --- /dev/null +++ b/src/com/sijobe/spc/asm/Replacer.java @@ -0,0 +1,13 @@ +package com.sijobe.spc.asm; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@interface Replacer +{ + String value(); +} diff --git a/src/com/sijobe/spc/asm/SpcCoreMod.java b/src/com/sijobe/spc/asm/SpcCoreMod.java new file mode 100644 index 0000000..d2452fa --- /dev/null +++ b/src/com/sijobe/spc/asm/SpcCoreMod.java @@ -0,0 +1,39 @@ +package com.sijobe.spc.asm; + +import java.util.Map; + +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion; + +@MCVersion("1.7.2") +public class SpcCoreMod implements IFMLLoadingPlugin +{ + @Override + public String[] getASMTransformerClass() + { + return new String[]{Transformer.class.getName()}; + } + + @Override + public String getModContainerClass() + { + return null; + } + + @Override + public String getSetupClass() + { + return null; + } + + @Override + public void injectData(Map data) + { + } + + @Override + public String getAccessTransformerClass() + { + return null; + } +} diff --git a/src/com/sijobe/spc/asm/Transformer.java b/src/com/sijobe/spc/asm/Transformer.java new file mode 100644 index 0000000..5b53c09 --- /dev/null +++ b/src/com/sijobe/spc/asm/Transformer.java @@ -0,0 +1,40 @@ +package com.sijobe.spc.asm; + +import org.objectweb.asm.ClassVisitor; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; + +import net.minecraft.launchwrapper.IClassTransformer; + +public class Transformer implements IClassTransformer +{ + public Transformer() + { + MethodOverwriter.init(); + } + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) + { + if(MethodOverwriter.clazzes.contains(name)) //TODO do obfucated names + { + System.out.println("modifiying "+name); + return this.applyPatch(name, basicClass); + } + else + { + return basicClass; + } + } + + protected byte[] applyPatch(String name, byte[] orginal) + { + ClassWriter writer = new ClassWriter(Opcodes.ASM4); + ClassVisitor visitor = new CustomClassVisitor(name, writer); + ClassReader reader = new ClassReader(orginal); + reader.accept(visitor, 0); + return writer.toByteArray(); + } +} diff --git a/src/com/sijobe/spc/asm/make/Make.java b/src/com/sijobe/spc/asm/make/Make.java new file mode 100644 index 0000000..5508eec --- /dev/null +++ b/src/com/sijobe/spc/asm/make/Make.java @@ -0,0 +1,9 @@ +package com.sijobe.spc.asm.make; + +public class Make +{ + public float getBlockReachDistance() + { + return com.sijobe.spc.command.BlockReach.reachDistance; + } +} diff --git a/src/com/sijobe/spc/command/BlockReach.java b/src/com/sijobe/spc/command/BlockReach.java index 7807a90..7759ee2 100644 --- a/src/com/sijobe/spc/command/BlockReach.java +++ b/src/com/sijobe/spc/command/BlockReach.java @@ -14,10 +14,11 @@ /** * Changes block reach distance + * TODO make this work in multiplayer (refers to PlayerControllerMP) * * @author q3hardcore * @version 1.0 - * @status broken through 1.7.2 update + * @status broken through 1.7.2 update -> fixed */ @Command ( name = "blockreach", @@ -35,6 +36,8 @@ public class BlockReach extends StandardCommand { } ); + public static float reachDistance = 4.5F; //refered to through ASM modifications + /** * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) */ @@ -53,8 +56,10 @@ public void execute(CommandSender sender, List params) throws CommandExceptio if(newReach < 4.5D || newReach > 255.0D) { throw new CommandException("Reach distance must be between 4.5 and 255."); } - ForgeHelper.setBlockReachDistance(playerEntity.theItemInWorldManager, newReach); + //ForgeHelper.setBlockReachDistance(playerEntity.theItemInWorldManager, newReach); //Minecraft.getMinecraft().thePlayer.setClientReach(newReach); //removed since spc 1.7.2 update now needs forge anyway + playerEntity.theItemInWorldManager.setBlockReachDistance(newReach); + reachDistance = (float) newReach; sender.sendMessageToPlayer("Set block reach distance to: " + newReach); } } diff --git a/src/com/sijobe/spc/command/Cheats.java b/src/com/sijobe/spc/command/Cheats.java index f1eee97..fa2b6a8 100644 --- a/src/com/sijobe/spc/command/Cheats.java +++ b/src/com/sijobe/spc/command/Cheats.java @@ -14,7 +14,7 @@ * * @author q3hardcore * @version 1.0 - * @status broken through 1.7.2 update + * @status broken through 1.7.2 update -> fixed */ @Command ( name = "cheats", @@ -41,5 +41,9 @@ public void execute(CommandSender sender, List params) throws CommandExceptio public Parameters getParameters() { return Parameters.DEFAULT_BOOLEAN; } - + + @Override + public boolean hasPermission(CommandSender sender) { + return true; + } } \ No newline at end of file diff --git a/src/com/sijobe/spc/command/Difficulty.java b/src/com/sijobe/spc/command/Difficulty.java index f65920f..3bf02bb 100644 --- a/src/com/sijobe/spc/command/Difficulty.java +++ b/src/com/sijobe/spc/command/Difficulty.java @@ -17,7 +17,7 @@ * * @author simo_415 * @version 1.0 - * @status broken through 1.7.2 update + * @status broken through 1.7.2 update -> fixed */ @Command ( name = "difficulty", @@ -45,17 +45,7 @@ public void execute(CommandSender sender, List params) throws CommandExceptio World world = super.getSenderAsPlayer(sender).getWorld(); int change; if (params.size() > 0) { - switch((Integer)params.get(0)) - { - case 0: - world.setDifficulty(EnumDifficulty.PEACEFUL); - case 1: - world.setDifficulty(EnumDifficulty.EASY); - case 2: - world.setDifficulty(EnumDifficulty.NORMAL); - case 3: - world.setDifficulty(EnumDifficulty.HARD); - } + world.setDifficulty(EnumDifficulty.getDifficultyEnum((Integer)params.get(0))); } else { world.setDifficulty(EnumDifficulty.getDifficultyEnum((world.getDifficulty().getDifficultyId() + 1) % 4)); } diff --git a/src/com/sijobe/spc/command/Enchant.java b/src/com/sijobe/spc/command/Enchant.java index da9e6f4..47b2bd2 100644 --- a/src/com/sijobe/spc/command/Enchant.java +++ b/src/com/sijobe/spc/command/Enchant.java @@ -17,7 +17,7 @@ * * @author simo_415 * @version 1.0 - * @survived 1.7.2 update + * @status survived 1.7.2 update */ @Command ( name = "enchant", diff --git a/src/com/sijobe/spc/command/Explode.java b/src/com/sijobe/spc/command/Explode.java index 7023a23..cecd7f5 100644 --- a/src/com/sijobe/spc/command/Explode.java +++ b/src/com/sijobe/spc/command/Explode.java @@ -16,7 +16,7 @@ * * @author simo_415 * @version 1.0 - * @survived 1.7.2 update + * @status survived 1.7.2 update */ @Command ( name = "explode", diff --git a/src/com/sijobe/spc/command/Give.java b/src/com/sijobe/spc/command/Give.java index 7208954..18e79b7 100644 --- a/src/com/sijobe/spc/command/Give.java +++ b/src/com/sijobe/spc/command/Give.java @@ -15,7 +15,7 @@ * * @author simo_415 * @version 1.0 - * @status broken through 1.7.2 update + * @status broken through 1.7.2 update -> fixed */ @Command ( name = "give", diff --git a/src/com/sijobe/spc/command/Hardcore.java b/src/com/sijobe/spc/command/Hardcore.java index adea8d9..514db1b 100644 --- a/src/com/sijobe/spc/command/Hardcore.java +++ b/src/com/sijobe/spc/command/Hardcore.java @@ -13,6 +13,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "hardcore", diff --git a/src/com/sijobe/spc/command/InstantMine.java b/src/com/sijobe/spc/command/InstantMine.java index 9570e73..16f4bc7 100644 --- a/src/com/sijobe/spc/command/InstantMine.java +++ b/src/com/sijobe/spc/command/InstantMine.java @@ -26,12 +26,6 @@ enabled = true ) public class InstantMine extends StandardCommand { - - @Override - public boolean isEnabled() { - return !ForgeHelper.HAS_FORGE; - } - @Override public void execute(CommandSender sender, List params) throws CommandException { Player player = super.getSenderAsPlayer(sender); diff --git a/src/com/sijobe/spc/command/StandardCommand.java b/src/com/sijobe/spc/command/StandardCommand.java index 3ab942e..f27229c 100644 --- a/src/com/sijobe/spc/command/StandardCommand.java +++ b/src/com/sijobe/spc/command/StandardCommand.java @@ -14,8 +14,4 @@ public abstract class StandardCommand extends CommandBase { /** * @see com.sijobe.spc.wrapper.CommandBase#hasPermission(com.sijobe.spc.wrapper.CommandSender) */ - @Override - public boolean hasPermission(CommandSender sender) { - return true; - } } diff --git a/src/com/sijobe/spc/wrapper/Item.java b/src/com/sijobe/spc/wrapper/Item.java index 6c6d27b..133d11a 100644 --- a/src/com/sijobe/spc/wrapper/Item.java +++ b/src/com/sijobe/spc/wrapper/Item.java @@ -84,7 +84,7 @@ public static Item getItem(net.minecraft.item.Item item) * @return true is returned if the id is valid, false otherwise */ public static boolean isValidItem(Item item) { - return itemRegistry.containsKey(item); + return itemRegistry.containsKey(itemRegistry.getNameForObject(item)); } /**TODO: remove arguement diff --git a/src/com/sijobe/spc/wrapper/World.java b/src/com/sijobe/spc/wrapper/World.java index 57b34be..96d49a2 100644 --- a/src/com/sijobe/spc/wrapper/World.java +++ b/src/com/sijobe/spc/wrapper/World.java @@ -4,6 +4,7 @@ import java.util.Random; +import net.minecraft.client.settings.GameSettings; import net.minecraft.entity.effect.EntityLightningBolt; import net.minecraft.inventory.IInventory; import net.minecraft.nbt.NBTTagCompound; @@ -147,7 +148,8 @@ private void changeWorldInfo(String key, Object value) { * @return The difficulty of the world */ public EnumDifficulty getDifficulty() { - return world.difficultySetting; + GameSettings settings = Minecraft.getMinecraft().gameSettings; + return settings.difficulty; } /** @@ -156,7 +158,8 @@ public EnumDifficulty getDifficulty() { * @param difficulty - The difficulty of the world */ public void setDifficulty(EnumDifficulty difficulty) { - world.difficultySetting = difficulty; + GameSettings settings = Minecraft.getMinecraft().gameSettings; + settings.setOptionValue(GameSettings.Options.DIFFICULTY, difficulty.getDifficultyId()-this.getDifficulty().getDifficultyId()); } /** From babc98bac60340cc9a8c8b29a7cd0994d03fdd28 Mon Sep 17 00:00:00 2001 From: aucguy Date: Thu, 13 Nov 2014 22:06:38 -0600 Subject: [PATCH 03/20] Fixed instantmine command --- src/com/sijobe/spc/ModSpc.java | 33 ++++++ src/com/sijobe/spc/asm/MethodOverwriter.java | 18 +++ .../sijobe/spc/asm/SpcAccessTransformer.java | 13 +++ src/com/sijobe/spc/asm/SpcCoreMod.java | 2 +- src/com/sijobe/spc/command/InstantMine.java | 103 ++++++++++++------ src/com/sijobe/spc/core/IBlockBroken.java | 9 ++ src/com/sijobe/spc/core/IBreakSpeed.java | 27 +++++ src/com/sijobe/spc/util/AccessHelper.java | 14 +++ .../sijobe/spc/util/DynamicClassLoader.java | 2 +- 9 files changed, 187 insertions(+), 34 deletions(-) create mode 100644 src/com/sijobe/spc/asm/SpcAccessTransformer.java create mode 100644 src/com/sijobe/spc/core/IBlockBroken.java create mode 100644 src/com/sijobe/spc/core/IBreakSpeed.java create mode 100644 src/com/sijobe/spc/util/AccessHelper.java diff --git a/src/com/sijobe/spc/ModSpc.java b/src/com/sijobe/spc/ModSpc.java index f35e9cd..9eb34c9 100644 --- a/src/com/sijobe/spc/ModSpc.java +++ b/src/com/sijobe/spc/ModSpc.java @@ -5,6 +5,8 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; +import net.minecraftforge.event.entity.player.PlayerEvent.BreakSpeed; +import net.minecraftforge.event.world.BlockEvent.BreakEvent; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; @@ -19,11 +21,14 @@ import com.sijobe.spc.core.Constants; import com.sijobe.spc.core.HookManager; +import com.sijobe.spc.core.IBlockBroken; +import com.sijobe.spc.core.IBreakSpeed; import com.sijobe.spc.core.IHook; import com.sijobe.spc.util.DynamicClassLoader; import com.sijobe.spc.wrapper.Block; import com.sijobe.spc.wrapper.Item; import com.sijobe.spc.wrapper.Player; +import com.sijobe.spc.wrapper.World; import com.sijobe.spc.core.IPlayerMP; import com.sijobe.spc.core.IPlayerSP; import com.sijobe.spc.core.ICUIEventHandler; @@ -49,6 +54,8 @@ public void init(FMLInitializationEvent event) this.hookManager.loadHooks(IPlayerMP.class); this.hookManager.loadHooks(IPlayerSP.class); this.hookManager.loadHooks(ICUIEventHandler.class); + this.hookManager.loadHooks(IBreakSpeed.class); + this.hookManager.loadHooks(IBlockBroken.class); MinecraftForge.EVENT_BUS.register(this); FMLCommonHandler.instance().bus().register(this); } @@ -60,6 +67,7 @@ public void onServerStarting(FMLServerStartingEvent event) this.commands.loadCommands(); } + //TODO make void handleHook() @SubscribeEvent public void onPlayerTick(PlayerTickEvent event) { @@ -94,4 +102,29 @@ else if(event.player instanceof EntityPlayerMP) } } } + + @SubscribeEvent + public void onBreakSpeed(BreakSpeed event) + { + for(IBreakSpeed hook : this.hookManager.getHooks(IBreakSpeed.class)) + { + if(hook.isEnabled()) + { + //TODO pass same player instance instead of creating a new one each time + event.newSpeed = hook.getBreakSpeed(new Player(event.entityPlayer), Block.fromMinecraftBlock(event.block), event.metadata, event.originalSpeed, event.x, event.y, event.z); + } + } + } + + @SubscribeEvent + public void onBlockBreak(BreakEvent event) + { + for(IBlockBroken hook : this.hookManager.getHooks(IBlockBroken.class)) + { + if(hook.isEnabled()) + { + hook.onBreakBroken(event.x, event.y, event.z, new World(event.world), Block.fromMinecraftBlock(event.block), event.blockMetadata, new Player(event.getPlayer())); + } + } + } } diff --git a/src/com/sijobe/spc/asm/MethodOverwriter.java b/src/com/sijobe/spc/asm/MethodOverwriter.java index c1ef149..1a8ac65 100644 --- a/src/com/sijobe/spc/asm/MethodOverwriter.java +++ b/src/com/sijobe/spc/asm/MethodOverwriter.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Set; +import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -74,4 +75,21 @@ protected void getBlockReachDistance() mv.visitMaxs(1, 1); mv.visitEnd(); } + + /* + @Replacer("net.minecraft.block.Block:getPlayerRelativeBlockHardness:(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;III)F") + protected void getPlayerRelativeBlockHardness() + { + MethodVisitor mv = this.writer; + mv.visitCode(); + mv.visitFieldInsn(Opcodes.GETSTATIC, "com/sijobe/spc/command/InstantMine", "instantMiningEnabled", "Z"); + Label l0 = new Label(); + mv.visitJumpInsn(Opcodes.IFEQ, l0); + mv.visitLdcInsn(new Float("1.1")); + mv.visitInsn(Opcodes.FRETURN); + mv.visitLabel(l0); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + this.mv = mv; //so the MethodWriter instance gets its visit methods called + } + */ } diff --git a/src/com/sijobe/spc/asm/SpcAccessTransformer.java b/src/com/sijobe/spc/asm/SpcAccessTransformer.java new file mode 100644 index 0000000..dd54935 --- /dev/null +++ b/src/com/sijobe/spc/asm/SpcAccessTransformer.java @@ -0,0 +1,13 @@ +package com.sijobe.spc.asm; + +import java.io.IOException; + +import cpw.mods.fml.common.asm.transformers.AccessTransformer; + +public class SpcAccessTransformer extends AccessTransformer +{ + public SpcAccessTransformer() throws IOException + { + super("com/sijobe/spc/asm/spc_at.txt"); + } +} diff --git a/src/com/sijobe/spc/asm/SpcCoreMod.java b/src/com/sijobe/spc/asm/SpcCoreMod.java index d2452fa..e087bdc 100644 --- a/src/com/sijobe/spc/asm/SpcCoreMod.java +++ b/src/com/sijobe/spc/asm/SpcCoreMod.java @@ -11,7 +11,7 @@ public class SpcCoreMod implements IFMLLoadingPlugin @Override public String[] getASMTransformerClass() { - return new String[]{Transformer.class.getName()}; + return new String[]{Transformer.class.getName(), SpcAccessTransformer.class.getName()}; } @Override diff --git a/src/com/sijobe/spc/command/InstantMine.java b/src/com/sijobe/spc/command/InstantMine.java index 16f4bc7..7639ef1 100644 --- a/src/com/sijobe/spc/command/InstantMine.java +++ b/src/com/sijobe/spc/command/InstantMine.java @@ -1,14 +1,21 @@ package com.sijobe.spc.command; +import com.sijobe.spc.core.IBlockBroken; +import com.sijobe.spc.core.IBreakSpeed; +import com.sijobe.spc.util.AccessHelper; import com.sijobe.spc.util.ForgeHelper; import com.sijobe.spc.util.Settings; import com.sijobe.spc.validation.Parameters; +import com.sijobe.spc.wrapper.Block; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; +import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.Player; +import com.sijobe.spc.wrapper.World; import java.util.List; +import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.entity.player.EntityPlayerMP; /** @@ -16,38 +23,70 @@ * * @author q3hardcore * @version 1.0 - * @status broken through 1.7.2 update + * @status broken through 1.7.2 update -> fixed */ @Command ( - name = "instantmine", - description = "Allows player to mine blocks instantly", - example = "", - videoURL = "", - enabled = true -) -public class InstantMine extends StandardCommand { - @Override - public void execute(CommandSender sender, List params) throws CommandException { - Player player = super.getSenderAsPlayer(sender); - if(player.getMinecraftPlayer() instanceof EntityPlayerMP) { - Settings config = super.loadSettings(player); - boolean instantMine = config.getBoolean("instantMine", false); - if (params.size() == 0) { - instantMine ^= true; - } else { - instantMine = ((Boolean)params.get(0)); - } - config.set("instantMine", instantMine); - super.saveSettings(player); - player.sendChatMessage("Instant mining " + (instantMine?"enabled.":"disabled.")); - } else { - throw new CommandException("Non-client command"); - } - } - - @Override - public Parameters getParameters() { - return Parameters.DEFAULT_BOOLEAN; - } - + name = "instantmine", + description = "Allows player to mine blocks instantly", + example = "", + videoURL = "", + enabled = true + ) +public class InstantMine extends StandardCommand implements IBreakSpeed, IBlockBroken{ + public static boolean instantMiningEnabled; + + @Override + public void execute(CommandSender sender, List params) throws CommandException { + Player player = super.getSenderAsPlayer(sender); + if(player.getMinecraftPlayer() instanceof EntityPlayerMP) { + Settings config = super.loadSettings(player); + boolean instantMine = config.getBoolean("instantMine", false); + if (params.size() == 0) { + instantMine ^= true; + } else { + instantMine = ((Boolean)params.get(0)); + } + + config.set("instantMine", instantMine); + super.saveSettings(player); + instantMiningEnabled = instantMine; + player.sendChatMessage("Instant mining " + (instantMine?"enabled.":"disabled.")); + } else { + throw new CommandException("Non-client command"); + } + } + + @Override + public Parameters getParameters() { + return Parameters.DEFAULT_BOOLEAN; + } + + @Override + public void init(Object... params) {} + + @Override + public float getBreakSpeed(Player player, Block block, int metadata, float orginalSpeed, int x, int y, int z) { + System.out.println("getting break speed..."); + return instantMiningEnabled ? 50000000.0F : orginalSpeed; + } + + @Override + public void onBreakBroken(int x, int y, int z, World world, Block block, int metadata, Player player) { + System.out.println("setting blockHitDelay"); + try { + AccessHelper.setInt(Minecraft.getMinecraft().playerController, "blockHitDelay", 5); + } catch (NoSuchFieldException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } \ No newline at end of file diff --git a/src/com/sijobe/spc/core/IBlockBroken.java b/src/com/sijobe/spc/core/IBlockBroken.java new file mode 100644 index 0000000..d382372 --- /dev/null +++ b/src/com/sijobe/spc/core/IBlockBroken.java @@ -0,0 +1,9 @@ +package com.sijobe.spc.core; + +import com.sijobe.spc.wrapper.Block; +import com.sijobe.spc.wrapper.Player; +import com.sijobe.spc.wrapper.World; + +public interface IBlockBroken extends IHook { + public void onBreakBroken(int x, int y, int z, World world, Block block, int metadata, Player player); +} diff --git a/src/com/sijobe/spc/core/IBreakSpeed.java b/src/com/sijobe/spc/core/IBreakSpeed.java new file mode 100644 index 0000000..b992984 --- /dev/null +++ b/src/com/sijobe/spc/core/IBreakSpeed.java @@ -0,0 +1,27 @@ +package com.sijobe.spc.core; + +import com.sijobe.spc.wrapper.Block; +import com.sijobe.spc.wrapper.Player; + + +/** + * Allows commands to change break speed + * Basically a wrapper for forge's BreakSpeed event + * @author aucguy + * + */ +public interface IBreakSpeed extends IHook { + /**called when a player damages a block + * + * @param player - the player that the event occurred on + * @param Block - the block being damaged + * @param metadata - the metadata of the block + * @param originalSpeed - the orginal break speed of the block + * @param x - the x positon of the block + * @param y - the y position of the block + * @param z - the z position of the block + * @return the new breaking speed + * */ + + public float getBreakSpeed(Player player, Block block, int metadata, float orginalSpeed, int x, int y, int z); +} diff --git a/src/com/sijobe/spc/util/AccessHelper.java b/src/com/sijobe/spc/util/AccessHelper.java new file mode 100644 index 0000000..a7057d5 --- /dev/null +++ b/src/com/sijobe/spc/util/AccessHelper.java @@ -0,0 +1,14 @@ +package com.sijobe.spc.util; + +import java.lang.reflect.Field; + +public class AccessHelper +{ + public static void setInt(Object obj, String name, int value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException + { + Class clazz = obj.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + field.setInt(obj, value); + } +} diff --git a/src/com/sijobe/spc/util/DynamicClassLoader.java b/src/com/sijobe/spc/util/DynamicClassLoader.java index e7f57e7..c902f04 100644 --- a/src/com/sijobe/spc/util/DynamicClassLoader.java +++ b/src/com/sijobe/spc/util/DynamicClassLoader.java @@ -203,7 +203,7 @@ public static List> loadSPCClassesFromDirectory(File directory, String File files[] = directory.listFiles(); for (File file : files) { try { - if (file.isFile()) { + if (file.isFile() && file.getPath().endsWith(".class")) { //TODO add class file type check to loadSPCClassesFromJar classes.add(loadClass(file.getName(),parent)); } else { classes.addAll(loadSPCClassesFromDirectory(file,parent + file.getName() + "/")); From 4273745eefc756c2db0e80c67f4beb54cd87f40b Mon Sep 17 00:00:00 2001 From: aucguy Date: Sun, 16 Nov 2014 16:52:04 -0600 Subject: [PATCH 04/20] Fixed nullPointerException when loading classes from a directory(DynamicClassLoader.loadSPCClassesFromDirectory(File, String)) --- src/com/sijobe/spc/command/InstantMine.java | 2 +- src/com/sijobe/spc/util/DynamicClassLoader.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/sijobe/spc/command/InstantMine.java b/src/com/sijobe/spc/command/InstantMine.java index 7639ef1..e373696 100644 --- a/src/com/sijobe/spc/command/InstantMine.java +++ b/src/com/sijobe/spc/command/InstantMine.java @@ -33,7 +33,7 @@ enabled = true ) public class InstantMine extends StandardCommand implements IBreakSpeed, IBlockBroken{ - public static boolean instantMiningEnabled; + public static boolean instantMiningEnabled; //TODO load initial value from config @Override public void execute(CommandSender sender, List params) throws CommandException { diff --git a/src/com/sijobe/spc/util/DynamicClassLoader.java b/src/com/sijobe/spc/util/DynamicClassLoader.java index c902f04..2b52079 100644 --- a/src/com/sijobe/spc/util/DynamicClassLoader.java +++ b/src/com/sijobe/spc/util/DynamicClassLoader.java @@ -205,7 +205,7 @@ public static List> loadSPCClassesFromDirectory(File directory, String try { if (file.isFile() && file.getPath().endsWith(".class")) { //TODO add class file type check to loadSPCClassesFromJar classes.add(loadClass(file.getName(),parent)); - } else { + } else if(file.isDirectory()){ classes.addAll(loadSPCClassesFromDirectory(file,parent + file.getName() + "/")); } } catch (Exception e) { From 9b62ac657bdb527ebbb8048ac6ffa8547c2872b3 Mon Sep 17 00:00:00 2001 From: aucguy Date: Sun, 16 Nov 2014 17:14:14 -0600 Subject: [PATCH 05/20] -Changed file format to include resources and to adapt to the new forge development enviroment. -Fixed moveplayer command. --- .../java}/com/sijobe/spc/ModSpc.java | 0 .../sijobe/spc/asm/CustomClassVisitor.java | 0 .../com/sijobe/spc/asm/MethodOverwriter.java | 0 .../java}/com/sijobe/spc/asm/Replacer.java | 0 .../sijobe/spc/asm/SpcAccessTransformer.java | 0 .../java}/com/sijobe/spc/asm/SpcCoreMod.java | 0 .../java}/com/sijobe/spc/asm/Transformer.java | 0 .../java/com/sijobe/spc/asm/make/Block.java | 19 ++++++ .../java}/com/sijobe/spc/asm/make/Make.java | 0 .../com/sijobe/spc/command/Achievement.java | 0 .../java}/com/sijobe/spc/command/Ascend.java | 0 .../java}/com/sijobe/spc/command/Bind.java | 0 .../com/sijobe/spc/command/BlockReach.java | 0 .../java}/com/sijobe/spc/command/Bring.java | 0 .../java}/com/sijobe/spc/command/Cannon.java | 0 .../java}/com/sijobe/spc/command/Cheats.java | 0 .../com/sijobe/spc/command/ClearDrops.java | 0 .../java}/com/sijobe/spc/command/Command.java | 0 .../com/sijobe/spc/command/CriticalHit.java | 0 .../java}/com/sijobe/spc/command/Damage.java | 0 .../java}/com/sijobe/spc/command/Descend.java | 0 .../com/sijobe/spc/command/Difficulty.java | 0 .../java}/com/sijobe/spc/command/DoDrops.java | 0 .../java}/com/sijobe/spc/command/Effect.java | 0 .../java}/com/sijobe/spc/command/Enchant.java | 0 .../com/sijobe/spc/command/EnderChest.java | 68 +++++++++---------- .../com/sijobe/spc/command/EnderCrystal.java | 0 .../java}/com/sijobe/spc/command/Explode.java | 0 .../com/sijobe/spc/command/Firework.java | 0 .../java}/com/sijobe/spc/command/Fly.java | 0 .../com/sijobe/spc/command/Gamemode.java | 0 .../java}/com/sijobe/spc/command/Give.java | 0 .../com/sijobe/spc/command/Hardcore.java | 0 .../java}/com/sijobe/spc/command/Heal.java | 0 .../java}/com/sijobe/spc/command/Health.java | 0 .../java}/com/sijobe/spc/command/Help.java | 0 .../java}/com/sijobe/spc/command/Home.java | 0 .../java}/com/sijobe/spc/command/Hunger.java | 0 .../java}/com/sijobe/spc/command/Ignite.java | 0 .../com/sijobe/spc/command/InstantMine.java | 0 .../java}/com/sijobe/spc/command/Jump.java | 0 .../java}/com/sijobe/spc/command/Kill.java | 0 .../java}/com/sijobe/spc/command/KillAll.java | 0 .../java}/com/sijobe/spc/command/Light.java | 0 .../com/sijobe/spc/command/LongerLegs.java | 0 .../java}/com/sijobe/spc/command/Macro.java | 0 .../com/sijobe/spc/command/MovePlayer.java | 10 +-- .../sijobe/spc/command/MultipleCommands.java | 0 .../java}/com/sijobe/spc/command/Noclip.java | 0 .../java}/com/sijobe/spc/command/Path.java | 0 .../com/sijobe/spc/command/Platform.java | 0 .../com/sijobe/spc/command/Position.java | 0 .../com/sijobe/spc/command/PrefixSlash.java | 0 .../java}/com/sijobe/spc/command/Repair.java | 0 .../java}/com/sijobe/spc/command/SPC.java | 0 .../java}/com/sijobe/spc/command/Scuba.java | 0 .../com/sijobe/spc/command/SetSpawn.java | 0 .../com/sijobe/spc/command/SetSpeed.java | 0 .../java}/com/sijobe/spc/command/Skin.java | 0 .../java}/com/sijobe/spc/command/Spawn.java | 0 .../com/sijobe/spc/command/SpawnPortal.java | 0 .../sijobe/spc/command/StandardCommand.java | 0 .../java}/com/sijobe/spc/command/Sudo.java | 0 .../com/sijobe/spc/command/SuperHeat.java | 0 .../com/sijobe/spc/command/Teleport.java | 0 .../java}/com/sijobe/spc/command/Test.java | 0 .../java}/com/sijobe/spc/command/Time.java | 0 .../com/sijobe/spc/command/UsePortal.java | 0 .../com/sijobe/spc/command/Waypoint.java | 0 .../java}/com/sijobe/spc/command/Weather.java | 0 .../java}/com/sijobe/spc/core/Constants.java | 0 .../com/sijobe/spc/core/HookManager.java | 0 .../com/sijobe/spc/core/IBlockBroken.java | 0 .../com/sijobe/spc/core/IBreakSpeed.java | 0 .../com/sijobe/spc/core/ICUIEventHandler.java | 0 .../java}/com/sijobe/spc/core/IHook.java | 0 .../java}/com/sijobe/spc/core/IPlayerMP.java | 0 .../java}/com/sijobe/spc/core/IPlayerSP.java | 0 .../java}/com/sijobe/spc/core/PlayerMP.java | 0 .../java}/com/sijobe/spc/core/PlayerSP.java | 0 .../java}/com/sijobe/spc/core/SPCLoader.java | 0 .../com/sijobe/spc/hooks/CheckUpdates.java | 0 .../sijobe/spc/hooks/InitialiseCommands.java | 0 .../com/sijobe/spc/hooks/TestPlayerMP.java | 0 .../com/sijobe/spc/hooks/WorldEditCUI.java | 0 .../spc/overwrite/ONetServerHandler.java | 0 .../com/sijobe/spc/updater/CheckVersion.java | 0 .../com/sijobe/spc/updater/ModVersion.java | 0 .../sijobe/spc/updater/UpdateCallback.java | 0 .../com/sijobe/spc/util/AccessHelper.java | 0 .../sijobe/spc/util/CommandBlockHelper.java | 0 .../sijobe/spc/util/DynamicClassLoader.java | 0 .../java}/com/sijobe/spc/util/FontColour.java | 0 .../com/sijobe/spc/util/ForgeHelper.java | 0 .../com/sijobe/spc/util/KeyListener.java | 0 .../com/sijobe/spc/util/KeyboardHandler.java | 0 .../java}/com/sijobe/spc/util/Mappings.java | 0 .../java}/com/sijobe/spc/util/PathData.java | 0 .../com/sijobe/spc/util/ReflectionHelper.java | 0 .../java}/com/sijobe/spc/util/Settings.java | 0 .../com/sijobe/spc/util/SettingsManager.java | 0 .../sijobe/spc/util/WorldEditCUIHelper.java | 0 .../com/sijobe/spc/validation/Parameter.java | 0 .../spc/validation/ParameterBoolean.java | 0 .../spc/validation/ParameterDouble.java | 0 .../spc/validation/ParameterInteger.java | 0 .../sijobe/spc/validation/ParameterLong.java | 0 .../spc/validation/ParameterPlayer.java | 0 .../spc/validation/ParameterString.java | 0 .../com/sijobe/spc/validation/Parameters.java | 0 .../spc/validation/ValidationException.java | 0 .../java}/com/sijobe/spc/wrapper/Block.java | 0 .../java}/com/sijobe/spc/wrapper/Blocks.java | 0 .../com/sijobe/spc/wrapper/CommandBase.java | 0 .../sijobe/spc/wrapper/CommandException.java | 0 .../sijobe/spc/wrapper/CommandManager.java | 0 .../com/sijobe/spc/wrapper/CommandSender.java | 0 .../com/sijobe/spc/wrapper/Coordinate.java | 0 .../java}/com/sijobe/spc/wrapper/Entity.java | 0 .../java}/com/sijobe/spc/wrapper/Item.java | 0 .../com/sijobe/spc/wrapper/Minecraft.java | 0 .../sijobe/spc/wrapper/MinecraftServer.java | 0 .../java}/com/sijobe/spc/wrapper/Player.java | 0 .../java}/com/sijobe/spc/wrapper/Potion.java | 0 .../java}/com/sijobe/spc/wrapper/Stats.java | 0 .../java}/com/sijobe/spc/wrapper/World.java | 0 .../resources/com/sijobe/spc/asm/spc_at.txt | 1 + src/main/resources/mcmod.info | 18 +++++ 128 files changed, 78 insertions(+), 38 deletions(-) rename src/{ => main/java}/com/sijobe/spc/ModSpc.java (100%) rename src/{ => main/java}/com/sijobe/spc/asm/CustomClassVisitor.java (100%) rename src/{ => main/java}/com/sijobe/spc/asm/MethodOverwriter.java (100%) rename src/{ => main/java}/com/sijobe/spc/asm/Replacer.java (100%) rename src/{ => main/java}/com/sijobe/spc/asm/SpcAccessTransformer.java (100%) rename src/{ => main/java}/com/sijobe/spc/asm/SpcCoreMod.java (100%) rename src/{ => main/java}/com/sijobe/spc/asm/Transformer.java (100%) create mode 100644 src/main/java/com/sijobe/spc/asm/make/Block.java rename src/{ => main/java}/com/sijobe/spc/asm/make/Make.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Achievement.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Ascend.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Bind.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/BlockReach.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Bring.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Cannon.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Cheats.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/ClearDrops.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Command.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/CriticalHit.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Damage.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Descend.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Difficulty.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/DoDrops.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Effect.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Enchant.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/EnderChest.java (96%) rename src/{ => main/java}/com/sijobe/spc/command/EnderCrystal.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Explode.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Firework.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Fly.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Gamemode.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Give.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Hardcore.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Heal.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Health.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Help.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Home.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Hunger.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Ignite.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/InstantMine.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Jump.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Kill.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/KillAll.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Light.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/LongerLegs.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Macro.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/MovePlayer.java (93%) rename src/{ => main/java}/com/sijobe/spc/command/MultipleCommands.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Noclip.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Path.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Platform.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Position.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/PrefixSlash.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Repair.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/SPC.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Scuba.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/SetSpawn.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/SetSpeed.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Skin.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Spawn.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/SpawnPortal.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/StandardCommand.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Sudo.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/SuperHeat.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Teleport.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Test.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Time.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/UsePortal.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Waypoint.java (100%) rename src/{ => main/java}/com/sijobe/spc/command/Weather.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/Constants.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/HookManager.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/IBlockBroken.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/IBreakSpeed.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/ICUIEventHandler.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/IHook.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/IPlayerMP.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/IPlayerSP.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/PlayerMP.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/PlayerSP.java (100%) rename src/{ => main/java}/com/sijobe/spc/core/SPCLoader.java (100%) rename src/{ => main/java}/com/sijobe/spc/hooks/CheckUpdates.java (100%) rename src/{ => main/java}/com/sijobe/spc/hooks/InitialiseCommands.java (100%) rename src/{ => main/java}/com/sijobe/spc/hooks/TestPlayerMP.java (100%) rename src/{ => main/java}/com/sijobe/spc/hooks/WorldEditCUI.java (100%) rename src/{ => main/java}/com/sijobe/spc/overwrite/ONetServerHandler.java (100%) rename src/{ => main/java}/com/sijobe/spc/updater/CheckVersion.java (100%) rename src/{ => main/java}/com/sijobe/spc/updater/ModVersion.java (100%) rename src/{ => main/java}/com/sijobe/spc/updater/UpdateCallback.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/AccessHelper.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/CommandBlockHelper.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/DynamicClassLoader.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/FontColour.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/ForgeHelper.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/KeyListener.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/KeyboardHandler.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/Mappings.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/PathData.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/ReflectionHelper.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/Settings.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/SettingsManager.java (100%) rename src/{ => main/java}/com/sijobe/spc/util/WorldEditCUIHelper.java (100%) rename src/{ => main/java}/com/sijobe/spc/validation/Parameter.java (100%) rename src/{ => main/java}/com/sijobe/spc/validation/ParameterBoolean.java (100%) rename src/{ => main/java}/com/sijobe/spc/validation/ParameterDouble.java (100%) rename src/{ => main/java}/com/sijobe/spc/validation/ParameterInteger.java (100%) rename src/{ => main/java}/com/sijobe/spc/validation/ParameterLong.java (100%) rename src/{ => main/java}/com/sijobe/spc/validation/ParameterPlayer.java (100%) rename src/{ => main/java}/com/sijobe/spc/validation/ParameterString.java (100%) rename src/{ => main/java}/com/sijobe/spc/validation/Parameters.java (100%) rename src/{ => main/java}/com/sijobe/spc/validation/ValidationException.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/Block.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/Blocks.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/CommandBase.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/CommandException.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/CommandManager.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/CommandSender.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/Coordinate.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/Entity.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/Item.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/Minecraft.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/MinecraftServer.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/Player.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/Potion.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/Stats.java (100%) rename src/{ => main/java}/com/sijobe/spc/wrapper/World.java (100%) create mode 100644 src/main/resources/com/sijobe/spc/asm/spc_at.txt create mode 100644 src/main/resources/mcmod.info diff --git a/src/com/sijobe/spc/ModSpc.java b/src/main/java/com/sijobe/spc/ModSpc.java similarity index 100% rename from src/com/sijobe/spc/ModSpc.java rename to src/main/java/com/sijobe/spc/ModSpc.java diff --git a/src/com/sijobe/spc/asm/CustomClassVisitor.java b/src/main/java/com/sijobe/spc/asm/CustomClassVisitor.java similarity index 100% rename from src/com/sijobe/spc/asm/CustomClassVisitor.java rename to src/main/java/com/sijobe/spc/asm/CustomClassVisitor.java diff --git a/src/com/sijobe/spc/asm/MethodOverwriter.java b/src/main/java/com/sijobe/spc/asm/MethodOverwriter.java similarity index 100% rename from src/com/sijobe/spc/asm/MethodOverwriter.java rename to src/main/java/com/sijobe/spc/asm/MethodOverwriter.java diff --git a/src/com/sijobe/spc/asm/Replacer.java b/src/main/java/com/sijobe/spc/asm/Replacer.java similarity index 100% rename from src/com/sijobe/spc/asm/Replacer.java rename to src/main/java/com/sijobe/spc/asm/Replacer.java diff --git a/src/com/sijobe/spc/asm/SpcAccessTransformer.java b/src/main/java/com/sijobe/spc/asm/SpcAccessTransformer.java similarity index 100% rename from src/com/sijobe/spc/asm/SpcAccessTransformer.java rename to src/main/java/com/sijobe/spc/asm/SpcAccessTransformer.java diff --git a/src/com/sijobe/spc/asm/SpcCoreMod.java b/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java similarity index 100% rename from src/com/sijobe/spc/asm/SpcCoreMod.java rename to src/main/java/com/sijobe/spc/asm/SpcCoreMod.java diff --git a/src/com/sijobe/spc/asm/Transformer.java b/src/main/java/com/sijobe/spc/asm/Transformer.java similarity index 100% rename from src/com/sijobe/spc/asm/Transformer.java rename to src/main/java/com/sijobe/spc/asm/Transformer.java diff --git a/src/main/java/com/sijobe/spc/asm/make/Block.java b/src/main/java/com/sijobe/spc/asm/make/Block.java new file mode 100644 index 0000000..678d228 --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/make/Block.java @@ -0,0 +1,19 @@ +package com.sijobe.spc.asm.make; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +public class Block +{ + private int blockHitDelay; + + public float getPlayerRelativeBlockHardness(EntityPlayer p_149737_1_, World p_149737_2_, int p_149737_3_, int p_149737_4_, int p_149737_5_) + { + if(com.sijobe.spc.command.InstantMine.instantMiningEnabled) + { + this.blockHitDelay = 5; + return 1.1F; + } + return p_149737_5_; + } +} diff --git a/src/com/sijobe/spc/asm/make/Make.java b/src/main/java/com/sijobe/spc/asm/make/Make.java similarity index 100% rename from src/com/sijobe/spc/asm/make/Make.java rename to src/main/java/com/sijobe/spc/asm/make/Make.java diff --git a/src/com/sijobe/spc/command/Achievement.java b/src/main/java/com/sijobe/spc/command/Achievement.java similarity index 100% rename from src/com/sijobe/spc/command/Achievement.java rename to src/main/java/com/sijobe/spc/command/Achievement.java diff --git a/src/com/sijobe/spc/command/Ascend.java b/src/main/java/com/sijobe/spc/command/Ascend.java similarity index 100% rename from src/com/sijobe/spc/command/Ascend.java rename to src/main/java/com/sijobe/spc/command/Ascend.java diff --git a/src/com/sijobe/spc/command/Bind.java b/src/main/java/com/sijobe/spc/command/Bind.java similarity index 100% rename from src/com/sijobe/spc/command/Bind.java rename to src/main/java/com/sijobe/spc/command/Bind.java diff --git a/src/com/sijobe/spc/command/BlockReach.java b/src/main/java/com/sijobe/spc/command/BlockReach.java similarity index 100% rename from src/com/sijobe/spc/command/BlockReach.java rename to src/main/java/com/sijobe/spc/command/BlockReach.java diff --git a/src/com/sijobe/spc/command/Bring.java b/src/main/java/com/sijobe/spc/command/Bring.java similarity index 100% rename from src/com/sijobe/spc/command/Bring.java rename to src/main/java/com/sijobe/spc/command/Bring.java diff --git a/src/com/sijobe/spc/command/Cannon.java b/src/main/java/com/sijobe/spc/command/Cannon.java similarity index 100% rename from src/com/sijobe/spc/command/Cannon.java rename to src/main/java/com/sijobe/spc/command/Cannon.java diff --git a/src/com/sijobe/spc/command/Cheats.java b/src/main/java/com/sijobe/spc/command/Cheats.java similarity index 100% rename from src/com/sijobe/spc/command/Cheats.java rename to src/main/java/com/sijobe/spc/command/Cheats.java diff --git a/src/com/sijobe/spc/command/ClearDrops.java b/src/main/java/com/sijobe/spc/command/ClearDrops.java similarity index 100% rename from src/com/sijobe/spc/command/ClearDrops.java rename to src/main/java/com/sijobe/spc/command/ClearDrops.java diff --git a/src/com/sijobe/spc/command/Command.java b/src/main/java/com/sijobe/spc/command/Command.java similarity index 100% rename from src/com/sijobe/spc/command/Command.java rename to src/main/java/com/sijobe/spc/command/Command.java diff --git a/src/com/sijobe/spc/command/CriticalHit.java b/src/main/java/com/sijobe/spc/command/CriticalHit.java similarity index 100% rename from src/com/sijobe/spc/command/CriticalHit.java rename to src/main/java/com/sijobe/spc/command/CriticalHit.java diff --git a/src/com/sijobe/spc/command/Damage.java b/src/main/java/com/sijobe/spc/command/Damage.java similarity index 100% rename from src/com/sijobe/spc/command/Damage.java rename to src/main/java/com/sijobe/spc/command/Damage.java diff --git a/src/com/sijobe/spc/command/Descend.java b/src/main/java/com/sijobe/spc/command/Descend.java similarity index 100% rename from src/com/sijobe/spc/command/Descend.java rename to src/main/java/com/sijobe/spc/command/Descend.java diff --git a/src/com/sijobe/spc/command/Difficulty.java b/src/main/java/com/sijobe/spc/command/Difficulty.java similarity index 100% rename from src/com/sijobe/spc/command/Difficulty.java rename to src/main/java/com/sijobe/spc/command/Difficulty.java diff --git a/src/com/sijobe/spc/command/DoDrops.java b/src/main/java/com/sijobe/spc/command/DoDrops.java similarity index 100% rename from src/com/sijobe/spc/command/DoDrops.java rename to src/main/java/com/sijobe/spc/command/DoDrops.java diff --git a/src/com/sijobe/spc/command/Effect.java b/src/main/java/com/sijobe/spc/command/Effect.java similarity index 100% rename from src/com/sijobe/spc/command/Effect.java rename to src/main/java/com/sijobe/spc/command/Effect.java diff --git a/src/com/sijobe/spc/command/Enchant.java b/src/main/java/com/sijobe/spc/command/Enchant.java similarity index 100% rename from src/com/sijobe/spc/command/Enchant.java rename to src/main/java/com/sijobe/spc/command/Enchant.java diff --git a/src/com/sijobe/spc/command/EnderChest.java b/src/main/java/com/sijobe/spc/command/EnderChest.java similarity index 96% rename from src/com/sijobe/spc/command/EnderChest.java rename to src/main/java/com/sijobe/spc/command/EnderChest.java index 0da2843..7d92c2d 100644 --- a/src/com/sijobe/spc/command/EnderChest.java +++ b/src/main/java/com/sijobe/spc/command/EnderChest.java @@ -1,34 +1,34 @@ -package com.sijobe.spc.command; - -import com.sijobe.spc.wrapper.CommandException; -import com.sijobe.spc.wrapper.CommandSender; - -import net.minecraft.entity.player.EntityPlayer; - -import java.util.List; - -/** - * Open enderchest GUI anywhere - * - * @author q3hardcore - * @version 1.4.2 - * @status survived 1.7.2 update - */ -@Command ( - name = "enderchest", - description = "Opens EnderChest GUI without having EnderChest", - example = "", - version = "1.4.2" -) -public class EnderChest extends StandardCommand { - - /** - * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) - */ - @Override - public void execute(CommandSender sender, List params) throws CommandException { - EntityPlayer player = getSenderAsPlayer(sender).getMinecraftPlayer(); - player.displayGUIChest(player.getInventoryEnderChest()); - } - -} +package com.sijobe.spc.command; + +import com.sijobe.spc.wrapper.CommandException; +import com.sijobe.spc.wrapper.CommandSender; + +import net.minecraft.entity.player.EntityPlayer; + +import java.util.List; + +/** + * Open enderchest GUI anywhere + * + * @author q3hardcore + * @version 1.4.2 + * @status survived 1.7.2 update + */ +@Command ( + name = "enderchest", + description = "Opens EnderChest GUI without having EnderChest", + example = "", + version = "1.4.2" +) +public class EnderChest extends StandardCommand { + + /** + * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) + */ + @Override + public void execute(CommandSender sender, List params) throws CommandException { + EntityPlayer player = getSenderAsPlayer(sender).getMinecraftPlayer(); + player.displayGUIChest(player.getInventoryEnderChest()); + } + +} diff --git a/src/com/sijobe/spc/command/EnderCrystal.java b/src/main/java/com/sijobe/spc/command/EnderCrystal.java similarity index 100% rename from src/com/sijobe/spc/command/EnderCrystal.java rename to src/main/java/com/sijobe/spc/command/EnderCrystal.java diff --git a/src/com/sijobe/spc/command/Explode.java b/src/main/java/com/sijobe/spc/command/Explode.java similarity index 100% rename from src/com/sijobe/spc/command/Explode.java rename to src/main/java/com/sijobe/spc/command/Explode.java diff --git a/src/com/sijobe/spc/command/Firework.java b/src/main/java/com/sijobe/spc/command/Firework.java similarity index 100% rename from src/com/sijobe/spc/command/Firework.java rename to src/main/java/com/sijobe/spc/command/Firework.java diff --git a/src/com/sijobe/spc/command/Fly.java b/src/main/java/com/sijobe/spc/command/Fly.java similarity index 100% rename from src/com/sijobe/spc/command/Fly.java rename to src/main/java/com/sijobe/spc/command/Fly.java diff --git a/src/com/sijobe/spc/command/Gamemode.java b/src/main/java/com/sijobe/spc/command/Gamemode.java similarity index 100% rename from src/com/sijobe/spc/command/Gamemode.java rename to src/main/java/com/sijobe/spc/command/Gamemode.java diff --git a/src/com/sijobe/spc/command/Give.java b/src/main/java/com/sijobe/spc/command/Give.java similarity index 100% rename from src/com/sijobe/spc/command/Give.java rename to src/main/java/com/sijobe/spc/command/Give.java diff --git a/src/com/sijobe/spc/command/Hardcore.java b/src/main/java/com/sijobe/spc/command/Hardcore.java similarity index 100% rename from src/com/sijobe/spc/command/Hardcore.java rename to src/main/java/com/sijobe/spc/command/Hardcore.java diff --git a/src/com/sijobe/spc/command/Heal.java b/src/main/java/com/sijobe/spc/command/Heal.java similarity index 100% rename from src/com/sijobe/spc/command/Heal.java rename to src/main/java/com/sijobe/spc/command/Heal.java diff --git a/src/com/sijobe/spc/command/Health.java b/src/main/java/com/sijobe/spc/command/Health.java similarity index 100% rename from src/com/sijobe/spc/command/Health.java rename to src/main/java/com/sijobe/spc/command/Health.java diff --git a/src/com/sijobe/spc/command/Help.java b/src/main/java/com/sijobe/spc/command/Help.java similarity index 100% rename from src/com/sijobe/spc/command/Help.java rename to src/main/java/com/sijobe/spc/command/Help.java diff --git a/src/com/sijobe/spc/command/Home.java b/src/main/java/com/sijobe/spc/command/Home.java similarity index 100% rename from src/com/sijobe/spc/command/Home.java rename to src/main/java/com/sijobe/spc/command/Home.java diff --git a/src/com/sijobe/spc/command/Hunger.java b/src/main/java/com/sijobe/spc/command/Hunger.java similarity index 100% rename from src/com/sijobe/spc/command/Hunger.java rename to src/main/java/com/sijobe/spc/command/Hunger.java diff --git a/src/com/sijobe/spc/command/Ignite.java b/src/main/java/com/sijobe/spc/command/Ignite.java similarity index 100% rename from src/com/sijobe/spc/command/Ignite.java rename to src/main/java/com/sijobe/spc/command/Ignite.java diff --git a/src/com/sijobe/spc/command/InstantMine.java b/src/main/java/com/sijobe/spc/command/InstantMine.java similarity index 100% rename from src/com/sijobe/spc/command/InstantMine.java rename to src/main/java/com/sijobe/spc/command/InstantMine.java diff --git a/src/com/sijobe/spc/command/Jump.java b/src/main/java/com/sijobe/spc/command/Jump.java similarity index 100% rename from src/com/sijobe/spc/command/Jump.java rename to src/main/java/com/sijobe/spc/command/Jump.java diff --git a/src/com/sijobe/spc/command/Kill.java b/src/main/java/com/sijobe/spc/command/Kill.java similarity index 100% rename from src/com/sijobe/spc/command/Kill.java rename to src/main/java/com/sijobe/spc/command/Kill.java diff --git a/src/com/sijobe/spc/command/KillAll.java b/src/main/java/com/sijobe/spc/command/KillAll.java similarity index 100% rename from src/com/sijobe/spc/command/KillAll.java rename to src/main/java/com/sijobe/spc/command/KillAll.java diff --git a/src/com/sijobe/spc/command/Light.java b/src/main/java/com/sijobe/spc/command/Light.java similarity index 100% rename from src/com/sijobe/spc/command/Light.java rename to src/main/java/com/sijobe/spc/command/Light.java diff --git a/src/com/sijobe/spc/command/LongerLegs.java b/src/main/java/com/sijobe/spc/command/LongerLegs.java similarity index 100% rename from src/com/sijobe/spc/command/LongerLegs.java rename to src/main/java/com/sijobe/spc/command/LongerLegs.java diff --git a/src/com/sijobe/spc/command/Macro.java b/src/main/java/com/sijobe/spc/command/Macro.java similarity index 100% rename from src/com/sijobe/spc/command/Macro.java rename to src/main/java/com/sijobe/spc/command/Macro.java diff --git a/src/com/sijobe/spc/command/MovePlayer.java b/src/main/java/com/sijobe/spc/command/MovePlayer.java similarity index 93% rename from src/com/sijobe/spc/command/MovePlayer.java rename to src/main/java/com/sijobe/spc/command/MovePlayer.java index 454f53a..cb437c0 100644 --- a/src/com/sijobe/spc/command/MovePlayer.java +++ b/src/main/java/com/sijobe/spc/command/MovePlayer.java @@ -46,10 +46,12 @@ public void execute(CommandSender sender, List params) throws CommandExceptio Player player = super.getSenderAsPlayer(sender); Coordinate c = player.getPosition(); int distance = 0; - try { - distance = Integer.parseInt((String)params.get(0)); - } catch (NumberFormatException e) { - throw new CommandException("Could not parse disance specified as integer: " + params.get(0)); + System.out.println(params.get(0).getClass()); + if(params.get(0) instanceof Integer){ + distance = (Integer)params.get(0); + } + else{ + throw new CommandException("Could not parse disance specified as integer: " + params.get(0)); } if (((String)params.get(1)).toUpperCase().startsWith("N")) { diff --git a/src/com/sijobe/spc/command/MultipleCommands.java b/src/main/java/com/sijobe/spc/command/MultipleCommands.java similarity index 100% rename from src/com/sijobe/spc/command/MultipleCommands.java rename to src/main/java/com/sijobe/spc/command/MultipleCommands.java diff --git a/src/com/sijobe/spc/command/Noclip.java b/src/main/java/com/sijobe/spc/command/Noclip.java similarity index 100% rename from src/com/sijobe/spc/command/Noclip.java rename to src/main/java/com/sijobe/spc/command/Noclip.java diff --git a/src/com/sijobe/spc/command/Path.java b/src/main/java/com/sijobe/spc/command/Path.java similarity index 100% rename from src/com/sijobe/spc/command/Path.java rename to src/main/java/com/sijobe/spc/command/Path.java diff --git a/src/com/sijobe/spc/command/Platform.java b/src/main/java/com/sijobe/spc/command/Platform.java similarity index 100% rename from src/com/sijobe/spc/command/Platform.java rename to src/main/java/com/sijobe/spc/command/Platform.java diff --git a/src/com/sijobe/spc/command/Position.java b/src/main/java/com/sijobe/spc/command/Position.java similarity index 100% rename from src/com/sijobe/spc/command/Position.java rename to src/main/java/com/sijobe/spc/command/Position.java diff --git a/src/com/sijobe/spc/command/PrefixSlash.java b/src/main/java/com/sijobe/spc/command/PrefixSlash.java similarity index 100% rename from src/com/sijobe/spc/command/PrefixSlash.java rename to src/main/java/com/sijobe/spc/command/PrefixSlash.java diff --git a/src/com/sijobe/spc/command/Repair.java b/src/main/java/com/sijobe/spc/command/Repair.java similarity index 100% rename from src/com/sijobe/spc/command/Repair.java rename to src/main/java/com/sijobe/spc/command/Repair.java diff --git a/src/com/sijobe/spc/command/SPC.java b/src/main/java/com/sijobe/spc/command/SPC.java similarity index 100% rename from src/com/sijobe/spc/command/SPC.java rename to src/main/java/com/sijobe/spc/command/SPC.java diff --git a/src/com/sijobe/spc/command/Scuba.java b/src/main/java/com/sijobe/spc/command/Scuba.java similarity index 100% rename from src/com/sijobe/spc/command/Scuba.java rename to src/main/java/com/sijobe/spc/command/Scuba.java diff --git a/src/com/sijobe/spc/command/SetSpawn.java b/src/main/java/com/sijobe/spc/command/SetSpawn.java similarity index 100% rename from src/com/sijobe/spc/command/SetSpawn.java rename to src/main/java/com/sijobe/spc/command/SetSpawn.java diff --git a/src/com/sijobe/spc/command/SetSpeed.java b/src/main/java/com/sijobe/spc/command/SetSpeed.java similarity index 100% rename from src/com/sijobe/spc/command/SetSpeed.java rename to src/main/java/com/sijobe/spc/command/SetSpeed.java diff --git a/src/com/sijobe/spc/command/Skin.java b/src/main/java/com/sijobe/spc/command/Skin.java similarity index 100% rename from src/com/sijobe/spc/command/Skin.java rename to src/main/java/com/sijobe/spc/command/Skin.java diff --git a/src/com/sijobe/spc/command/Spawn.java b/src/main/java/com/sijobe/spc/command/Spawn.java similarity index 100% rename from src/com/sijobe/spc/command/Spawn.java rename to src/main/java/com/sijobe/spc/command/Spawn.java diff --git a/src/com/sijobe/spc/command/SpawnPortal.java b/src/main/java/com/sijobe/spc/command/SpawnPortal.java similarity index 100% rename from src/com/sijobe/spc/command/SpawnPortal.java rename to src/main/java/com/sijobe/spc/command/SpawnPortal.java diff --git a/src/com/sijobe/spc/command/StandardCommand.java b/src/main/java/com/sijobe/spc/command/StandardCommand.java similarity index 100% rename from src/com/sijobe/spc/command/StandardCommand.java rename to src/main/java/com/sijobe/spc/command/StandardCommand.java diff --git a/src/com/sijobe/spc/command/Sudo.java b/src/main/java/com/sijobe/spc/command/Sudo.java similarity index 100% rename from src/com/sijobe/spc/command/Sudo.java rename to src/main/java/com/sijobe/spc/command/Sudo.java diff --git a/src/com/sijobe/spc/command/SuperHeat.java b/src/main/java/com/sijobe/spc/command/SuperHeat.java similarity index 100% rename from src/com/sijobe/spc/command/SuperHeat.java rename to src/main/java/com/sijobe/spc/command/SuperHeat.java diff --git a/src/com/sijobe/spc/command/Teleport.java b/src/main/java/com/sijobe/spc/command/Teleport.java similarity index 100% rename from src/com/sijobe/spc/command/Teleport.java rename to src/main/java/com/sijobe/spc/command/Teleport.java diff --git a/src/com/sijobe/spc/command/Test.java b/src/main/java/com/sijobe/spc/command/Test.java similarity index 100% rename from src/com/sijobe/spc/command/Test.java rename to src/main/java/com/sijobe/spc/command/Test.java diff --git a/src/com/sijobe/spc/command/Time.java b/src/main/java/com/sijobe/spc/command/Time.java similarity index 100% rename from src/com/sijobe/spc/command/Time.java rename to src/main/java/com/sijobe/spc/command/Time.java diff --git a/src/com/sijobe/spc/command/UsePortal.java b/src/main/java/com/sijobe/spc/command/UsePortal.java similarity index 100% rename from src/com/sijobe/spc/command/UsePortal.java rename to src/main/java/com/sijobe/spc/command/UsePortal.java diff --git a/src/com/sijobe/spc/command/Waypoint.java b/src/main/java/com/sijobe/spc/command/Waypoint.java similarity index 100% rename from src/com/sijobe/spc/command/Waypoint.java rename to src/main/java/com/sijobe/spc/command/Waypoint.java diff --git a/src/com/sijobe/spc/command/Weather.java b/src/main/java/com/sijobe/spc/command/Weather.java similarity index 100% rename from src/com/sijobe/spc/command/Weather.java rename to src/main/java/com/sijobe/spc/command/Weather.java diff --git a/src/com/sijobe/spc/core/Constants.java b/src/main/java/com/sijobe/spc/core/Constants.java similarity index 100% rename from src/com/sijobe/spc/core/Constants.java rename to src/main/java/com/sijobe/spc/core/Constants.java diff --git a/src/com/sijobe/spc/core/HookManager.java b/src/main/java/com/sijobe/spc/core/HookManager.java similarity index 100% rename from src/com/sijobe/spc/core/HookManager.java rename to src/main/java/com/sijobe/spc/core/HookManager.java diff --git a/src/com/sijobe/spc/core/IBlockBroken.java b/src/main/java/com/sijobe/spc/core/IBlockBroken.java similarity index 100% rename from src/com/sijobe/spc/core/IBlockBroken.java rename to src/main/java/com/sijobe/spc/core/IBlockBroken.java diff --git a/src/com/sijobe/spc/core/IBreakSpeed.java b/src/main/java/com/sijobe/spc/core/IBreakSpeed.java similarity index 100% rename from src/com/sijobe/spc/core/IBreakSpeed.java rename to src/main/java/com/sijobe/spc/core/IBreakSpeed.java diff --git a/src/com/sijobe/spc/core/ICUIEventHandler.java b/src/main/java/com/sijobe/spc/core/ICUIEventHandler.java similarity index 100% rename from src/com/sijobe/spc/core/ICUIEventHandler.java rename to src/main/java/com/sijobe/spc/core/ICUIEventHandler.java diff --git a/src/com/sijobe/spc/core/IHook.java b/src/main/java/com/sijobe/spc/core/IHook.java similarity index 100% rename from src/com/sijobe/spc/core/IHook.java rename to src/main/java/com/sijobe/spc/core/IHook.java diff --git a/src/com/sijobe/spc/core/IPlayerMP.java b/src/main/java/com/sijobe/spc/core/IPlayerMP.java similarity index 100% rename from src/com/sijobe/spc/core/IPlayerMP.java rename to src/main/java/com/sijobe/spc/core/IPlayerMP.java diff --git a/src/com/sijobe/spc/core/IPlayerSP.java b/src/main/java/com/sijobe/spc/core/IPlayerSP.java similarity index 100% rename from src/com/sijobe/spc/core/IPlayerSP.java rename to src/main/java/com/sijobe/spc/core/IPlayerSP.java diff --git a/src/com/sijobe/spc/core/PlayerMP.java b/src/main/java/com/sijobe/spc/core/PlayerMP.java similarity index 100% rename from src/com/sijobe/spc/core/PlayerMP.java rename to src/main/java/com/sijobe/spc/core/PlayerMP.java diff --git a/src/com/sijobe/spc/core/PlayerSP.java b/src/main/java/com/sijobe/spc/core/PlayerSP.java similarity index 100% rename from src/com/sijobe/spc/core/PlayerSP.java rename to src/main/java/com/sijobe/spc/core/PlayerSP.java diff --git a/src/com/sijobe/spc/core/SPCLoader.java b/src/main/java/com/sijobe/spc/core/SPCLoader.java similarity index 100% rename from src/com/sijobe/spc/core/SPCLoader.java rename to src/main/java/com/sijobe/spc/core/SPCLoader.java diff --git a/src/com/sijobe/spc/hooks/CheckUpdates.java b/src/main/java/com/sijobe/spc/hooks/CheckUpdates.java similarity index 100% rename from src/com/sijobe/spc/hooks/CheckUpdates.java rename to src/main/java/com/sijobe/spc/hooks/CheckUpdates.java diff --git a/src/com/sijobe/spc/hooks/InitialiseCommands.java b/src/main/java/com/sijobe/spc/hooks/InitialiseCommands.java similarity index 100% rename from src/com/sijobe/spc/hooks/InitialiseCommands.java rename to src/main/java/com/sijobe/spc/hooks/InitialiseCommands.java diff --git a/src/com/sijobe/spc/hooks/TestPlayerMP.java b/src/main/java/com/sijobe/spc/hooks/TestPlayerMP.java similarity index 100% rename from src/com/sijobe/spc/hooks/TestPlayerMP.java rename to src/main/java/com/sijobe/spc/hooks/TestPlayerMP.java diff --git a/src/com/sijobe/spc/hooks/WorldEditCUI.java b/src/main/java/com/sijobe/spc/hooks/WorldEditCUI.java similarity index 100% rename from src/com/sijobe/spc/hooks/WorldEditCUI.java rename to src/main/java/com/sijobe/spc/hooks/WorldEditCUI.java diff --git a/src/com/sijobe/spc/overwrite/ONetServerHandler.java b/src/main/java/com/sijobe/spc/overwrite/ONetServerHandler.java similarity index 100% rename from src/com/sijobe/spc/overwrite/ONetServerHandler.java rename to src/main/java/com/sijobe/spc/overwrite/ONetServerHandler.java diff --git a/src/com/sijobe/spc/updater/CheckVersion.java b/src/main/java/com/sijobe/spc/updater/CheckVersion.java similarity index 100% rename from src/com/sijobe/spc/updater/CheckVersion.java rename to src/main/java/com/sijobe/spc/updater/CheckVersion.java diff --git a/src/com/sijobe/spc/updater/ModVersion.java b/src/main/java/com/sijobe/spc/updater/ModVersion.java similarity index 100% rename from src/com/sijobe/spc/updater/ModVersion.java rename to src/main/java/com/sijobe/spc/updater/ModVersion.java diff --git a/src/com/sijobe/spc/updater/UpdateCallback.java b/src/main/java/com/sijobe/spc/updater/UpdateCallback.java similarity index 100% rename from src/com/sijobe/spc/updater/UpdateCallback.java rename to src/main/java/com/sijobe/spc/updater/UpdateCallback.java diff --git a/src/com/sijobe/spc/util/AccessHelper.java b/src/main/java/com/sijobe/spc/util/AccessHelper.java similarity index 100% rename from src/com/sijobe/spc/util/AccessHelper.java rename to src/main/java/com/sijobe/spc/util/AccessHelper.java diff --git a/src/com/sijobe/spc/util/CommandBlockHelper.java b/src/main/java/com/sijobe/spc/util/CommandBlockHelper.java similarity index 100% rename from src/com/sijobe/spc/util/CommandBlockHelper.java rename to src/main/java/com/sijobe/spc/util/CommandBlockHelper.java diff --git a/src/com/sijobe/spc/util/DynamicClassLoader.java b/src/main/java/com/sijobe/spc/util/DynamicClassLoader.java similarity index 100% rename from src/com/sijobe/spc/util/DynamicClassLoader.java rename to src/main/java/com/sijobe/spc/util/DynamicClassLoader.java diff --git a/src/com/sijobe/spc/util/FontColour.java b/src/main/java/com/sijobe/spc/util/FontColour.java similarity index 100% rename from src/com/sijobe/spc/util/FontColour.java rename to src/main/java/com/sijobe/spc/util/FontColour.java diff --git a/src/com/sijobe/spc/util/ForgeHelper.java b/src/main/java/com/sijobe/spc/util/ForgeHelper.java similarity index 100% rename from src/com/sijobe/spc/util/ForgeHelper.java rename to src/main/java/com/sijobe/spc/util/ForgeHelper.java diff --git a/src/com/sijobe/spc/util/KeyListener.java b/src/main/java/com/sijobe/spc/util/KeyListener.java similarity index 100% rename from src/com/sijobe/spc/util/KeyListener.java rename to src/main/java/com/sijobe/spc/util/KeyListener.java diff --git a/src/com/sijobe/spc/util/KeyboardHandler.java b/src/main/java/com/sijobe/spc/util/KeyboardHandler.java similarity index 100% rename from src/com/sijobe/spc/util/KeyboardHandler.java rename to src/main/java/com/sijobe/spc/util/KeyboardHandler.java diff --git a/src/com/sijobe/spc/util/Mappings.java b/src/main/java/com/sijobe/spc/util/Mappings.java similarity index 100% rename from src/com/sijobe/spc/util/Mappings.java rename to src/main/java/com/sijobe/spc/util/Mappings.java diff --git a/src/com/sijobe/spc/util/PathData.java b/src/main/java/com/sijobe/spc/util/PathData.java similarity index 100% rename from src/com/sijobe/spc/util/PathData.java rename to src/main/java/com/sijobe/spc/util/PathData.java diff --git a/src/com/sijobe/spc/util/ReflectionHelper.java b/src/main/java/com/sijobe/spc/util/ReflectionHelper.java similarity index 100% rename from src/com/sijobe/spc/util/ReflectionHelper.java rename to src/main/java/com/sijobe/spc/util/ReflectionHelper.java diff --git a/src/com/sijobe/spc/util/Settings.java b/src/main/java/com/sijobe/spc/util/Settings.java similarity index 100% rename from src/com/sijobe/spc/util/Settings.java rename to src/main/java/com/sijobe/spc/util/Settings.java diff --git a/src/com/sijobe/spc/util/SettingsManager.java b/src/main/java/com/sijobe/spc/util/SettingsManager.java similarity index 100% rename from src/com/sijobe/spc/util/SettingsManager.java rename to src/main/java/com/sijobe/spc/util/SettingsManager.java diff --git a/src/com/sijobe/spc/util/WorldEditCUIHelper.java b/src/main/java/com/sijobe/spc/util/WorldEditCUIHelper.java similarity index 100% rename from src/com/sijobe/spc/util/WorldEditCUIHelper.java rename to src/main/java/com/sijobe/spc/util/WorldEditCUIHelper.java diff --git a/src/com/sijobe/spc/validation/Parameter.java b/src/main/java/com/sijobe/spc/validation/Parameter.java similarity index 100% rename from src/com/sijobe/spc/validation/Parameter.java rename to src/main/java/com/sijobe/spc/validation/Parameter.java diff --git a/src/com/sijobe/spc/validation/ParameterBoolean.java b/src/main/java/com/sijobe/spc/validation/ParameterBoolean.java similarity index 100% rename from src/com/sijobe/spc/validation/ParameterBoolean.java rename to src/main/java/com/sijobe/spc/validation/ParameterBoolean.java diff --git a/src/com/sijobe/spc/validation/ParameterDouble.java b/src/main/java/com/sijobe/spc/validation/ParameterDouble.java similarity index 100% rename from src/com/sijobe/spc/validation/ParameterDouble.java rename to src/main/java/com/sijobe/spc/validation/ParameterDouble.java diff --git a/src/com/sijobe/spc/validation/ParameterInteger.java b/src/main/java/com/sijobe/spc/validation/ParameterInteger.java similarity index 100% rename from src/com/sijobe/spc/validation/ParameterInteger.java rename to src/main/java/com/sijobe/spc/validation/ParameterInteger.java diff --git a/src/com/sijobe/spc/validation/ParameterLong.java b/src/main/java/com/sijobe/spc/validation/ParameterLong.java similarity index 100% rename from src/com/sijobe/spc/validation/ParameterLong.java rename to src/main/java/com/sijobe/spc/validation/ParameterLong.java diff --git a/src/com/sijobe/spc/validation/ParameterPlayer.java b/src/main/java/com/sijobe/spc/validation/ParameterPlayer.java similarity index 100% rename from src/com/sijobe/spc/validation/ParameterPlayer.java rename to src/main/java/com/sijobe/spc/validation/ParameterPlayer.java diff --git a/src/com/sijobe/spc/validation/ParameterString.java b/src/main/java/com/sijobe/spc/validation/ParameterString.java similarity index 100% rename from src/com/sijobe/spc/validation/ParameterString.java rename to src/main/java/com/sijobe/spc/validation/ParameterString.java diff --git a/src/com/sijobe/spc/validation/Parameters.java b/src/main/java/com/sijobe/spc/validation/Parameters.java similarity index 100% rename from src/com/sijobe/spc/validation/Parameters.java rename to src/main/java/com/sijobe/spc/validation/Parameters.java diff --git a/src/com/sijobe/spc/validation/ValidationException.java b/src/main/java/com/sijobe/spc/validation/ValidationException.java similarity index 100% rename from src/com/sijobe/spc/validation/ValidationException.java rename to src/main/java/com/sijobe/spc/validation/ValidationException.java diff --git a/src/com/sijobe/spc/wrapper/Block.java b/src/main/java/com/sijobe/spc/wrapper/Block.java similarity index 100% rename from src/com/sijobe/spc/wrapper/Block.java rename to src/main/java/com/sijobe/spc/wrapper/Block.java diff --git a/src/com/sijobe/spc/wrapper/Blocks.java b/src/main/java/com/sijobe/spc/wrapper/Blocks.java similarity index 100% rename from src/com/sijobe/spc/wrapper/Blocks.java rename to src/main/java/com/sijobe/spc/wrapper/Blocks.java diff --git a/src/com/sijobe/spc/wrapper/CommandBase.java b/src/main/java/com/sijobe/spc/wrapper/CommandBase.java similarity index 100% rename from src/com/sijobe/spc/wrapper/CommandBase.java rename to src/main/java/com/sijobe/spc/wrapper/CommandBase.java diff --git a/src/com/sijobe/spc/wrapper/CommandException.java b/src/main/java/com/sijobe/spc/wrapper/CommandException.java similarity index 100% rename from src/com/sijobe/spc/wrapper/CommandException.java rename to src/main/java/com/sijobe/spc/wrapper/CommandException.java diff --git a/src/com/sijobe/spc/wrapper/CommandManager.java b/src/main/java/com/sijobe/spc/wrapper/CommandManager.java similarity index 100% rename from src/com/sijobe/spc/wrapper/CommandManager.java rename to src/main/java/com/sijobe/spc/wrapper/CommandManager.java diff --git a/src/com/sijobe/spc/wrapper/CommandSender.java b/src/main/java/com/sijobe/spc/wrapper/CommandSender.java similarity index 100% rename from src/com/sijobe/spc/wrapper/CommandSender.java rename to src/main/java/com/sijobe/spc/wrapper/CommandSender.java diff --git a/src/com/sijobe/spc/wrapper/Coordinate.java b/src/main/java/com/sijobe/spc/wrapper/Coordinate.java similarity index 100% rename from src/com/sijobe/spc/wrapper/Coordinate.java rename to src/main/java/com/sijobe/spc/wrapper/Coordinate.java diff --git a/src/com/sijobe/spc/wrapper/Entity.java b/src/main/java/com/sijobe/spc/wrapper/Entity.java similarity index 100% rename from src/com/sijobe/spc/wrapper/Entity.java rename to src/main/java/com/sijobe/spc/wrapper/Entity.java diff --git a/src/com/sijobe/spc/wrapper/Item.java b/src/main/java/com/sijobe/spc/wrapper/Item.java similarity index 100% rename from src/com/sijobe/spc/wrapper/Item.java rename to src/main/java/com/sijobe/spc/wrapper/Item.java diff --git a/src/com/sijobe/spc/wrapper/Minecraft.java b/src/main/java/com/sijobe/spc/wrapper/Minecraft.java similarity index 100% rename from src/com/sijobe/spc/wrapper/Minecraft.java rename to src/main/java/com/sijobe/spc/wrapper/Minecraft.java diff --git a/src/com/sijobe/spc/wrapper/MinecraftServer.java b/src/main/java/com/sijobe/spc/wrapper/MinecraftServer.java similarity index 100% rename from src/com/sijobe/spc/wrapper/MinecraftServer.java rename to src/main/java/com/sijobe/spc/wrapper/MinecraftServer.java diff --git a/src/com/sijobe/spc/wrapper/Player.java b/src/main/java/com/sijobe/spc/wrapper/Player.java similarity index 100% rename from src/com/sijobe/spc/wrapper/Player.java rename to src/main/java/com/sijobe/spc/wrapper/Player.java diff --git a/src/com/sijobe/spc/wrapper/Potion.java b/src/main/java/com/sijobe/spc/wrapper/Potion.java similarity index 100% rename from src/com/sijobe/spc/wrapper/Potion.java rename to src/main/java/com/sijobe/spc/wrapper/Potion.java diff --git a/src/com/sijobe/spc/wrapper/Stats.java b/src/main/java/com/sijobe/spc/wrapper/Stats.java similarity index 100% rename from src/com/sijobe/spc/wrapper/Stats.java rename to src/main/java/com/sijobe/spc/wrapper/Stats.java diff --git a/src/com/sijobe/spc/wrapper/World.java b/src/main/java/com/sijobe/spc/wrapper/World.java similarity index 100% rename from src/com/sijobe/spc/wrapper/World.java rename to src/main/java/com/sijobe/spc/wrapper/World.java diff --git a/src/main/resources/com/sijobe/spc/asm/spc_at.txt b/src/main/resources/com/sijobe/spc/asm/spc_at.txt new file mode 100644 index 0000000..c5675b7 --- /dev/null +++ b/src/main/resources/com/sijobe/spc/asm/spc_at.txt @@ -0,0 +1 @@ +public int blockHitDelay \ No newline at end of file diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info new file mode 100644 index 0000000..1fca447 --- /dev/null +++ b/src/main/resources/mcmod.info @@ -0,0 +1,18 @@ +[ +{ + "modid": "spc", + "name": "Single Player Commands", + "description": "Adds various commands to minecraft", + "version": "5.0", + "mcversion": "1.7.2", + "url": "", + "updateUrl": "", + "authorList": ["sijobe", "q3hardcore", "aucguy"], + "credits": "simo_415 for making this mod in the first place, + q3hardcore and Lamp-Post for adding some commands and + aucguy for updating the mod to minecraft 1.7.2", + "logoFile": "", + "screenshots": [], + "dependencies": [] +} +] From cbb17907849416d1fcab210430db6d621abec5ff Mon Sep 17 00:00:00 2001 From: aucguy Date: Sun, 16 Nov 2014 17:50:43 -0600 Subject: [PATCH 06/20] Marked MovePlayer status as fixed --- src/main/java/com/sijobe/spc/command/MovePlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sijobe/spc/command/MovePlayer.java b/src/main/java/com/sijobe/spc/command/MovePlayer.java index cb437c0..282cc04 100644 --- a/src/main/java/com/sijobe/spc/command/MovePlayer.java +++ b/src/main/java/com/sijobe/spc/command/MovePlayer.java @@ -17,7 +17,7 @@ * * @author simo_415 * @version 1.0 - * @status broken through 1.7.2 update + * @status broken through 1.7.2 update -> fixed */ @Command ( name = "moveplayer", From efd49ec12823ffbdc26dcb69386f5d8a6e48fb4d Mon Sep 17 00:00:00 2001 From: aucguy Date: Sun, 16 Nov 2014 19:51:49 -0600 Subject: [PATCH 07/20] -Removed development files -Fixed noclip command --- .../com/sijobe/spc/asm/MethodOverwriter.java | 12 ++++++------ .../java/com/sijobe/spc/asm/make/Block.java | 19 ------------------- .../java/com/sijobe/spc/asm/make/Make.java | 9 --------- .../java/com/sijobe/spc/command/Noclip.java | 2 +- 4 files changed, 7 insertions(+), 35 deletions(-) delete mode 100644 src/main/java/com/sijobe/spc/asm/make/Block.java delete mode 100644 src/main/java/com/sijobe/spc/asm/make/Make.java diff --git a/src/main/java/com/sijobe/spc/asm/MethodOverwriter.java b/src/main/java/com/sijobe/spc/asm/MethodOverwriter.java index 1a8ac65..cabfbb2 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodOverwriter.java +++ b/src/main/java/com/sijobe/spc/asm/MethodOverwriter.java @@ -76,20 +76,20 @@ protected void getBlockReachDistance() mv.visitEnd(); } - /* - @Replacer("net.minecraft.block.Block:getPlayerRelativeBlockHardness:(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;III)F") - protected void getPlayerRelativeBlockHardness() + @Replacer("net.minecraft.client.renderer.ItemRenderer:renderInsideOfBlock:(FLnet/minecraft/util/IIcon;)V") + protected void renderInsideOfBlock() { MethodVisitor mv = this.writer; mv.visitCode(); - mv.visitFieldInsn(Opcodes.GETSTATIC, "com/sijobe/spc/command/InstantMine", "instantMiningEnabled", "Z"); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/wrapper/Minecraft", "getMinecraft", "()Lnet/minecraft/client/Minecraft;"); + mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/client/Minecraft", "thePlayer", "Lnet/minecraft/client/entity/EntityClientPlayerMP;"); + mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/client/entity/EntityClientPlayerMP", "noClip", "Z"); Label l0 = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, l0); mv.visitLdcInsn(new Float("1.1")); - mv.visitInsn(Opcodes.FRETURN); + mv.visitInsn(Opcodes.RETURN); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); this.mv = mv; //so the MethodWriter instance gets its visit methods called } - */ } diff --git a/src/main/java/com/sijobe/spc/asm/make/Block.java b/src/main/java/com/sijobe/spc/asm/make/Block.java deleted file mode 100644 index 678d228..0000000 --- a/src/main/java/com/sijobe/spc/asm/make/Block.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.sijobe.spc.asm.make; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.world.World; - -public class Block -{ - private int blockHitDelay; - - public float getPlayerRelativeBlockHardness(EntityPlayer p_149737_1_, World p_149737_2_, int p_149737_3_, int p_149737_4_, int p_149737_5_) - { - if(com.sijobe.spc.command.InstantMine.instantMiningEnabled) - { - this.blockHitDelay = 5; - return 1.1F; - } - return p_149737_5_; - } -} diff --git a/src/main/java/com/sijobe/spc/asm/make/Make.java b/src/main/java/com/sijobe/spc/asm/make/Make.java deleted file mode 100644 index 5508eec..0000000 --- a/src/main/java/com/sijobe/spc/asm/make/Make.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.sijobe.spc.asm.make; - -public class Make -{ - public float getBlockReachDistance() - { - return com.sijobe.spc.command.BlockReach.reachDistance; - } -} diff --git a/src/main/java/com/sijobe/spc/command/Noclip.java b/src/main/java/com/sijobe/spc/command/Noclip.java index efee43c..c8b122a 100644 --- a/src/main/java/com/sijobe/spc/command/Noclip.java +++ b/src/main/java/com/sijobe/spc/command/Noclip.java @@ -23,7 +23,7 @@ * * @author q3hardcore * @version 1.2 - * @status survived 1.7.2 update but can't see anything while inside blocks + * @status survived 1.7.2 update but can't see anything while inside blocks -> fixed */ @Command ( name = "noclip", From ea483e7812ca86ef9ce07b17620cb0463b9ef1c0 Mon Sep 17 00:00:00 2001 From: aucguy Date: Mon, 17 Nov 2014 20:35:53 -0600 Subject: [PATCH 08/20] Fixed path command --- resources/mcmod.info | 18 ------------------ src/main/java/com/sijobe/spc/command/Path.java | 5 ++--- .../java/com/sijobe/spc/wrapper/World.java | 11 +++++++++-- 3 files changed, 11 insertions(+), 23 deletions(-) delete mode 100644 resources/mcmod.info diff --git a/resources/mcmod.info b/resources/mcmod.info deleted file mode 100644 index 629fdee..0000000 --- a/resources/mcmod.info +++ /dev/null @@ -1,18 +0,0 @@ -[ -{ - "modid": "spc", - "name": "Single Player Commands", - "description": "Adds various commands to minecraft", - "version": "2.0", - "mcversion": "1.7.2", - "url": "", - "updateUrl": "", - "authorList": ["sijobe", "q3hardcore", "aucguy"], - "credits": "simo_415 for making this mod in the first place, - q3hardcore and Lamp-Post for adding some commands and - aucguy for updating the mod to minecraft 1.7.2", - "logoFile": "", - "screenshots": [], - "dependencies": [] -} -] diff --git a/src/main/java/com/sijobe/spc/command/Path.java b/src/main/java/com/sijobe/spc/command/Path.java index d0854d4..51bb82b 100644 --- a/src/main/java/com/sijobe/spc/command/Path.java +++ b/src/main/java/com/sijobe/spc/command/Path.java @@ -24,7 +24,7 @@ * * @author q3hardcore * @version 1.4 - * @status broken through 1.7.2 update + * @status broken through 1.7.2 update -> fixed */ @Command ( name = "path", @@ -83,7 +83,7 @@ public void execute(CommandSender sender, List params) throws CommandExceptio block = null; } - if (!player.getWorld().isValidBlockType(block) && block != null) { // isValidBlockType should be static + if (!player.getWorld().isValidBlockType(block)) { // isValidBlockType should be static throw new CommandException("Unknown block: " + args[0]); } @@ -216,7 +216,6 @@ private void makePath(Player player, PathData data) { * @param type - The type (ID) of the block */ private void setBlock(Player player, int i, int j, int k, Block type, int meta) { - //player.getWorld().getMinecraftWorld().func_94575_c(i, j, k, type); player.getWorld().setBlockDataWithMeta(new Coordinate(i, j, k), type, meta); } } diff --git a/src/main/java/com/sijobe/spc/wrapper/World.java b/src/main/java/com/sijobe/spc/wrapper/World.java index 96d49a2..d644b79 100644 --- a/src/main/java/com/sijobe/spc/wrapper/World.java +++ b/src/main/java/com/sijobe/spc/wrapper/World.java @@ -389,13 +389,20 @@ public void createExplosion(Player player, Coordinate coordinate, int size) { } /** - * Checks if the specified block type (block ID) is valid in Minecraft + * Checks if the specified block type is valid in Minecraft * * @param type - The type of block * @return True if it is a valid block type */ public boolean isValidBlockType(Block type) { - return Block.blockRegistry.containsKey(type); + if(type == null) + { + return false; + } + else + { + return Block.blockRegistry.getNameForObject(type) != null; + } } /** From 62d589de99c3491826a1bf9181586e4454b284f7 Mon Sep 17 00:00:00 2001 From: aucguy Date: Thu, 20 Nov 2014 22:04:23 -0600 Subject: [PATCH 09/20] Cleaned up core mod files --- .../com/sijobe/spc/asm/ClassTransformer.java | 69 ++++++++++++++ .../sijobe/spc/asm/CustomClassVisitor.java | 33 ------- .../java/com/sijobe/spc/asm/MethodHooker.java | 41 ++++++++ .../com/sijobe/spc/asm/MethodOverwriter.java | 95 ------------------- .../com/sijobe/spc/asm/MethodPrefixer.java | 38 ++++++++ .../com/sijobe/spc/asm/MethodReplacer.java | 40 ++++++++ .../com/sijobe/spc/asm/MethodTransformer.java | 61 ++++++++++++ .../java/com/sijobe/spc/asm/Processor.java | 66 +++++++++++++ .../java/com/sijobe/spc/asm/Replacer.java | 13 --- .../java/com/sijobe/spc/asm/SimpleHooked.java | 33 +++++++ .../java/com/sijobe/spc/asm/Transformer.java | 21 +--- .../java/com/sijobe/spc/command/Position.java | 1 + .../java/com/sijobe/spc/wrapper/World.java | 9 +- 13 files changed, 352 insertions(+), 168 deletions(-) create mode 100644 src/main/java/com/sijobe/spc/asm/ClassTransformer.java delete mode 100644 src/main/java/com/sijobe/spc/asm/CustomClassVisitor.java create mode 100644 src/main/java/com/sijobe/spc/asm/MethodHooker.java delete mode 100644 src/main/java/com/sijobe/spc/asm/MethodOverwriter.java create mode 100644 src/main/java/com/sijobe/spc/asm/MethodPrefixer.java create mode 100644 src/main/java/com/sijobe/spc/asm/MethodReplacer.java create mode 100644 src/main/java/com/sijobe/spc/asm/MethodTransformer.java create mode 100644 src/main/java/com/sijobe/spc/asm/Processor.java delete mode 100644 src/main/java/com/sijobe/spc/asm/Replacer.java create mode 100644 src/main/java/com/sijobe/spc/asm/SimpleHooked.java diff --git a/src/main/java/com/sijobe/spc/asm/ClassTransformer.java b/src/main/java/com/sijobe/spc/asm/ClassTransformer.java new file mode 100644 index 0000000..d19898b --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/ClassTransformer.java @@ -0,0 +1,69 @@ +package com.sijobe.spc.asm; + +import java.util.Map; +import java.util.HashMap; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +class ClassTransformer extends ClassVisitor +{ + protected String name; + protected Map methodTransformers; + + ClassTransformer(String name) + { + super(Opcodes.ASM4, new ClassWriter(Opcodes.ASM4)); + this.name = name; + this.methodTransformers = new HashMap(); + } + + String getApplicableClass() + { + return this.name; + } + + ClassWriter getWriter() + { + return (ClassWriter) this.cv; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) + { + MethodVisitor writer = super.visitMethod(access, name, desc, signature, exceptions); + String id = this.getApplicableClass()+":"+name+":"+desc; + + if(this.methodTransformers.containsKey(id)) + { + MethodTransformer transformer = this.methodTransformers.get(id); + transformer.injectMethodWriter(writer); + return transformer; + } + else + { + return writer; + } + } + + void registerMethodTransformer(MethodTransformer mt) throws IllegalArgumentException + { + String name = mt.getApplicableMethod(); + String clazz = name.split(":", 2)[0]; + if(!clazz.equals(this.getApplicableClass())) + { + throw(new IllegalArgumentException("MethodTransformer not of correct class")); + } + this.methodTransformers.put(mt.getApplicableMethod(), mt); + } + + void regsiterMethodTransformers(MethodTransformer[] mt) throws IllegalArgumentException + { + for(MethodTransformer i : mt) + { + this.registerMethodTransformer(i); + } + } +} diff --git a/src/main/java/com/sijobe/spc/asm/CustomClassVisitor.java b/src/main/java/com/sijobe/spc/asm/CustomClassVisitor.java deleted file mode 100644 index b4d73d1..0000000 --- a/src/main/java/com/sijobe/spc/asm/CustomClassVisitor.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.sijobe.spc.asm; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.Opcodes; - -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.MethodVisitor; - -public class CustomClassVisitor extends ClassVisitor -{ - String clazz; - - public CustomClassVisitor(String clazz, ClassWriter writer) - { - super(Opcodes.ASM4, writer); - this.clazz = clazz; - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) - { - MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); - String id = this.clazz+":"+name+":"+desc; - if(MethodOverwriter.replacers.containsKey(id)) - { - return (MethodVisitor) new MethodOverwriter(mv, id); - } - else - { - return mv; - } - } -} diff --git a/src/main/java/com/sijobe/spc/asm/MethodHooker.java b/src/main/java/com/sijobe/spc/asm/MethodHooker.java new file mode 100644 index 0000000..c92f1d1 --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/MethodHooker.java @@ -0,0 +1,41 @@ +package com.sijobe.spc.asm; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.objectweb.asm.MethodVisitor; + +abstract class MethodHooker extends MethodTransformer +{ + protected Method method; + + MethodHooker(String id, Method method) throws IllegalArgumentException + { + super(id); + if(!Modifier.isStatic(method.getModifiers())) + { + throw(new IllegalArgumentException("MethodTransformer not of correct class")); + } + this.method = method; + } + + protected abstract MethodVisitor getWriter(); + + @Override + public void visitCode() + { + try { + this.method.invoke(null, this.getWriter()); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/sijobe/spc/asm/MethodOverwriter.java b/src/main/java/com/sijobe/spc/asm/MethodOverwriter.java deleted file mode 100644 index cabfbb2..0000000 --- a/src/main/java/com/sijobe/spc/asm/MethodOverwriter.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.sijobe.spc.asm; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -public class MethodOverwriter extends MethodVisitor -{ - static Set clazzes; - static Map replacers; - - static void init() - { - clazzes = new HashSet(); - replacers = new HashMap(); - for(Method method : MethodOverwriter.class.getDeclaredMethods()) - { - if(method.isAnnotationPresent(Replacer.class)) - { - String annotation = method.getAnnotation(Replacer.class).value(); - System.out.println("found replacement for "+annotation); - String clazz = annotation.split(":", 2)[0]; - if(!clazzes.contains(clazz)) - { - clazzes.add(clazz); - } - replacers.put(annotation, method); - } - } - } - - MethodVisitor writer; - String id; - - public MethodOverwriter(MethodVisitor writer, String id) - { - super(Opcodes.ASM4); - this.writer = writer; - this.id = id; - } - - @Override - public void visitCode() - { - try { - replacers.get(this.id).invoke(this); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvocationTargetException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @Replacer("net.minecraft.client.multiplayer.PlayerControllerMP:getBlockReachDistance:()F") - protected void getBlockReachDistance() - { - MethodVisitor mv = this.writer; - mv.visitCode(); - mv.visitFieldInsn(Opcodes.GETSTATIC, "com/sijobe/spc/command/BlockReach", "reachDistance", "F"); - mv.visitInsn(Opcodes.FRETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - - @Replacer("net.minecraft.client.renderer.ItemRenderer:renderInsideOfBlock:(FLnet/minecraft/util/IIcon;)V") - protected void renderInsideOfBlock() - { - MethodVisitor mv = this.writer; - mv.visitCode(); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/wrapper/Minecraft", "getMinecraft", "()Lnet/minecraft/client/Minecraft;"); - mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/client/Minecraft", "thePlayer", "Lnet/minecraft/client/entity/EntityClientPlayerMP;"); - mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/client/entity/EntityClientPlayerMP", "noClip", "Z"); - Label l0 = new Label(); - mv.visitJumpInsn(Opcodes.IFEQ, l0); - mv.visitLdcInsn(new Float("1.1")); - mv.visitInsn(Opcodes.RETURN); - mv.visitLabel(l0); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - this.mv = mv; //so the MethodWriter instance gets its visit methods called - } -} diff --git a/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java b/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java new file mode 100644 index 0000000..944abbb --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java @@ -0,0 +1,38 @@ +package com.sijobe.spc.asm; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.objectweb.asm.MethodVisitor; + +class MethodPrefixer extends MethodHooker +{ + MethodPrefixer(String id, Method method) throws IllegalArgumentException + { + super(id, method); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + @interface Hook + { + String value(); + } + + @Override + void injectMethodWriter(MethodVisitor mv) + { + this.mv = mv; + } + + @Override + protected MethodVisitor getWriter() + { + return this.mv; + } +} diff --git a/src/main/java/com/sijobe/spc/asm/MethodReplacer.java b/src/main/java/com/sijobe/spc/asm/MethodReplacer.java new file mode 100644 index 0000000..86c3564 --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/MethodReplacer.java @@ -0,0 +1,40 @@ +package com.sijobe.spc.asm; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.objectweb.asm.MethodVisitor; + +class MethodReplacer extends MethodHooker +{ + protected MethodVisitor writer; + + MethodReplacer(String id, Method method) throws IllegalArgumentException + { + super(id, method); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + @interface Hook + { + String value(); + } + + @Override + void injectMethodWriter(MethodVisitor mv) + { + this.writer = mv; + } + + @Override + protected MethodVisitor getWriter() + { + return this.writer; + } +} diff --git a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java new file mode 100644 index 0000000..e072966 --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java @@ -0,0 +1,61 @@ +package com.sijobe.spc.asm; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.LinkedList; +import java.util.List; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +abstract class MethodTransformer extends MethodVisitor +{ + String id; + + MethodTransformer(String id) + { + super(Opcodes.ASM4); + this.id = id; + } + + String getApplicableMethod() + { + return this.id; + } + + abstract void injectMethodWriter(MethodVisitor mv); + + static MethodTransformer[] generateFromFunctions(Class clazz) + { + List modifiers = new LinkedList(); + for(Method method : clazz.getDeclaredMethods()) + { + if(Modifier.isStatic(method.getModifiers())) + { + System.out.println(method.getName()+":"); + for(Annotation i : method.getDeclaredAnnotations()) + { + System.out.println(i); + } + if(method.isAnnotationPresent(MethodReplacer.Hook.class)) + { + String annotation = method.getAnnotation(MethodReplacer.Hook.class).value(); + System.out.println("found replacement for "+annotation); + String cl = annotation.split(":", 2)[0]; + modifiers.add(new MethodReplacer(annotation, method)); + } + else if(method.isAnnotationPresent(MethodPrefixer.Hook.class)) + { + String annotation = method.getAnnotation(MethodPrefixer.Hook.class).value(); + System.out.println("found prefix for "+annotation); + String cl = annotation.split(":", 2)[0]; + modifiers.add(new MethodPrefixer(annotation, method)); + } + } + } + + MethodTransformer[] r = new MethodTransformer[modifiers.size()]; + return modifiers.toArray(r); + } +} diff --git a/src/main/java/com/sijobe/spc/asm/Processor.java b/src/main/java/com/sijobe/spc/asm/Processor.java new file mode 100644 index 0000000..adbc965 --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/Processor.java @@ -0,0 +1,66 @@ +package com.sijobe.spc.asm; + +import java.util.Map; +import java.util.HashMap; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; + +class Processor +{ + private static Processor instance = new Processor(); + + static Processor getInstance() + { + return instance; + } + + protected Map classTransformers; + + Processor() + { + this.classTransformers = new HashMap(); + } + + byte[] process(String name, byte[] data) + { + if(this.classTransformers.containsKey(name)) + { + ClassTransformer transformer = this.classTransformers.get(name); + this.classTransformers.remove(name); + ClassReader reader = new ClassReader(data); + reader.accept(transformer, 0); + return transformer.getWriter().toByteArray(); + } + else + { + return data; + } + } + + void registerClassTransformer(ClassTransformer ct) + { + this.classTransformers.put(ct.getApplicableClass(), ct); + } + + void registerMethodTransformer(MethodTransformer mt) + { + String id = mt.getApplicableMethod(); + String clazz = id.split(":", 2)[0]; + if(!this.classTransformers.containsKey(clazz)) + { + this.classTransformers.put(clazz, new ClassTransformer(clazz)); + } + this.classTransformers.get(clazz).registerMethodTransformer(mt); + } + + void registerMethodTransformers(MethodTransformer[] mt) + { + for(MethodTransformer i : mt) + { + this.registerMethodTransformer(i); + } + } +} diff --git a/src/main/java/com/sijobe/spc/asm/Replacer.java b/src/main/java/com/sijobe/spc/asm/Replacer.java deleted file mode 100644 index 33a4d6c..0000000 --- a/src/main/java/com/sijobe/spc/asm/Replacer.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.sijobe.spc.asm; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@interface Replacer -{ - String value(); -} diff --git a/src/main/java/com/sijobe/spc/asm/SimpleHooked.java b/src/main/java/com/sijobe/spc/asm/SimpleHooked.java new file mode 100644 index 0000000..8262416 --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/SimpleHooked.java @@ -0,0 +1,33 @@ +package com.sijobe.spc.asm; + +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +public class SimpleHooked +{ + @MethodReplacer.Hook("net.minecraft.client.multiplayer.PlayerControllerMP:getBlockReachDistance:()F") + public static void getBlockReachDistance(MethodVisitor mv) + { + mv.visitCode(); + mv.visitFieldInsn(Opcodes.GETSTATIC, "com/sijobe/spc/command/BlockReach", "reachDistance", "F"); + mv.visitInsn(Opcodes.FRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + + @MethodPrefixer.Hook("net.minecraft.client.renderer.ItemRenderer:renderInsideOfBlock:(FLnet/minecraft/util/IIcon;)V") + public static void renderInsideOfBlock(MethodVisitor mv) + { + mv.visitCode(); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/wrapper/Minecraft", "getMinecraft", "()Lnet/minecraft/client/Minecraft;"); + mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/client/Minecraft", "thePlayer", "Lnet/minecraft/client/entity/EntityClientPlayerMP;"); + mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/client/entity/EntityClientPlayerMP", "noClip", "Z"); + Label l0 = new Label(); + mv.visitJumpInsn(Opcodes.IFEQ, l0); + mv.visitLdcInsn(new Float("1.1")); + mv.visitInsn(Opcodes.RETURN); + mv.visitLabel(l0); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + } +} diff --git a/src/main/java/com/sijobe/spc/asm/Transformer.java b/src/main/java/com/sijobe/spc/asm/Transformer.java index 5b53c09..030cca3 100644 --- a/src/main/java/com/sijobe/spc/asm/Transformer.java +++ b/src/main/java/com/sijobe/spc/asm/Transformer.java @@ -12,29 +12,12 @@ public class Transformer implements IClassTransformer { public Transformer() { - MethodOverwriter.init(); + Processor.getInstance().registerMethodTransformers(MethodTransformer.generateFromFunctions(SimpleHooked.class)); } @Override public byte[] transform(String name, String transformedName, byte[] basicClass) { - if(MethodOverwriter.clazzes.contains(name)) //TODO do obfucated names - { - System.out.println("modifiying "+name); - return this.applyPatch(name, basicClass); - } - else - { - return basicClass; - } - } - - protected byte[] applyPatch(String name, byte[] orginal) - { - ClassWriter writer = new ClassWriter(Opcodes.ASM4); - ClassVisitor visitor = new CustomClassVisitor(name, writer); - ClassReader reader = new ClassReader(orginal); - reader.accept(visitor, 0); - return writer.toByteArray(); + return Processor.getInstance().process(name, basicClass); } } diff --git a/src/main/java/com/sijobe/spc/command/Position.java b/src/main/java/com/sijobe/spc/command/Position.java index b7df089..51174f6 100644 --- a/src/main/java/com/sijobe/spc/command/Position.java +++ b/src/main/java/com/sijobe/spc/command/Position.java @@ -13,6 +13,7 @@ * * @author simo_415 * @version 1.0 + * @status survived 1.7.2 update */ @Command ( name = "pos", diff --git a/src/main/java/com/sijobe/spc/wrapper/World.java b/src/main/java/com/sijobe/spc/wrapper/World.java index d644b79..d80c3b9 100644 --- a/src/main/java/com/sijobe/spc/wrapper/World.java +++ b/src/main/java/com/sijobe/spc/wrapper/World.java @@ -395,14 +395,7 @@ public void createExplosion(Player player, Coordinate coordinate, int size) { * @return True if it is a valid block type */ public boolean isValidBlockType(Block type) { - if(type == null) - { - return false; - } - else - { - return Block.blockRegistry.getNameForObject(type) != null; - } + return Block.blockRegistry.getNameForObject(type) != null; } /** From d19febca71ef024a5142bb4c338d68a4b6a28b8a Mon Sep 17 00:00:00 2001 From: aucguy Date: Sat, 22 Nov 2014 21:05:30 -0600 Subject: [PATCH 10/20] fixed prefixslash command --- .../com/sijobe/spc/asm/SlashPrefixer.java | 49 +++++++++++++++++++ .../java/com/sijobe/spc/asm/Transformer.java | 1 + .../com/sijobe/spc/command/PrefixSlash.java | 8 ++- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/sijobe/spc/asm/SlashPrefixer.java diff --git a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java new file mode 100644 index 0000000..78306b7 --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java @@ -0,0 +1,49 @@ +package com.sijobe.spc.asm; + +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; + +import com.sijobe.spc.command.PrefixSlash; +import com.sun.xml.internal.ws.org.objectweb.asm.Opcodes; + +public class SlashPrefixer extends MethodTransformer +{ + + SlashPrefixer() + { + super("net.minecraft.network.NetHandlerPlayServer:processChatMessage:(Lnet/minecraft/network/play/client/C01PacketChatMessage;)V"); + } + + @Override + void injectMethodWriter(MethodVisitor mv) + { + this.mv = mv; + } + + @Override + public void visitLdcInsn(Object cst) + { + if(!cst.equals("/")) + { + this.mv.visitLdcInsn(cst); + } + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc) + { + if(opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/lang/String") && name.equals("startsWith") && desc.equals("(Ljava/lang/String;)Z")) + { + this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/asm/SlashPrefixer", "isCommand", "(Ljava/lang/String;)Z"); + } + else + { + this.mv.visitMethodInsn(opcode, owner, name, desc); + } + } + + public static boolean isCommand(String s) + { + return s.startsWith("/") || PrefixSlash.prefixSlashEnabled; + } +} diff --git a/src/main/java/com/sijobe/spc/asm/Transformer.java b/src/main/java/com/sijobe/spc/asm/Transformer.java index 030cca3..f553348 100644 --- a/src/main/java/com/sijobe/spc/asm/Transformer.java +++ b/src/main/java/com/sijobe/spc/asm/Transformer.java @@ -13,6 +13,7 @@ public class Transformer implements IClassTransformer public Transformer() { Processor.getInstance().registerMethodTransformers(MethodTransformer.generateFromFunctions(SimpleHooked.class)); + Processor.getInstance().registerMethodTransformer(new SlashPrefixer()); } @Override diff --git a/src/main/java/com/sijobe/spc/command/PrefixSlash.java b/src/main/java/com/sijobe/spc/command/PrefixSlash.java index c849517..a5c6156 100644 --- a/src/main/java/com/sijobe/spc/command/PrefixSlash.java +++ b/src/main/java/com/sijobe/spc/command/PrefixSlash.java @@ -16,6 +16,7 @@ * * @author q3hardcore * @version 1.0 + * @status broken through 1.7.2 update -> fixed */ @Command ( name = "prefixslash", @@ -25,7 +26,8 @@ enabled = true ) public class PrefixSlash extends StandardCommand { - + public static boolean prefixSlashEnabled = false; + @Override public boolean isEnabled() { return Minecraft.isSinglePlayer(); @@ -35,7 +37,8 @@ public boolean isEnabled() { public void execute(CommandSender sender, List params) throws CommandException { Player player = CommandBase.getSenderAsPlayer(sender); Settings config = super.loadSettings(player); - boolean prefixSlash = config.getBoolean("prefixSlash", true); + //boolean prefixSlash = config.getBoolean("prefixSlash", true); + boolean prefixSlash = prefixSlashEnabled; if (params.size() == 0) { prefixSlash ^= true; } else { @@ -43,6 +46,7 @@ public void execute(CommandSender sender, List params) throws CommandExceptio } config.set("prefixSlash", prefixSlash); super.saveSettings(player); + prefixSlashEnabled = prefixSlash; player.sendChatMessage("Slash prefixing is now " + FontColour.AQUA + (prefixSlash ? "enabled" : "disabled")); } From fc8ed48bc26b0f866dcfe453ff16c8ff47824b31 Mon Sep 17 00:00:00 2001 From: aucguy Date: Sat, 22 Nov 2014 22:32:39 -0600 Subject: [PATCH 11/20] fixed setspeed command --- .../java/com/sijobe/spc/command/SetSpeed.java | 185 ++++++++---------- .../com/sijobe/spc/util/AccessHelper.java | 8 + 2 files changed, 92 insertions(+), 101 deletions(-) diff --git a/src/main/java/com/sijobe/spc/command/SetSpeed.java b/src/main/java/com/sijobe/spc/command/SetSpeed.java index 1c34bc7..8aafe5f 100644 --- a/src/main/java/com/sijobe/spc/command/SetSpeed.java +++ b/src/main/java/com/sijobe/spc/command/SetSpeed.java @@ -1,6 +1,7 @@ package com.sijobe.spc.command; import com.sijobe.spc.core.IPlayerSP; +import com.sijobe.spc.util.AccessHelper; import com.sijobe.spc.util.FontColour; import com.sijobe.spc.util.Settings; import com.sijobe.spc.validation.Parameter; @@ -14,6 +15,10 @@ import java.util.List; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerCapabilities; + /** * The set speed command allows you to set the speed that the player moves at. * By default the player speed is 1 where player speed 2 is twice as fast, @@ -21,113 +26,91 @@ * * @author simo_415 * @version 1.1 - * @status broken through 1.7.2 update + * @status broken through 1.7.2 update -> fixed */ @Command ( - name = "setspeed", - description = "Sets the players speed to the value specified", - example = "2", - videoURL = "http://www.youtube.com/watch?v=G48upLnQr-s", - version = "1.3", - enabled = true -) -public class SetSpeed extends StandardCommand implements IPlayerSP { - /** - * The parameters of the command - */ - private static final Parameters PARAMETERS = new Parameters ( - new Parameter[] { - new ParameterString("", false), - } - ); + name = "setspeed", + description = "Sets the players speed to the value specified", + example = "2", + videoURL = "http://www.youtube.com/watch?v=G48upLnQr-s", + version = "1.3", + enabled = true + ) +public class SetSpeed extends StandardCommand { + /** + * The parameters of the command + */ + private static final Parameters PARAMETERS = new Parameters ( + new Parameter[] { + new ParameterString("", false), + } + ); - /** - * The default speed multiplier that the player moves - */ - private static final double DEFAULT_SPEED = 1; - - /** - * The key that is saved into the config - */ - private static final String CONFIG_KEY = "speed"; + /** + * The default speed multiplier that the player moves + */ + private static final double DEFAULT_SPEED = 1; - /** - * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) - */ - @Override - public void execute(CommandSender sender, List params) throws CommandException { - Settings config = super.loadSettings(super.getSenderAsPlayer(sender)); - if (((String)params.get(0)).equalsIgnoreCase("reset")) { - config.set(CONFIG_KEY, DEFAULT_SPEED); - } else { - try { - config.set(CONFIG_KEY, Double.parseDouble((String)params.get(0))); - } catch (Exception e) { - throw new CommandException("Could not parse " + (String)params.get(0) + " as a speed."); - } - } - config.save(); - sender.sendMessageToPlayer("Player speed set to " + FontColour.AQUA - + config.getDouble(CONFIG_KEY, DEFAULT_SPEED) + FontColour.WHITE + "x normal speed"); - } + /** + * The key that is saved into the config + */ + private static final String CONFIG_KEY = "speed"; - /** - * @see com.sijobe.spc.wrapper.CommandBase#getParameters() - */ - @Override - public Parameters getParameters() { - return PARAMETERS; - } + /** + * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) + */ + @Override + public void execute(CommandSender sender, List params) throws CommandException { + Settings config = super.loadSettings(super.getSenderAsPlayer(sender)); + if (((String)params.get(0)).equalsIgnoreCase("reset")) { + config.set(CONFIG_KEY, DEFAULT_SPEED); + } else { + try { + float speed = Float.parseFloat((String)params.get(0)); + config.set(CONFIG_KEY, speed); + try { + PlayerCapabilities capabilities = super.getSenderAsPlayer(sender).getMinecraftPlayer().capabilities; + AccessHelper.setFloat(capabilities, "walkSpeed", speed/10); + AccessHelper.setFloat(capabilities, "flySpeed", speed/20); + super.getSenderAsPlayer(sender).getMinecraftPlayer().sendPlayerAbilities(); + } catch (NoSuchFieldException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } catch (NumberFormatException e) { + throw new CommandException("Could not parse " + (String)params.get(0) + " as a speed."); + } + } + config.save(); - /** - * @see com.sijobe.spc.core.IHook#init(java.lang.Object[]) - */ - @Override - public void init(Object... params) { - } + sender.sendMessageToPlayer("Player speed set to " + FontColour.AQUA + + config.getDouble(CONFIG_KEY, DEFAULT_SPEED) + FontColour.WHITE + "x normal speed"); + } - /** - * @see com.sijobe.spc.core.IPlayerMP#onTick(com.sijobe.spc.wrapper.Player) - */ - @Override - public void onTick(Player player) { - } - - /** - * Only enabled in single player since this is a client-side mod - * - * @see com.sijobe.spc.wrapper.CommandBase#isEnabled() - */ - @Override - public boolean isEnabled() { - return Minecraft.isSinglePlayer(); - } + /** + * @see com.sijobe.spc.wrapper.CommandBase#getParameters() + */ + @Override + public Parameters getParameters() { + return PARAMETERS; + } - /** - * @see com.sijobe.spc.core.IPlayerSP#movePlayer(float, float, float) - */ - @Override - public void movePlayer(Player player, float forward, float strafe, float speed) { - Double pspeed = super.loadSettings(player).getDouble(CONFIG_KEY, DEFAULT_SPEED); - if (pspeed == null || pspeed == 1) { - return; - } - pspeed--; - double direction = Math.sqrt((forward * forward) + (strafe * strafe)); - if (direction < 0.01F) { - return; - } - if (direction < 1.0D) { - direction = 1D; - } - direction = speed / direction; - forward *= direction; - strafe *= direction; - double f4 = Math.sin(player.getYaw() * Math.PI / 180.0F); - double f5 = Math.cos(player.getYaw() * Math.PI / 180.0F); - Coordinate motion = player.getMotion(); - double motionx = forward * f5 - strafe * f4; - double motionz = strafe * f5 + forward * f4; - player.setMotion(new Coordinate(motion.getX() + motionx * pspeed, motion.getY(), motion.getZ() + motionz * pspeed)); - } + /** + * Only enabled in single player since this is a client-side mod + * + * @see com.sijobe.spc.wrapper.CommandBase#isEnabled() + */ + @Override + public boolean isEnabled() { + return Minecraft.isSinglePlayer(); + } } diff --git a/src/main/java/com/sijobe/spc/util/AccessHelper.java b/src/main/java/com/sijobe/spc/util/AccessHelper.java index a7057d5..c2185c5 100644 --- a/src/main/java/com/sijobe/spc/util/AccessHelper.java +++ b/src/main/java/com/sijobe/spc/util/AccessHelper.java @@ -11,4 +11,12 @@ public static void setInt(Object obj, String name, int value) throws NoSuchField field.setAccessible(true); field.setInt(obj, value); } + + public static void setFloat(Object obj, String name, float value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException + { + Class clazz = obj.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + field.setFloat(obj, value); + } } From fc2988237c23b912f310f1841b17bac318a662bc Mon Sep 17 00:00:00 2001 From: aucguy Date: Sun, 23 Nov 2014 17:40:46 -0600 Subject: [PATCH 12/20] fixed spawnportal command --- .../com/sijobe/spc/command/SpawnPortal.java | 86 +++++++++++++++---- .../java/com/sijobe/spc/wrapper/Blocks.java | 8 ++ .../resources/com/sijobe/spc/asm/spc_at.txt | 3 +- 3 files changed, 81 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/sijobe/spc/command/SpawnPortal.java b/src/main/java/com/sijobe/spc/command/SpawnPortal.java index 7befdc2..bdb92c6 100644 --- a/src/main/java/com/sijobe/spc/command/SpawnPortal.java +++ b/src/main/java/com/sijobe/spc/command/SpawnPortal.java @@ -7,7 +7,12 @@ import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Coordinate; import com.sijobe.spc.wrapper.Player; +import com.sijobe.spc.wrapper.World; +import com.sijobe.spc.wrapper.Blocks; + import java.lang.reflect.Method; + +import net.minecraft.block.BlockEndPortal; import net.minecraft.entity.boss.EntityDragon; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.MathHelper; @@ -48,22 +53,9 @@ public void execute(CommandSender sender, List params) throws CommandExceptio if (portalType.equalsIgnoreCase("end")) { Coordinate coord = player.getPosition(); int x = MathHelper.floor_double(coord.getX()); + int y = MathHelper.floor_double(coord.getY()+1); int z = MathHelper.floor_double(coord.getZ()); - EntityDragon entityDragon = new EntityDragon(player.getWorld().getMinecraftWorld()); // EntityDragon - try { - Class[] args = new Class[]{Integer.TYPE, Integer.TYPE}; - Method method; - try { - method = entityDragon.getClass().getDeclaredMethod("c", args); - } catch (NoSuchMethodException nsme) { - method = entityDragon.getClass().getDeclaredMethod("createEnderPortal", args); - } - method.setAccessible(true); - method.invoke(entityDragon, new Object[]{x, z}); - } catch (Throwable t) { - t.printStackTrace(); - throw new CommandException("End portal generation is currently unsupported."); - } + this.createEnderPortal(x, z, y, new World(sender.getMinecraftISender().getEntityWorld())); } else if (portalType.equalsIgnoreCase("nether")) { EntityPlayerMP playerEntity; if(player.getMinecraftPlayer() instanceof EntityPlayerMP) { @@ -84,4 +76,68 @@ public void execute(CommandSender sender, List params) throws CommandExceptio public Parameters getParameters() { return PARAMETERS; } + + /** + * taken from EntityDragon.createEnderPortal + * Creates the ender portal leading back to the normal world after defeating the enderdragon. + */ + public void createEnderPortal(int x, int z, int level, World worldObj) + { + //byte level = 64; //used to be this in minecraft method + BlockEndPortal.field_149948_a = true; //so dragon eggs don't despawn + byte radius = 4; + + for (int coordy = level - 1; coordy <= level + 32; ++coordy) + { + for (int coordx = x - radius; coordx <= x + radius; ++coordx) + { + for (int coordz = z - radius; coordz <= z + radius; ++coordz) + { + double offsetx = (double)(coordx - x); + double offsetz = (double)(coordz - z); + double dist = offsetx * offsetx + offsetz * offsetz; + + //sqrt isn't used for distance calculations because + //sqrt(x1*x1+y2*y2) < sqrt(x2*x2+y2*y2) will have the same result as + //x1*x1+y2*y2 < x2*x2+y2*y2 + //this takes advantage of the multiplication property of equality + + if (dist <= ((double)radius - 0.5D) * ((double)radius - 0.5D)) //must be within distance + { + if (coordy < level) //lower level + { + //-1 so one block smaller radius + if (dist <= ((double)(radius - 1) - 0.5D) * ((double)(radius - 1) - 0.5D)) //right under end portal + { + worldObj.setBlock(new Coordinate(coordx, coordy, coordz), Blocks.bedrock); + } + } + else if (coordy > level) //above frame + { + worldObj.setBlock(new Coordinate(coordx, coordy, coordz), Blocks.air); + } + else if (dist > ((double)(radius - 1) - 0.5D) * ((double)(radius - 1) - 0.5D)) //forms the end portal ring + { + worldObj.setBlock(new Coordinate(coordx, coordy, coordz), Blocks.bedrock); + } + else //the actual end portal (only occurs on the level) + { + worldObj.setBlock(new Coordinate(coordx, coordy, coordz), Blocks.end_portal); + } + } + } + } + } + + worldObj.setBlock(new Coordinate(x, level + 0, z), Blocks.bedrock); //the column + worldObj.setBlock(new Coordinate(x, level + 1, z), Blocks.bedrock); + worldObj.setBlock(new Coordinate(x, level + 2, z), Blocks.bedrock); + worldObj.setBlock(new Coordinate(x - 1, level + 2, z), Blocks.torch); //torches on the clumn + worldObj.setBlock(new Coordinate(x + 1, level + 2, z), Blocks.torch); + worldObj.setBlock(new Coordinate(x, level + 2, z - 1), Blocks.torch); + worldObj.setBlock(new Coordinate(x, level + 2, z + 1), Blocks.torch); + worldObj.setBlock(new Coordinate(x, level + 3, z), Blocks.bedrock); //another block for the column + worldObj.setBlock(new Coordinate(x, level + 4, z), Blocks.dragon_egg); //tops it off + BlockEndPortal.field_149948_a = false; //reset this field + } } diff --git a/src/main/java/com/sijobe/spc/wrapper/Blocks.java b/src/main/java/com/sijobe/spc/wrapper/Blocks.java index ccb5af7..b9be7c4 100644 --- a/src/main/java/com/sijobe/spc/wrapper/Blocks.java +++ b/src/main/java/com/sijobe/spc/wrapper/Blocks.java @@ -5,11 +5,19 @@ public class Blocks public static Block air; public static Block fire; public static Block glass; + public static Block bedrock; + public static Block end_portal; + public static Block torch; + public static Block dragon_egg; static void init() { air = (Block) Block.blockRegistry.getObject("minecraft:air"); fire = (Block) Block.blockRegistry.getObject("minecraft:fire"); glass = (Block) Block.blockRegistry.getObject("minecraft:glass"); + bedrock = (Block) Block.blockRegistry.getObject("minecraft:bedrock"); + end_portal = (Block) Block.blockRegistry.getObject("minecraft:end_portal"); + torch = (Block) Block.blockRegistry.getObject("minecraft:torch"); + dragon_egg = (Block) Block.blockRegistry.getObject("minecraft:dragon_egg"); } } diff --git a/src/main/resources/com/sijobe/spc/asm/spc_at.txt b/src/main/resources/com/sijobe/spc/asm/spc_at.txt index c5675b7..2ef3da6 100644 --- a/src/main/resources/com/sijobe/spc/asm/spc_at.txt +++ b/src/main/resources/com/sijobe/spc/asm/spc_at.txt @@ -1 +1,2 @@ -public int blockHitDelay \ No newline at end of file +#public int blockHitDelay +#public net.minecraft.entity.Player.PlayerCapabilities walkSpeed \ No newline at end of file From c4120b267c294fabdb4931df4d4ed849a3a48c65 Mon Sep 17 00:00:00 2001 From: aucguy Date: Mon, 24 Nov 2014 21:38:57 -0600 Subject: [PATCH 13/20] fixed useportal command and removed debugging statements --- .../com/sijobe/spc/asm/MethodTransformer.java | 5 ----- .../com/sijobe/spc/command/InstantMine.java | 2 -- .../java/com/sijobe/spc/command/MovePlayer.java | 1 - .../java/com/sijobe/spc/command/Noclip.java | 3 +-- .../java/com/sijobe/spc/command/UsePortal.java | 17 +++++++++-------- .../java/com/sijobe/spc/wrapper/Player.java | 1 + 6 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java index e072966..09a5e1a 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java +++ b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java @@ -33,11 +33,6 @@ static MethodTransformer[] generateFromFunctions(Class clazz) { if(Modifier.isStatic(method.getModifiers())) { - System.out.println(method.getName()+":"); - for(Annotation i : method.getDeclaredAnnotations()) - { - System.out.println(i); - } if(method.isAnnotationPresent(MethodReplacer.Hook.class)) { String annotation = method.getAnnotation(MethodReplacer.Hook.class).value(); diff --git a/src/main/java/com/sijobe/spc/command/InstantMine.java b/src/main/java/com/sijobe/spc/command/InstantMine.java index e373696..c22c55d 100644 --- a/src/main/java/com/sijobe/spc/command/InstantMine.java +++ b/src/main/java/com/sijobe/spc/command/InstantMine.java @@ -66,13 +66,11 @@ public void init(Object... params) {} @Override public float getBreakSpeed(Player player, Block block, int metadata, float orginalSpeed, int x, int y, int z) { - System.out.println("getting break speed..."); return instantMiningEnabled ? 50000000.0F : orginalSpeed; } @Override public void onBreakBroken(int x, int y, int z, World world, Block block, int metadata, Player player) { - System.out.println("setting blockHitDelay"); try { AccessHelper.setInt(Minecraft.getMinecraft().playerController, "blockHitDelay", 5); } catch (NoSuchFieldException e) { diff --git a/src/main/java/com/sijobe/spc/command/MovePlayer.java b/src/main/java/com/sijobe/spc/command/MovePlayer.java index 282cc04..426ec2d 100644 --- a/src/main/java/com/sijobe/spc/command/MovePlayer.java +++ b/src/main/java/com/sijobe/spc/command/MovePlayer.java @@ -46,7 +46,6 @@ public void execute(CommandSender sender, List params) throws CommandExceptio Player player = super.getSenderAsPlayer(sender); Coordinate c = player.getPosition(); int distance = 0; - System.out.println(params.get(0).getClass()); if(params.get(0) instanceof Integer){ distance = (Integer)params.get(0); } diff --git a/src/main/java/com/sijobe/spc/command/Noclip.java b/src/main/java/com/sijobe/spc/command/Noclip.java index c8b122a..0fe8cdb 100644 --- a/src/main/java/com/sijobe/spc/command/Noclip.java +++ b/src/main/java/com/sijobe/spc/command/Noclip.java @@ -38,8 +38,7 @@ public class Noclip extends StandardCommand { public void execute(CommandSender sender, List params) throws CommandException { Player player = CommandBase.getSenderAsPlayer(sender); - System.out.println(player.getUsername() + " " + MinecraftServer.getServer().getServerOwner()); - /*if(!player.getUsername().equals(MinecraftServer.getServer().getServerOwner())) { + /*if(!player.getUsername().equals(MinecraftServer.getServer().getServerOwner())) { throw new CommandException("Must be server host"); }*/ if(!player.getMinecraftPlayer().capabilities.isFlying && !player.getMinecraftPlayer().noClip) { diff --git a/src/main/java/com/sijobe/spc/command/UsePortal.java b/src/main/java/com/sijobe/spc/command/UsePortal.java index a55fe34..5d97776 100644 --- a/src/main/java/com/sijobe/spc/command/UsePortal.java +++ b/src/main/java/com/sijobe/spc/command/UsePortal.java @@ -7,6 +7,7 @@ import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; +import com.sijobe.spc.wrapper.Entity; import com.sijobe.spc.wrapper.Player; /** @@ -41,14 +42,14 @@ public void execute(CommandSender sender, List params) throws CommandExceptio Player player = super.getSenderAsPlayer(sender); String type = (String)params.get(0); if (type.equalsIgnoreCase("normal")) { - player.changeDimension(DIMENSION_NORMAL); - } else if (type.equalsIgnoreCase("nether")) { - player.changeDimension(DIMENSION_NETHER); - } else if (type.equalsIgnoreCase("end")) { - player.changeDimension(DIMENSION_END); - } else { - throw new CommandException("Unknown dimension specified"); - } + player.changeDimension(DIMENSION_NORMAL); + } else if (type.equalsIgnoreCase("nether")) { + player.changeDimension(DIMENSION_NETHER); + } else if (type.equalsIgnoreCase("end")) { + player.changeDimension(DIMENSION_END); + } else { + throw new CommandException("Unknown dimension specified"); + } } @Override diff --git a/src/main/java/com/sijobe/spc/wrapper/Player.java b/src/main/java/com/sijobe/spc/wrapper/Player.java index 3d26b9b..87d78b7 100644 --- a/src/main/java/com/sijobe/spc/wrapper/Player.java +++ b/src/main/java/com/sijobe/spc/wrapper/Player.java @@ -485,6 +485,7 @@ public void addPotionEffect(int id, int duration, int strength) { */ public void changeDimension(int dimension) { player.travelToDimension(dimension); + player.timeUntilPortal = player.getPortalCooldown(); } /** From 4c4f600633ca4366fbedbc553375615c1ee449a8 Mon Sep 17 00:00:00 2001 From: aucguy Date: Fri, 5 Dec 2014 23:15:48 -0600 Subject: [PATCH 14/20] Added multiplayer support and added ids for give command --- src/main/java/com/sijobe/spc/ModSpc.java | 60 ++++-- .../com/sijobe/spc/asm/MethodTransformer.java | 1 - .../java/com/sijobe/spc/asm/Processor.java | 3 - .../java/com/sijobe/spc/asm/SimpleHooked.java | 7 +- .../com/sijobe/spc/asm/SlashPrefixer.java | 2 +- .../java/com/sijobe/spc/asm/SpcCoreMod.java | 4 + .../java/com/sijobe/spc/asm/Transformer.java | 11 +- .../com/sijobe/spc/command/Achievement.java | 9 +- .../java/com/sijobe/spc/command/Bind.java | 187 ++++++++++-------- .../com/sijobe/spc/command/BlockReach.java | 58 +++--- .../java/com/sijobe/spc/command/DoDrops.java | 3 +- .../com/sijobe/spc/command/InstantMine.java | 124 ++++++------ .../java/com/sijobe/spc/command/Keypress.java | 42 ++++ .../java/com/sijobe/spc/command/Light.java | 74 +++---- .../com/sijobe/spc/command/LongerLegs.java | 30 ++- .../java/com/sijobe/spc/command/Macro.java | 178 +++++++++++++---- .../java/com/sijobe/spc/command/Noclip.java | 67 ++++--- .../com/sijobe/spc/command/PrefixSlash.java | 57 ++++-- .../java/com/sijobe/spc/command/SetSpeed.java | 12 -- .../java/com/sijobe/spc/command/Sudo.java | 2 +- .../java/com/sijobe/spc/core/Constants.java | 8 +- .../java/com/sijobe/spc/core/SPCLoader.java | 6 +- .../java/com/sijobe/spc/network/Config.java | 34 ++++ .../spc/network/ConfigMessageHandler.java | 21 ++ .../com/sijobe/spc/network/IClientConfig.java | 8 + .../com/sijobe/spc/network/PacketConfig.java | 59 ++++++ .../com/sijobe/spc/proxy/DummyException.java | 5 + src/main/java/com/sijobe/spc/proxy/Proxy.java | 20 ++ .../sijobe/spc/proxy/client/ClientProxy.java | 107 ++++++++++ .../client/MinecraftClient.java} | 6 +- .../sijobe/spc/proxy/server/ServerProxy.java | 67 +++++++ .../com/sijobe/spc/util/AccessHelper.java | 76 +++++++ .../com/sijobe/spc/util/KeyboardHandler.java | 36 ++-- .../sijobe/spc/util/RegistryIdCompatible.java | 21 ++ .../java/com/sijobe/spc/wrapper/Block.java | 7 +- .../com/sijobe/spc/wrapper/CommandBase.java | 2 +- .../java/com/sijobe/spc/wrapper/Item.java | 18 +- .../sijobe/spc/wrapper/MinecraftServer.java | 54 ++++- .../java/com/sijobe/spc/wrapper/World.java | 25 ++- 39 files changed, 1104 insertions(+), 407 deletions(-) create mode 100644 src/main/java/com/sijobe/spc/command/Keypress.java create mode 100644 src/main/java/com/sijobe/spc/network/Config.java create mode 100644 src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java create mode 100644 src/main/java/com/sijobe/spc/network/IClientConfig.java create mode 100644 src/main/java/com/sijobe/spc/network/PacketConfig.java create mode 100644 src/main/java/com/sijobe/spc/proxy/DummyException.java create mode 100644 src/main/java/com/sijobe/spc/proxy/Proxy.java create mode 100644 src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java rename src/main/java/com/sijobe/spc/{wrapper/Minecraft.java => proxy/client/MinecraftClient.java} (93%) create mode 100644 src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java create mode 100644 src/main/java/com/sijobe/spc/util/RegistryIdCompatible.java diff --git a/src/main/java/com/sijobe/spc/ModSpc.java b/src/main/java/com/sijobe/spc/ModSpc.java index 9eb34c9..10d2f4a 100644 --- a/src/main/java/com/sijobe/spc/ModSpc.java +++ b/src/main/java/com/sijobe/spc/ModSpc.java @@ -10,11 +10,13 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; +import cpw.mods.fml.common.Mod.Instance; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.TickEvent.Phase; import cpw.mods.fml.common.gameevent.TickEvent.PlayerTickEvent; +import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.relauncher.Side; import com.google.common.eventbus.Subscribe; @@ -30,15 +32,27 @@ import com.sijobe.spc.wrapper.Player; import com.sijobe.spc.wrapper.World; import com.sijobe.spc.core.IPlayerMP; -import com.sijobe.spc.core.IPlayerSP; import com.sijobe.spc.core.ICUIEventHandler; import com.sijobe.spc.hooks.InitialiseCommands; +import com.sijobe.spc.network.ConfigMessageHandler; +import com.sijobe.spc.network.IClientConfig; +import com.sijobe.spc.network.PacketConfig; +import com.sijobe.spc.proxy.Proxy; + +//TODO make prefixslash work in multiplayer @Mod(useMetadata=true, modid="spc", version="5.0") public class ModSpc { + @Instance + public static ModSpc instance; + protected HookManager hookManager; protected InitialiseCommands commands; + public SimpleNetworkWrapper networkHandler; + + public Side side; + public Proxy proxy; public ModSpc() { @@ -47,17 +61,28 @@ public ModSpc() } @EventHandler - public void init(FMLInitializationEvent event) + public void init(FMLInitializationEvent event) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + this.side = event.getSide(); + if(this.side == Side.CLIENT) { + this.proxy = (Proxy) Class.forName("com.sijobe.spc.proxy.client.ClientProxy").newInstance(); //using reflection to prevent client class loading server side + } + else { + this.proxy = (Proxy) Class.forName("com.sijobe.spc.proxy.server.ServerProxy").newInstance(); //using reflection to prevent client class loading server side + } + Block.init(); Item.init(); this.hookManager.loadHooks(IPlayerMP.class); - this.hookManager.loadHooks(IPlayerSP.class); this.hookManager.loadHooks(ICUIEventHandler.class); this.hookManager.loadHooks(IBreakSpeed.class); this.hookManager.loadHooks(IBlockBroken.class); + this.hookManager.loadHooks(IClientConfig.class); MinecraftForge.EVENT_BUS.register(this); FMLCommonHandler.instance().bus().register(this); + this.networkHandler = new SimpleNetworkWrapper("spc.network"); + this.networkHandler.registerMessage(ConfigMessageHandler.class, PacketConfig.class, 0, Side.CLIENT); + this.loadClientSettingHooks(); } @EventHandler @@ -73,23 +98,7 @@ public void onPlayerTick(PlayerTickEvent event) { if(event.phase == Phase.START && event.side == Side.SERVER) { - if(event.player instanceof EntityPlayerSP) - { - Player player = new Player((EntityPlayer) event.player); - boolean moved = event.player.posX != event.player.prevPosX || event.player.posY != event.player.prevPosY || event.player.posZ != event.player.prevPosZ; - for(IPlayerSP hook : this.hookManager.getHooks(IPlayerSP.class)) - { - if(hook.isEnabled()) - { - hook.onTick(player); - if(moved) - { - hook.movePlayer(player, player.getMovementForward(), player.getMovementStrafe(), event.player.getAIMoveSpeed()); - } - } - } - } - else if(event.player instanceof EntityPlayerMP) + if(event.player instanceof EntityPlayerMP) { Player player = new Player((EntityPlayer) event.player); for(IPlayerMP hook : this.hookManager.getHooks(IPlayerMP.class)) @@ -127,4 +136,15 @@ public void onBlockBreak(BreakEvent event) } } } + + public void loadClientSettingHooks() + { + for(IClientConfig hook : this.hookManager.getHooks(IClientConfig.class)) + { + if(hook.isEnabled()) + { + hook.getConfig().setHandler(hook); + } + } + } } diff --git a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java index 09a5e1a..9c16586 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java +++ b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java @@ -1,6 +1,5 @@ package com.sijobe.spc.asm; -import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.LinkedList; diff --git a/src/main/java/com/sijobe/spc/asm/Processor.java b/src/main/java/com/sijobe/spc/asm/Processor.java index adbc965..1ab670f 100644 --- a/src/main/java/com/sijobe/spc/asm/Processor.java +++ b/src/main/java/com/sijobe/spc/asm/Processor.java @@ -4,9 +4,6 @@ import java.util.HashMap; import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Opcodes; class Processor { diff --git a/src/main/java/com/sijobe/spc/asm/SimpleHooked.java b/src/main/java/com/sijobe/spc/asm/SimpleHooked.java index 8262416..63465f5 100644 --- a/src/main/java/com/sijobe/spc/asm/SimpleHooked.java +++ b/src/main/java/com/sijobe/spc/asm/SimpleHooked.java @@ -20,12 +20,11 @@ public static void getBlockReachDistance(MethodVisitor mv) public static void renderInsideOfBlock(MethodVisitor mv) { mv.visitCode(); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/wrapper/Minecraft", "getMinecraft", "()Lnet/minecraft/client/Minecraft;"); - mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/client/Minecraft", "thePlayer", "Lnet/minecraft/client/entity/EntityClientPlayerMP;"); - mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/client/entity/EntityClientPlayerMP", "noClip", "Z"); + mv.visitFieldInsn(Opcodes.GETSTATIC, "com/sijobe/spc/ModSpc", "instance", "Lcom/sijobe/spc/ModSpc;"); + mv.visitFieldInsn(Opcodes.GETFIELD, "com/sijobe/spc/ModSpc", "proxy", "Lcom/sijobe/spc/proxy/Proxy;"); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/sijobe/spc/proxy/Proxy", "shouldNotRenderInsideOfBlock", "()Z"); Label l0 = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, l0); - mv.visitLdcInsn(new Float("1.1")); mv.visitInsn(Opcodes.RETURN); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); diff --git a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java index 78306b7..186dcbe 100644 --- a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java +++ b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java @@ -44,6 +44,6 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc) public static boolean isCommand(String s) { - return s.startsWith("/") || PrefixSlash.prefixSlashEnabled; + return s.startsWith("/") || PrefixSlash.prefixSlash; } } diff --git a/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java b/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java index e087bdc..6d4bebc 100644 --- a/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java +++ b/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java @@ -4,8 +4,12 @@ import cpw.mods.fml.relauncher.IFMLLoadingPlugin; import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.Name; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions; @MCVersion("1.7.2") +@Name("spc Coremod") +@TransformerExclusions("com.sijobe.spc.asm") public class SpcCoreMod implements IFMLLoadingPlugin { @Override diff --git a/src/main/java/com/sijobe/spc/asm/Transformer.java b/src/main/java/com/sijobe/spc/asm/Transformer.java index f553348..b9557c2 100644 --- a/src/main/java/com/sijobe/spc/asm/Transformer.java +++ b/src/main/java/com/sijobe/spc/asm/Transformer.java @@ -1,19 +1,14 @@ package com.sijobe.spc.asm; -import org.objectweb.asm.ClassVisitor; - -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Opcodes; - import net.minecraft.launchwrapper.IClassTransformer; public class Transformer implements IClassTransformer { public Transformer() { - Processor.getInstance().registerMethodTransformers(MethodTransformer.generateFromFunctions(SimpleHooked.class)); - Processor.getInstance().registerMethodTransformer(new SlashPrefixer()); + Processor processor = Processor.getInstance(); + processor.registerMethodTransformers(MethodTransformer.generateFromFunctions(SimpleHooked.class)); + processor.registerMethodTransformer(new SlashPrefixer()); } @Override diff --git a/src/main/java/com/sijobe/spc/command/Achievement.java b/src/main/java/com/sijobe/spc/command/Achievement.java index 8db9f7e..be7f174 100644 --- a/src/main/java/com/sijobe/spc/command/Achievement.java +++ b/src/main/java/com/sijobe/spc/command/Achievement.java @@ -5,7 +5,7 @@ import com.sijobe.spc.validation.ParameterString; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Minecraft; +import com.sijobe.spc.wrapper.MinecraftServer; import com.sijobe.spc.wrapper.Player; import com.sijobe.spc.wrapper.Stats; @@ -48,7 +48,7 @@ public void execute(CommandSender sender, List params) { achievements = achievements.substring(0, achievements.length() - 2); sender.sendMessageToPlayer(achievements); } else if (((String)params.get(0)).equalsIgnoreCase("unlock")) { - Player player = Minecraft.getPlayer(); + Player player = getSenderAsPlayer(sender); if (params.size() == 2) { if (player.addAchievement((String)params.get(1))) { player.sendChatMessage("The " + FontColour.AQUA + (String)params.get(1) @@ -69,9 +69,4 @@ public void execute(CommandSender sender, List params) { public Parameters getParameters() { return PARAMETERS; } - - @Override - public boolean isEnabled() { - return Minecraft.isSinglePlayer(); - } } diff --git a/src/main/java/com/sijobe/spc/command/Bind.java b/src/main/java/com/sijobe/spc/command/Bind.java index b7817d6..82ab2ab 100644 --- a/src/main/java/com/sijobe/spc/command/Bind.java +++ b/src/main/java/com/sijobe/spc/command/Bind.java @@ -1,6 +1,11 @@ package com.sijobe.spc.command; +import com.sijobe.spc.ModSpc; import com.sijobe.spc.core.Constants; +import com.sijobe.spc.network.Config; +import com.sijobe.spc.network.IClientConfig; +import com.sijobe.spc.network.PacketConfig; +import com.sijobe.spc.proxy.client.MinecraftClient; import com.sijobe.spc.util.FontColour; import com.sijobe.spc.util.KeyListener; import com.sijobe.spc.util.KeyboardHandler; @@ -12,7 +17,6 @@ import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandManager; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.MinecraftServer; import com.sijobe.spc.wrapper.Player; @@ -21,95 +25,76 @@ import org.lwjgl.input.Keyboard; +import net.minecraft.entity.player.EntityPlayerMP; + /** * Handles the bindings that the player has assigned to keys * * @author simo_415 * @version 1.1 */ -public class Bind extends MultipleCommands implements KeyListener { - - /** - * The bindings that the player uses - */ - private static Settings BINDINGS = new Settings(new File(Constants.MOD_DIR, "bindings.properties")); - +public class Bind extends MultipleCommands implements KeyListener, IClientConfig { + public static final String SETTINGS_PREFIX = "keybinding-"; + public static final String KEYPRESS_COMMAND = "/keypress "; + /** * The instance that all key bindings are associated against */ private static Bind INSTANCE = new Bind(""); - // Adds all the binding listeners - static { - INSTANCE.addKeyListeners(); - } - /** * The parameters for the bind command */ private static final Parameters BIND_PARAMS = new Parameters ( - new Parameter[] { - new ParameterString("", false), - new ParameterString("", false), - new ParameterString("{PARAMETERS}", true, true) - } - ); - + new Parameter[] { + new ParameterString("", false), + new ParameterString("", false), + new ParameterString("{PARAMETERS}", true, true) + } + ); + /** * The parameters for the bindid command */ private static final Parameters BINDID_PARAMS = new Parameters ( - new Parameter[] { - new ParameterInteger("", false), - new ParameterString("", false), - new ParameterString("{PARAMETERS}", true, true) - } - ); - + new Parameter[] { + new ParameterInteger("", false), + new ParameterString("", false), + new ParameterString("{PARAMETERS}", true, true) + } + ); + /** * The parameters for the unbind command */ private static final Parameters UNBIND_PARAMS = new Parameters ( - new Parameter[] { - new ParameterString("", false), - } - ); - - /** - * Initialises the instance using the specified command name - * - * @param name - The name of the command - */ - public Bind(String name) { - super(name); - } + new Parameter[] { + new ParameterString("", false), + } + ); /** - * Adds all the binding listeners to the key listener + * The parameters for the unbind command */ - private void addKeyListeners() { - for (Object key : BINDINGS.keySet()) { - try { - bind(Integer.parseInt((String)key)); - } catch (Exception e) { - System.err.println("Invalid key specified in bindings: " + key); - BINDINGS.remove(key); + private static final Parameters UNBINDID_PARAMS = new Parameters ( + new Parameter[] { + new ParameterInteger("", false), } - } + ); + + public Bind() { + super(""); } - + /** - * The bind commands are only enabled in single player mode since keyboard - * handling can only currently be done locally as key presses don't get sent - * to the server. + * Initialises the instance using the specified command name * - * @see com.sijobe.spc.wrapper.CommandBase#isEnabled() + * @param name - The name of the command */ - @Override - public boolean isEnabled() { - return Minecraft.isSinglePlayer(); + public Bind(String name) { + super(name); } - + /** * @see com.sijobe.spc.command.MultipleCommands#getCommands() */ @@ -117,12 +102,14 @@ public boolean isEnabled() { public String[] getCommands() { return new String[] {"bind", "unbind", "bindid", "unbindid"}; } - + /** * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) */ @Override public void execute(CommandSender sender, List params) throws CommandException { + Player player = getSenderAsPlayer(sender); + Settings settings = loadSettings(player); if (getName().equalsIgnoreCase("bind") || getName().equalsIgnoreCase("bindid")) { int keycode = Keyboard.KEY_NONE; if (getName().equalsIgnoreCase("bind")) { @@ -139,21 +126,25 @@ public void execute(CommandSender sender, List params) throws CommandExceptio if (params.size() > 2) { param = (String)params.get(2); } - if (BINDINGS.get(keycode + "") == null) { - bind(keycode); - } - BINDINGS.set(keycode + "", command + " " + param); - BINDINGS.save(); + + ModSpc.instance.networkHandler.sendTo(new PacketConfig(this.getConfig(), keycode), (EntityPlayerMP) player.getMinecraftPlayer()); + settings.set(SETTINGS_PREFIX + keycode, command + " " + param); + settings.save(); sender.sendMessageToPlayer("Key " + FontColour.AQUA + params.get(0) + - FontColour.WHITE + " was successfully bound."); + FontColour.WHITE + " was successfully bound."); } else if (getName().equalsIgnoreCase("unbind") || getName().equalsIgnoreCase("unbindid")) { int keycode = Keyboard.KEY_NONE; if (getName().equalsIgnoreCase("unbind")) { String key = (String)params.get(0); if (key.equalsIgnoreCase("all")) { - BINDINGS.clear(); - BINDINGS.save(); + for(Object i : settings.entrySet()) { + if(i instanceof String && ((String) i).startsWith(SETTINGS_PREFIX)) { + settings.remove(i); + } + } + settings.save(); sender.sendMessageToPlayer("All bindings removed."); + ModSpc.instance.networkHandler.sendTo(new PacketConfig(this.getConfig(), 0x02000000), (EntityPlayerMP) player.getMinecraftPlayer()); return; } keycode = Keyboard.getKeyIndex(key.toUpperCase()); @@ -163,19 +154,21 @@ public void execute(CommandSender sender, List params) throws CommandExceptio if (keycode == Keyboard.KEY_NONE) { throw new CommandException("Unknown keycode " + params.get(0)); } - unbind(keycode); - if (BINDINGS.remove(keycode + "") == null) { + + + if (settings.remove(SETTINGS_PREFIX + keycode) == null) { throw new CommandException("No binding was found for key " + FontColour.AQUA + (String)params.get(0)); } else { - BINDINGS.save(); + settings.save(); + ModSpc.instance.networkHandler.sendTo(new PacketConfig(this.getConfig(), 0x01000000 | keycode), (EntityPlayerMP) player.getMinecraftPlayer()); sender.sendMessageToPlayer("Binding " + FontColour.AQUA + params.get(0) + - FontColour.WHITE + " was successfully removed."); + FontColour.WHITE + " was successfully removed."); } } else { assert false : "Invalid command " + getName(); } } - + /** * Binds a key to a listener * @@ -184,7 +177,6 @@ public void execute(CommandSender sender, List params) throws CommandExceptio private void bind(int key) { if (!KeyboardHandler.getInstance().addKeyPressedListener(key, INSTANCE)) { System.err.println("Invalid key specified in bindings: " + key); - BINDINGS.remove(key); } } @@ -196,7 +188,7 @@ private void bind(int key) { private void unbind(int key) { KeyboardHandler.getInstance().removeKeyPressedListener(key, INSTANCE); } - + @Override public Parameters getParameters() { if (getName().equalsIgnoreCase("bind")) { @@ -205,12 +197,14 @@ public Parameters getParameters() { return UNBIND_PARAMS; } else if (getName().equalsIgnoreCase("bindid")) { return BINDID_PARAMS; + } else if (getName().equalsIgnoreCase("unbindid")) { + return UNBINDID_PARAMS; } else { assert false : "Invalid command name initialsied " + getName(); return Parameters.DEFAULT; } } - + /** * Handles binding events * @@ -218,16 +212,13 @@ public Parameters getParameters() { */ @Override public void keyPressed(int key) { - if (Minecraft.isGuiScreenOpen()) { + if (ModSpc.instance.proxy.isClientGuiScreenOpen()) { return; } - Player player = Minecraft.getPlayer(); - if (player != null) { - CommandSender sender = new CommandSender(MinecraftServer.getPlayerByUsername(player.getPlayerName())); - CommandManager.runCommand(sender, BINDINGS.getString(key + "", "")); - } + + ModSpc.instance.proxy.sendClientChat(KEYPRESS_COMMAND + key); } - + /** * @see com.sijobe.spc.util.KeyListener#keyReleased(int) */ @@ -235,4 +226,36 @@ public void keyPressed(int key) { public void keyReleased(int key) { // Not required } + + @Override + public void init(Object... params) { + } + + + /** + * @see com.sijobe.spc.network.IClientConfig#onConfigRecieved(java.lang.Object) + * @param value the first byte determines the what action is required + * if it is zero, bind the key specified in the last byte + * if it is one, unbind the key specified in the last byte + * if it is two, unbind all keys + */ + @Override + public void onConfigRecieved(Integer value) { + int action = (value & 0xFF000000) >> 24; + int keycode = value & 0x000000FF; + if(action == 0) { + this.bind(keycode); + } + else if(action == 1) { + this.unbind(keycode); + } + else if(action == 2) { + KeyboardHandler.removeAllKeys(INSTANCE); + } + } + + @Override + public Config getConfig() { + return Config.BIND; + } } diff --git a/src/main/java/com/sijobe/spc/command/BlockReach.java b/src/main/java/com/sijobe/spc/command/BlockReach.java index 7759ee2..9094794 100644 --- a/src/main/java/com/sijobe/spc/command/BlockReach.java +++ b/src/main/java/com/sijobe/spc/command/BlockReach.java @@ -1,12 +1,15 @@ package com.sijobe.spc.command; +import com.sijobe.spc.ModSpc; +import com.sijobe.spc.network.Config; +import com.sijobe.spc.network.IClientConfig; +import com.sijobe.spc.network.PacketConfig; import com.sijobe.spc.util.ForgeHelper; import com.sijobe.spc.validation.Parameter; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.validation.ParameterDouble; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.Player; import net.minecraft.entity.player.EntityPlayerMP; @@ -14,29 +17,28 @@ /** * Changes block reach distance - * TODO make this work in multiplayer (refers to PlayerControllerMP) * * @author q3hardcore * @version 1.0 * @status broken through 1.7.2 update -> fixed */ @Command ( - name = "blockreach", - description = "Changes block reach distance", - alias = {"reach"} -) -public class BlockReach extends StandardCommand { - + name = "blockreach", + description = "Changes block reach distance", + alias = {"reach"} + ) +public class BlockReach extends StandardCommand implements IClientConfig{ + /** * The parameters of the command */ private static final Parameters PARAMETERS = new Parameters ( - new Parameter[] { - new ParameterDouble("[DISTANCE]", true), - } - ); + new Parameter[] { + new ParameterDouble("[DISTANCE]", true), + } + ); - public static float reachDistance = 4.5F; //refered to through ASM modifications + public static float reachDistance = 4.5F; //refered to through ASM modifications and is client sided /** * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) @@ -50,30 +52,18 @@ public void execute(CommandSender sender, List params) throws CommandExceptio EntityPlayerMP playerEntity = (EntityPlayerMP)player.getMinecraftPlayer(); if(params.size() == 0) { sender.sendMessageToPlayer("Current block reach distance: " + - ForgeHelper.getBlockReachDistance(playerEntity.theItemInWorldManager)); + ForgeHelper.getBlockReachDistance(playerEntity.theItemInWorldManager)); } else { double newReach = (Double)params.get(0); if(newReach < 4.5D || newReach > 255.0D) { throw new CommandException("Reach distance must be between 4.5 and 255."); } - //ForgeHelper.setBlockReachDistance(playerEntity.theItemInWorldManager, newReach); - //Minecraft.getMinecraft().thePlayer.setClientReach(newReach); //removed since spc 1.7.2 update now needs forge anyway playerEntity.theItemInWorldManager.setBlockReachDistance(newReach); - reachDistance = (float) newReach; sender.sendMessageToPlayer("Set block reach distance to: " + newReach); + ModSpc.instance.networkHandler.sendTo(new PacketConfig(this.getConfig(), (float) newReach), playerEntity); } } - /** - * Only enabled in single player since this is a client-side mod - * - * @see com.sijobe.spc.wrapper.CommandBase#isEnabled() - */ - @Override - public boolean isEnabled() { - return Minecraft.isSinglePlayer() && ForgeHelper.HAS_FORGE; - } - /** * @see com.sijobe.spc.wrapper.CommandBase#getParameters() */ @@ -81,4 +71,18 @@ public boolean isEnabled() { public Parameters getParameters() { return PARAMETERS; } + + @Override + public void init(Object... params) { + } + + @Override + public void onConfigRecieved(Float value) { + reachDistance = value; + } + + @Override + public Config getConfig() { + return Config.BLOCK_REACH; + } } diff --git a/src/main/java/com/sijobe/spc/command/DoDrops.java b/src/main/java/com/sijobe/spc/command/DoDrops.java index 64a085d..6aed7cc 100644 --- a/src/main/java/com/sijobe/spc/command/DoDrops.java +++ b/src/main/java/com/sijobe/spc/command/DoDrops.java @@ -6,7 +6,6 @@ import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Coordinate; -import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.Player; import java.util.List; @@ -31,7 +30,7 @@ public class DoDrops extends StandardCommand implements IPlayerMP { @Override public boolean isEnabled() { - return Minecraft.isSinglePlayer(); + return true; } @Override diff --git a/src/main/java/com/sijobe/spc/command/InstantMine.java b/src/main/java/com/sijobe/spc/command/InstantMine.java index c22c55d..315688f 100644 --- a/src/main/java/com/sijobe/spc/command/InstantMine.java +++ b/src/main/java/com/sijobe/spc/command/InstantMine.java @@ -1,7 +1,10 @@ package com.sijobe.spc.command; +import com.sijobe.spc.ModSpc; import com.sijobe.spc.core.IBlockBroken; import com.sijobe.spc.core.IBreakSpeed; +import com.sijobe.spc.network.Config; +import com.sijobe.spc.network.IClientConfig; import com.sijobe.spc.util.AccessHelper; import com.sijobe.spc.util.ForgeHelper; import com.sijobe.spc.util.Settings; @@ -9,7 +12,6 @@ import com.sijobe.spc.wrapper.Block; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.Player; import com.sijobe.spc.wrapper.World; @@ -26,65 +28,63 @@ * @status broken through 1.7.2 update -> fixed */ @Command ( - name = "instantmine", - description = "Allows player to mine blocks instantly", - example = "", - videoURL = "", - enabled = true - ) -public class InstantMine extends StandardCommand implements IBreakSpeed, IBlockBroken{ - public static boolean instantMiningEnabled; //TODO load initial value from config - - @Override - public void execute(CommandSender sender, List params) throws CommandException { - Player player = super.getSenderAsPlayer(sender); - if(player.getMinecraftPlayer() instanceof EntityPlayerMP) { - Settings config = super.loadSettings(player); - boolean instantMine = config.getBoolean("instantMine", false); - if (params.size() == 0) { - instantMine ^= true; - } else { - instantMine = ((Boolean)params.get(0)); - } - - config.set("instantMine", instantMine); - super.saveSettings(player); - instantMiningEnabled = instantMine; - player.sendChatMessage("Instant mining " + (instantMine?"enabled.":"disabled.")); - } else { - throw new CommandException("Non-client command"); - } - } - - @Override - public Parameters getParameters() { - return Parameters.DEFAULT_BOOLEAN; - } - - @Override - public void init(Object... params) {} - - @Override - public float getBreakSpeed(Player player, Block block, int metadata, float orginalSpeed, int x, int y, int z) { - return instantMiningEnabled ? 50000000.0F : orginalSpeed; - } - - @Override - public void onBreakBroken(int x, int y, int z, World world, Block block, int metadata, Player player) { - try { - AccessHelper.setInt(Minecraft.getMinecraft().playerController, "blockHitDelay", 5); - } catch (NoSuchFieldException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + name = "instantmine", + description = "Allows player to mine blocks instantly", + example = "", + videoURL = "", + enabled = true + ) +public class InstantMine extends StandardCommand implements IBreakSpeed, IBlockBroken, IClientConfig{ + public static boolean instantMiningEnabled; //TODO load initial value from config + + @Override + public void execute(CommandSender sender, List params) throws CommandException { + Player player = super.getSenderAsPlayer(sender); + if(player.getMinecraftPlayer() instanceof EntityPlayerMP) { + Settings config = super.loadSettings(player); + boolean instantMine = config.getBoolean("instantMine", false); + if (params.size() == 0) { + instantMine ^= true; + } else { + instantMine = ((Boolean)params.get(0)); + } + + config.set("instantMine", instantMine); + super.saveSettings(player); + instantMiningEnabled = instantMine; + player.sendChatMessage("Instant mining " + (instantMine?"enabled.":"disabled.")); + } else { + throw new CommandException("Non-client command"); + } + } + + @Override + public Parameters getParameters() { + return Parameters.DEFAULT_BOOLEAN; + } + + @Override + public void init(Object... params) {} + + @Override + public float getBreakSpeed(Player player, Block block, int metadata, float orginalSpeed, int x, int y, int z) { + return instantMiningEnabled ? 50000000.0F : orginalSpeed; + } + + @Override + public void onBreakBroken(int x, int y, int z, World world, Block block, int metadata, Player player) { + if(instantMiningEnabled) { + ModSpc.instance.proxy.setClientHitDelay(5); + } + } + + @Override + public void onConfigRecieved(Boolean value) { + instantMiningEnabled = value; + } + + @Override + public Config getConfig() { + return Config.INSTANT_MINE; + } } \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/command/Keypress.java b/src/main/java/com/sijobe/spc/command/Keypress.java new file mode 100644 index 0000000..8719259 --- /dev/null +++ b/src/main/java/com/sijobe/spc/command/Keypress.java @@ -0,0 +1,42 @@ +package com.sijobe.spc.command; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; + +import com.sijobe.spc.util.Settings; +import com.sijobe.spc.validation.Parameter; +import com.sijobe.spc.validation.ParameterInteger; +import com.sijobe.spc.validation.ParameterString; +import com.sijobe.spc.validation.Parameters; +import com.sijobe.spc.wrapper.CommandException; +import com.sijobe.spc.wrapper.CommandManager; +import com.sijobe.spc.wrapper.CommandSender; +import com.sijobe.spc.wrapper.MinecraftServer; + +/** + * Executes the command bound to the given key. + * + * @author aucguy + * @version 1.0 + */ +@Command ( + name = "keypress", + description = "Executes the command bound to the given key. Internally used command", + videoURL = "none, as I said, this is an internally used command.", + version = "1.0" + ) +public class Keypress extends StandardCommand { + private static final Parameters PARAMETERS = new Parameters ( + new Parameter[] { + new ParameterInteger("[keycode]",true) + } + ); + + @Override + public void execute(CommandSender sender, List params) throws CommandException { + Settings settings = this.loadSettings(getSenderAsPlayer(sender)); + String command = settings.getProperty(Bind.SETTINGS_PREFIX+params.get(0)); + CommandManager.runCommand(sender, command); + } +} diff --git a/src/main/java/com/sijobe/spc/command/Light.java b/src/main/java/com/sijobe/spc/command/Light.java index 289623d..7c9b1ad 100644 --- a/src/main/java/com/sijobe/spc/command/Light.java +++ b/src/main/java/com/sijobe/spc/command/Light.java @@ -1,13 +1,18 @@ package com.sijobe.spc.command; +import com.sijobe.spc.ModSpc; +import com.sijobe.spc.network.Config; +import com.sijobe.spc.network.IClientConfig; +import com.sijobe.spc.network.PacketConfig; +import com.sijobe.spc.util.Settings; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.Player; -import com.sijobe.spc.wrapper.World; import java.util.List; +import net.minecraft.entity.player.EntityPlayerMP; + /** * Light command from SinglePlayerCommands 3.2.2, * ported to SinglePlayerConsole then back to SPC 4.1 @@ -17,14 +22,13 @@ * @status survived 1.7.2 update */ @Command ( - name = "light", - description = "Lights up world", - version = "1.4" -) -public class Light extends StandardCommand { - - public static boolean isLit = false; // is current world lit? - public static int litWorld = 0; // hashCode for currently lit world + name = "light", + description = "Lights up world", + version = "1.4" + ) +public class Light extends StandardCommand implements IClientConfig { + + public static boolean isLit = false; // is current world lit? client sided /** * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) @@ -32,41 +36,23 @@ public class Light extends StandardCommand { @Override public void execute(CommandSender sender, List params) throws CommandException { Player player = super.getSenderAsPlayer(sender); // Why super.? Meh, Cannon has it like that - Player clientPlayer = Minecraft.getPlayer(); - - if(clientPlayer == null) { - throw new CommandException("No client player!"); - } - - World clientWorld = clientPlayer.getWorld(); - - if(player.getWorld().getMinecraftWorld().hashCode() != litWorld) { - isLit = false; - } - - // Note: provider is worldProvider - if(!isLit) { - sender.sendMessageToPlayer("Lighting world"); - float[] lightBrightnessTable = clientWorld.getMinecraftWorld().provider.lightBrightnessTable; - for(int i = 0; i < lightBrightnessTable.length; i++) { - lightBrightnessTable[i] = 1.0F; - } - litWorld = player.getWorld().getMinecraftWorld().hashCode(); // we go by the serverside hashcode - } else { - sender.sendMessageToPlayer("Restoring light levels"); - clientWorld.getMinecraftWorld().provider.registerWorld(clientWorld.getMinecraftWorld()); - } - isLit = !isLit; // toggle isLit + Settings config = this.loadSettings(player); + boolean lit = !config.getBoolean("light", false); + config.set("light", lit); + ModSpc.instance.networkHandler.sendTo(new PacketConfig(this.getConfig(), lit), (EntityPlayerMP) player.getMinecraftPlayer()); } - - /** - * Only enabled in single player since this is a client-side mod - * - * @see com.sijobe.spc.wrapper.CommandBase#isEnabled() - */ + @Override - public boolean isEnabled() { - return Minecraft.isSinglePlayer(); + public void init(Object... params) { + } + + @Override + public void onConfigRecieved(Boolean value) { + ModSpc.instance.proxy.toggleClientLighting(value); + } + + @Override + public Config getConfig() { + return Config.LIGHT; } - } diff --git a/src/main/java/com/sijobe/spc/command/LongerLegs.java b/src/main/java/com/sijobe/spc/command/LongerLegs.java index f79e099..8871425 100644 --- a/src/main/java/com/sijobe/spc/command/LongerLegs.java +++ b/src/main/java/com/sijobe/spc/command/LongerLegs.java @@ -2,10 +2,15 @@ import java.util.List; +import net.minecraft.entity.player.EntityPlayerMP; + +import com.sijobe.spc.ModSpc; +import com.sijobe.spc.network.Config; +import com.sijobe.spc.network.IClientConfig; +import com.sijobe.spc.network.PacketConfig; import com.sijobe.spc.util.FontColour; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.Player; /** @@ -25,17 +30,17 @@ videoURL = "http://www.youtube.com/watch?v=1Qy2jhvCkDk", version = "1.4.6" ) -public class LongerLegs extends StandardCommand { +public class LongerLegs extends StandardCommand implements IClientConfig { @Override public boolean isEnabled() { - return Minecraft.isSinglePlayer(); + return true; } @Override public void execute(CommandSender sender, List params) throws CommandException { - Player player = Minecraft.getPlayer(); + Player player = getSenderAsPlayer(sender); if (player.getStepHeight() != 0.5F) { player.setStepHeight(0.5F); sender.sendMessageToPlayer("Longer legs is "+FontColour.AQUA+"disabled"); @@ -43,6 +48,21 @@ public void execute(CommandSender sender, List params) player.setStepHeight(1.0F); sender.sendMessageToPlayer("Longer legs is "+FontColour.AQUA+"enabled"); } + ModSpc.instance.networkHandler.sendTo(new PacketConfig(this.getConfig(), player.getStepHeight()), (EntityPlayerMP) player.getMinecraftPlayer()); } -} + @Override + public void init(Object... params) { + } + + @Override + public void onConfigRecieved(Float value) { + System.out.println("foo"); + ModSpc.instance.proxy.getClientPlayer().setStepHeight(value); + } + + @Override + public Config getConfig() { + return Config.LONGER_LEGS; + } +} \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/command/Macro.java b/src/main/java/com/sijobe/spc/command/Macro.java index 7b962ae..eb8369b 100644 --- a/src/main/java/com/sijobe/spc/command/Macro.java +++ b/src/main/java/com/sijobe/spc/command/Macro.java @@ -1,35 +1,39 @@ package com.sijobe.spc.command; import com.sijobe.spc.core.Constants; +import com.sijobe.spc.util.Settings; import com.sijobe.spc.validation.Parameter; import com.sijobe.spc.validation.ParameterString; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandManager; import com.sijobe.spc.wrapper.CommandSender; +import com.sijobe.spc.wrapper.Player; import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; import java.util.List; /** * Macro command allows you to write a file with a list of commands in it then * run the file. - * + * * @author simo_415 * @version 1.0 * @status survived 1.7.2 update */ -@Command ( - name = "macro", - description = "Macro based commands allow multiple commands to be run", - example = "test", - videoURL = "http://www.youtube.com/watch?v=hkQfslQJoQs", - version = "1.0" -) -public class Macro extends StandardCommand { - +@Command(name = "macro", description = "Macro based commands allow multiple commands to be run", example = "test", videoURL = "http://www.youtube.com/watch?v=hkQfslQJoQs", version = "1.0") +public class Macro extends MultipleCommands { + /** + * The prefix in a player's settings for player specific macros + */ + public static final String SETTINGS_PREFIX = "macro-"; + /** * The file extension of macro files */ @@ -43,58 +47,156 @@ public class Macro extends StandardCommand { MACRO_DIR.mkdirs(); } } - + /** - * Parameters of the command + * Parameters of the macro command */ - private static final Parameters PARAMETERS = new Parameters ( - new Parameter[] { - new ParameterString("", false), - new ParameterString("{PARAMETERS}", true, true) - } - ); - + private static final Parameters MACRO_PARAMS = new Parameters( + new Parameter[] { new ParameterString("", false), + new ParameterString("{PARAMETERS}", true, true) }); + + /** + * Parameters of the setmacro command + */ + private static final Parameters SETMACRO_PARAMS = new Parameters( + new Parameter[] { new ParameterString("", false), + new ParameterString("{COMMANDS}", true, true) }); + /** - * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) + * Parameters of the remove macro command + */ + private static final Parameters REMOVEMACRO_PARAMS = new Parameters( + new Parameter[] { new ParameterString("", false) + }); + + public Macro(String name) { + super(name); + } + + /** + * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, + * java.util.List) */ @Override - public void execute(CommandSender sender, List params) throws CommandException { - File macro = new File(MACRO_DIR, (String)params.get(0) + MACRO_EXTENSION); - if (!macro.exists()) { - throw new CommandException("Specified macro does not exist."); - } - - try { - BufferedReader br = new BufferedReader(new FileReader(macro)); + public void execute(CommandSender sender, List params) + throws CommandException { + + if(getName().equalsIgnoreCase("macro")) { + String macro; + try { + macro = getMacro((String) params.get(0), sender); + } catch (IOException e) { + throw new CommandException("Unable to opening file."); + } + String split[] = null; if (params.size() == 1) { - split = new String[] { (String)params.get(0) }; + split = new String[] { (String) params.get(0) }; } else { - split = (((String)params.get(0)) + " " + ((String)params.get(1))).split(" "); + split = (((String) params.get(0)) + " " + ((String) params.get(1))) + .split(" "); } - String line = null; - while ((line = br.readLine()) != null) { + + String[] lines = macro.replace("\r", "\n").split("\n"); + for (String line : lines) { + if(line.equals("")) { + continue; + } // Adds arguments to the line for (int i = 0; i < split.length; i++) { line = line.replaceAll("\\$_" + i, split[i]); } - + // Remove all unspecified arguments from line line = line.replaceAll("\\$_[0-9]+", ""); - + // Executes the line CommandManager.runCommand(sender, line); } - } catch (Exception e) { - throw new CommandException(e); + } else if(getName().equalsIgnoreCase("setmacro")) { + Player player = getSenderAsPlayer(sender); + if(player == null) { + throw new CommandException("sender must be player"); + } + Settings settings = loadSettings(player); + settings.set(SETTINGS_PREFIX + (String)params.get(0), ((String) params.get(1)).replace("/", "\n\r")); + } else if(getName().equalsIgnoreCase("removemacro")) { + String macro = (String) params.get(0); + Player player = getSenderAsPlayer(sender); + if(player == null) { + throw new CommandException("sender must be player"); + } + Settings settings = loadSettings(player); + if(macro.equals("all")) { + for(Object i : settings.keySet().toArray()) { + if(i instanceof String && ((String) i).startsWith(SETTINGS_PREFIX)) { + settings.remove(i); + } + } + settings.save(); + sender.sendMessageToPlayer("All macros removed."); + return; + } + settings.remove(SETTINGS_PREFIX + macro); + sender.sendMessageToPlayer("Macro " + macro + " removed."); + } else { + assert false : "Invalid command " + getName(); } } - + + /** + * gets the macro file for a given macro name + * + * @param name + * - the name of the macro (ie. passed through the chat like + * '/macro test') + * @param sender + * - the sender who sent the command + * @return the macro contents (ie the contents of the macro file) + * @throws CommandException + * @throws IOException + * */ + public String getMacro(String name, CommandSender sender) + throws CommandException, IOException { + Player player = getSenderAsPlayer(sender); + if (player != null) { + Settings settings = loadSettings(player); + String key = SETTINGS_PREFIX + name; + if (settings.containsKey(key)) { + return settings.getProperty(key); + } + } + File file = new File(MACRO_DIR, name + MACRO_EXTENSION); + FileInputStream reader; + try { + reader = new FileInputStream(file); + } catch (FileNotFoundException error) { + throw new CommandException("Specified macro does not exist."); + } + byte[] data = new byte[(int) file.length()]; + reader.read(data); + return new String(data); + } + /** * @see com.sijobe.spc.wrapper.CommandBase#getParameters() */ @Override public Parameters getParameters() { - return PARAMETERS; + if (getName().equalsIgnoreCase("macro")) { + return MACRO_PARAMS; + } else if (getName().equalsIgnoreCase("setmacro")) { + return SETMACRO_PARAMS; + } else if (getName().equalsIgnoreCase("removemacro")) { + return REMOVEMACRO_PARAMS; + } else { + assert false : "Invalid command name initialsied " + getName(); + return Parameters.DEFAULT; + } + } + + @Override + public String[] getCommands() { + return new String[]{"macro", "setmacro", "removemacro"}; } } diff --git a/src/main/java/com/sijobe/spc/command/Noclip.java b/src/main/java/com/sijobe/spc/command/Noclip.java index 0fe8cdb..3aff61d 100644 --- a/src/main/java/com/sijobe/spc/command/Noclip.java +++ b/src/main/java/com/sijobe/spc/command/Noclip.java @@ -1,5 +1,9 @@ package com.sijobe.spc.command; +import com.sijobe.spc.ModSpc; +import com.sijobe.spc.network.Config; +import com.sijobe.spc.network.IClientConfig; +import com.sijobe.spc.network.PacketConfig; import com.sijobe.spc.overwrite.ONetServerHandler; import com.sijobe.spc.util.FontColour; import com.sijobe.spc.validation.Parameters; @@ -7,7 +11,6 @@ import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Coordinate; -import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.Player; import java.util.List; @@ -26,31 +29,31 @@ * @status survived 1.7.2 update but can't see anything while inside blocks -> fixed */ @Command ( - name = "noclip", - description = "Enables and disables the ability to clip for the player", - example = "", - videoURL = "http://www.youtube.com/watch?v=4ZOvu3hf7k0", // video for fly command - enabled = true -) -public class Noclip extends StandardCommand { - + name = "noclip", + description = "Enables and disables the ability to clip for the player", + example = "", + videoURL = "http://www.youtube.com/watch?v=4ZOvu3hf7k0", // video for fly command + enabled = true + ) +public class Noclip extends StandardCommand implements IClientConfig { + @Override public void execute(CommandSender sender, List params) throws CommandException { Player player = CommandBase.getSenderAsPlayer(sender); - - /*if(!player.getUsername().equals(MinecraftServer.getServer().getServerOwner())) { + + /*if(!player.getUsername().equals(MinecraftServer.getServer().getServerOwner())) { throw new CommandException("Must be server host"); }*/ if(!player.getMinecraftPlayer().capabilities.isFlying && !player.getMinecraftPlayer().noClip) { throw new CommandException("Must be flying"); } - + if (params.size() == 0) { player.getMinecraftPlayer().noClip ^= true; } else { player.getMinecraftPlayer().noClip = (Boolean)params.get(0); } - + // replace server handler if(player.getMinecraftPlayer() instanceof EntityPlayerMP) { updateServerHandler((EntityPlayerMP)player.getMinecraftPlayer()); @@ -58,19 +61,19 @@ public void execute(CommandSender sender, List params) throws CommandExceptio player.getMinecraftPlayer().noClip = false; throw new CommandException("Noclip unavailable"); } - + if(player.getMinecraftPlayer().noClip == false) { ascendPlayer(player); } - Minecraft.getMinecraft().thePlayer.noClip = player.getMinecraftPlayer().noClip; + ModSpc.instance.networkHandler.sendTo(new PacketConfig(this.getConfig(), player.getMinecraftPlayer().noClip), (EntityPlayerMP) player.getMinecraftPlayer()); player.sendChatMessage("Noclip is now " + FontColour.AQUA + (!player.getMinecraftPlayer().noClip ? "disabled" : "enabled")); } - + @Override public Parameters getParameters() { return Parameters.DEFAULT_BOOLEAN; } - + private static boolean hasXCommands() { try { NetHandlerPlayServer.class.getDeclaredField("clientHasXCommands"); @@ -79,7 +82,7 @@ private static boolean hasXCommands() { return false; } } - + /** * Changes server handler to SPC's server handler if noclip is enabled, * otherwise restores the default server handler. @@ -88,17 +91,17 @@ private static void updateServerHandler(EntityPlayerMP playerEntity) { if(hasXCommands()) { return; } - + NetHandlerPlayServer handler = playerEntity.playerNetServerHandler; - + if(playerEntity.noClip) { if(!(handler instanceof ONetServerHandler)) { playerEntity.playerNetServerHandler = new ONetServerHandler(MinecraftServer.getServer(), - handler.netManager, handler.playerEntity, handler); + handler.netManager, handler.playerEntity, handler); } } else { if(handler instanceof ONetServerHandler) { - NetHandlerPlayServer oldInstance = ((ONetServerHandler)handler).getOldInstance(); + NetHandlerPlayServer oldInstance = ((ONetServerHandler)handler).getOldInstance(); if(oldInstance != null) { handler.netManager.setNetHandler(oldInstance); playerEntity.playerNetServerHandler = oldInstance; @@ -106,17 +109,17 @@ private static void updateServerHandler(EntityPlayerMP playerEntity) { } } } - + public static void checkSafe(EntityPlayerMP player) { if(player.noClip && !player.capabilities.isFlying) { player.noClip = false; - Minecraft.getMinecraft().thePlayer.noClip = false; + ModSpc.instance.networkHandler.sendTo(new PacketConfig(Config.NOCLIP, false), player); player.addChatMessage(new ChatComponentText("Noclip auto-disabled. (Player not flying)")); updateServerHandler(player); ascendPlayer(new Player(player)); } } - + private static boolean ascendPlayer(Player player) { Coordinate playerPos = player.getPosition(); if(player.isClearBelow(playerPos) && playerPos.getY() > 0) { @@ -138,4 +141,18 @@ private static boolean ascendPlayer(Player player) { } return true; } + + @Override + public void init(Object... params) { + } + + @Override + public void onConfigRecieved(Boolean value) { + ModSpc.instance.proxy.getClientPlayer().getMinecraftPlayer().noClip = value; + } + + @Override + public Config getConfig() { + return Config.NOCLIP; + } } \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/command/PrefixSlash.java b/src/main/java/com/sijobe/spc/command/PrefixSlash.java index a5c6156..d64ef10 100644 --- a/src/main/java/com/sijobe/spc/command/PrefixSlash.java +++ b/src/main/java/com/sijobe/spc/command/PrefixSlash.java @@ -1,16 +1,21 @@ package com.sijobe.spc.command; +import com.sijobe.spc.ModSpc; +import com.sijobe.spc.network.Config; +import com.sijobe.spc.network.IClientConfig; +import com.sijobe.spc.network.PacketConfig; import com.sijobe.spc.util.FontColour; import com.sijobe.spc.util.Settings; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandBase; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.Player; import java.util.List; +import net.minecraft.entity.player.EntityPlayerMP; + /** * Command to toggle requiring '/' * @@ -19,26 +24,25 @@ * @status broken through 1.7.2 update -> fixed */ @Command ( - name = "prefixslash", - description = "Enables and disables auto slash-prefixing", - example = "", - videoURL = "", - enabled = true -) -public class PrefixSlash extends StandardCommand { - public static boolean prefixSlashEnabled = false; - - @Override - public boolean isEnabled() { - return Minecraft.isSinglePlayer(); - } - + name = "prefixslash", + description = "Enables and disables auto slash-prefixing", + example = "", + videoURL = "", + enabled = true + ) +public class PrefixSlash extends StandardCommand implements IClientConfig { + public static boolean prefixSlash = false; + + @Override + public boolean isEnabled() { + return true; + } + @Override public void execute(CommandSender sender, List params) throws CommandException { Player player = CommandBase.getSenderAsPlayer(sender); Settings config = super.loadSettings(player); - //boolean prefixSlash = config.getBoolean("prefixSlash", true); - boolean prefixSlash = prefixSlashEnabled; + boolean prefixSlash = config.getBoolean("prefixSlash", true); if (params.size() == 0) { prefixSlash ^= true; } else { @@ -46,14 +50,27 @@ public void execute(CommandSender sender, List params) throws CommandExceptio } config.set("prefixSlash", prefixSlash); super.saveSettings(player); - prefixSlashEnabled = prefixSlash; + ModSpc.instance.networkHandler.sendTo(new PacketConfig(this.getConfig(), prefixSlash), (EntityPlayerMP) player.getMinecraftPlayer()); player.sendChatMessage("Slash prefixing is now " + FontColour.AQUA - + (prefixSlash ? "enabled" : "disabled")); + + (prefixSlash ? "enabled" : "disabled")); } @Override public Parameters getParameters() { return Parameters.DEFAULT_BOOLEAN; } - + + @Override + public void init(Object... params) { + } + + @Override + public void onConfigRecieved(Boolean value) { + prefixSlash = value; + } + + @Override + public Config getConfig() { + return Config.PREFIX_SLASH; + } } \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/command/SetSpeed.java b/src/main/java/com/sijobe/spc/command/SetSpeed.java index 8aafe5f..cdb512e 100644 --- a/src/main/java/com/sijobe/spc/command/SetSpeed.java +++ b/src/main/java/com/sijobe/spc/command/SetSpeed.java @@ -1,6 +1,5 @@ package com.sijobe.spc.command; -import com.sijobe.spc.core.IPlayerSP; import com.sijobe.spc.util.AccessHelper; import com.sijobe.spc.util.FontColour; import com.sijobe.spc.util.Settings; @@ -10,7 +9,6 @@ import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Coordinate; -import com.sijobe.spc.wrapper.Minecraft; import com.sijobe.spc.wrapper.Player; import java.util.List; @@ -103,14 +101,4 @@ public void execute(CommandSender sender, List params) throws CommandExceptio public Parameters getParameters() { return PARAMETERS; } - - /** - * Only enabled in single player since this is a client-side mod - * - * @see com.sijobe.spc.wrapper.CommandBase#isEnabled() - */ - @Override - public boolean isEnabled() { - return Minecraft.isSinglePlayer(); - } } diff --git a/src/main/java/com/sijobe/spc/command/Sudo.java b/src/main/java/com/sijobe/spc/command/Sudo.java index 4de7543..2173edd 100644 --- a/src/main/java/com/sijobe/spc/command/Sudo.java +++ b/src/main/java/com/sijobe/spc/command/Sudo.java @@ -16,7 +16,7 @@ * * @author simo_415 * @version 1.0 - * @survived 1.7.2 update + * @status survived 1.7.2 update */ @Command ( name = "sudo", diff --git a/src/main/java/com/sijobe/spc/core/Constants.java b/src/main/java/com/sijobe/spc/core/Constants.java index c3e5019..c070779 100644 --- a/src/main/java/com/sijobe/spc/core/Constants.java +++ b/src/main/java/com/sijobe/spc/core/Constants.java @@ -2,11 +2,13 @@ import com.sijobe.spc.updater.ModVersion; import com.sijobe.spc.util.Settings; -import com.sijobe.spc.wrapper.Minecraft; +import com.sijobe.spc.wrapper.MinecraftServer; import java.io.File; import java.util.Date; +import net.minecraft.server.integrated.IntegratedServer; + /** * Contains all of the constant values that the mod uses * @@ -32,7 +34,7 @@ public class Constants { /** * The directory that the mod saves/loads global settings from */ - public static final File MOD_DIR = new File(Minecraft.getMinecraftDirectory(), "mods/spc"); + public static final File MOD_DIR = new File(MinecraftServer.getDirectoryName(), "mods/spc"); // Creates the mod directory if it doesn't already exist static { @@ -49,7 +51,7 @@ public class Constants { /** * Directory where the Minecraft level saves are located */ - public static final File SAVES_DIR = new File(Minecraft.getMinecraftDirectory(), "saves"); + public static final File SAVES_DIR = new File(MinecraftServer.getDirectoryName(), MinecraftServer.getMinecraftServer().isDedicatedServer() ? "" : "saves"); /** * @return the version diff --git a/src/main/java/com/sijobe/spc/core/SPCLoader.java b/src/main/java/com/sijobe/spc/core/SPCLoader.java index 3fc6be1..0ead5b4 100644 --- a/src/main/java/com/sijobe/spc/core/SPCLoader.java +++ b/src/main/java/com/sijobe/spc/core/SPCLoader.java @@ -1,7 +1,7 @@ package com.sijobe.spc.core; import com.sijobe.spc.util.DynamicClassLoader; -import com.sijobe.spc.wrapper.Minecraft; +import com.sijobe.spc.wrapper.MinecraftServer; import java.io.File; @@ -36,8 +36,8 @@ public static void load() { */ private static void loadClasspath() { File classpath[] = DynamicClassLoader.getClasspath(); - //System.out.println("Minecraft: " + Minecraft.getMinecraftDirectory().getAbsolutePath()); - File files[] = (new File(Minecraft.getMinecraftDirectory(),"bin")).listFiles(); + System.out.println("Minecraft: " + MinecraftServer.getDirectoryName()); + File files[] = (new File(MinecraftServer.getDirectoryName(),"bin")).listFiles(); if (files == null) { return; } diff --git a/src/main/java/com/sijobe/spc/network/Config.java b/src/main/java/com/sijobe/spc/network/Config.java new file mode 100644 index 0000000..cc99bdb --- /dev/null +++ b/src/main/java/com/sijobe/spc/network/Config.java @@ -0,0 +1,34 @@ +package com.sijobe.spc.network; + +import java.lang.reflect.Method; + +public final class Config { + static Config[] configs = new Config[256]; + public static final Config BLOCK_REACH = new Config(0, Float.class); + public static final Config NOCLIP = new Config(1, Boolean.class); + public static final Config LIGHT = new Config(2, Boolean.class); + public static final Config INSTANT_MINE = new Config(3, Boolean.class); + public static final Config PREFIX_SLASH = new Config(4, Boolean.class); + public static final Config LONGER_LEGS = new Config(5, Float.class); + public static final Config BIND = new Config(6, Integer.class); + + int id; + Class kind; + private IClientConfig handler; + + private Config(int id, Class kind) { + this.id = id; + this.kind = kind; + configs[this.id] = this; + } + + void callHook(T value) { + if(this.handler != null) { + this.handler.onConfigRecieved(value); + } + } + + public void setHandler(IClientConfig handler) { + this.handler = handler; + } +} diff --git a/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java b/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java new file mode 100644 index 0000000..64fba73 --- /dev/null +++ b/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java @@ -0,0 +1,21 @@ +package com.sijobe.spc.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import cpw.mods.fml.relauncher.Side; + +public class ConfigMessageHandler implements IMessageHandler { + @Override + public IMessage onMessage(PacketConfig message, MessageContext ctx) { + if(ctx.side != Side.CLIENT) { + System.out.println("Config packet handled on server side. Abandon Ship!"); + return null; + } + + if(message.value != null) { + message.config.callHook(message.value); + } + return null; + } +} diff --git a/src/main/java/com/sijobe/spc/network/IClientConfig.java b/src/main/java/com/sijobe/spc/network/IClientConfig.java new file mode 100644 index 0000000..5f3bfc2 --- /dev/null +++ b/src/main/java/com/sijobe/spc/network/IClientConfig.java @@ -0,0 +1,8 @@ +package com.sijobe.spc.network; + +import com.sijobe.spc.core.IHook; + +public interface IClientConfig extends IHook { + public void onConfigRecieved(T value); + Config getConfig(); +} diff --git a/src/main/java/com/sijobe/spc/network/PacketConfig.java b/src/main/java/com/sijobe/spc/network/PacketConfig.java new file mode 100644 index 0000000..0f192f5 --- /dev/null +++ b/src/main/java/com/sijobe/spc/network/PacketConfig.java @@ -0,0 +1,59 @@ +package com.sijobe.spc.network; + +import io.netty.buffer.ByteBuf; +import cpw.mods.fml.common.network.simpleimpl.IMessage; + +public class PacketConfig implements IMessage { + Config config; + Object value; + + public PacketConfig() { + } + + public PacketConfig(Config config, Object value) { + this.config = config; + this.value = value; + if(!this.value.getClass().equals(this.config.kind)) { + throw(new IllegalArgumentException("value must be of type "+this.config.kind.getName()+ + " but instead was of type "+this.value.getClass().getName())); + } + } + + @Override + public void fromBytes(ByteBuf buf) { + byte id = buf.readByte(); + if(id > Config.configs.length || Config.configs[id] == null) { + return; + } + this.config = Config.configs[id]; + if(this.config.kind.equals(Boolean.class)) { + this.value = buf.readBoolean(); + } + else if(this.config.kind.equals(Integer.class)) { + this.value = buf.readInt(); + } + else if(this.config.kind.equals(Double.class)) { + this.value = buf.readDouble(); + } + else if(this.config.kind.equals(Float.class)) { + this.value = buf.readFloat(); + } + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeByte(this.config.id); + if(this.config.kind.equals(Boolean.class)) { + buf.writeBoolean((Boolean) this.value); + } + else if(this.config.kind.equals(Integer.class)) { + buf.writeInt((Integer) this.value); + } + else if(this.config.kind.equals(Double.class)) { + buf.writeDouble((Double) this.value); + } + else if(this.config.kind.equals(Float.class)) { + buf.writeFloat((Float) this.value); + } + } +} diff --git a/src/main/java/com/sijobe/spc/proxy/DummyException.java b/src/main/java/com/sijobe/spc/proxy/DummyException.java new file mode 100644 index 0000000..eec3c3e --- /dev/null +++ b/src/main/java/com/sijobe/spc/proxy/DummyException.java @@ -0,0 +1,5 @@ +package com.sijobe.spc.proxy; + +public class DummyException extends RuntimeException { + +} diff --git a/src/main/java/com/sijobe/spc/proxy/Proxy.java b/src/main/java/com/sijobe/spc/proxy/Proxy.java new file mode 100644 index 0000000..b2c0150 --- /dev/null +++ b/src/main/java/com/sijobe/spc/proxy/Proxy.java @@ -0,0 +1,20 @@ +package com.sijobe.spc.proxy; + +import java.io.File; + +import com.sijobe.spc.core.IBlockBroken; +import com.sijobe.spc.wrapper.Player; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.EnumDifficulty; + +public abstract class Proxy{ + public abstract File getDataDirectory(); + public abstract Player getClientPlayer(); + public abstract boolean shouldNotRenderInsideOfBlock(); + public abstract void setDifficulty(EnumDifficulty difficulty); + public abstract void toggleClientLighting(boolean isLit); + public abstract boolean isClientGuiScreenOpen(); + public abstract void sendClientChat(String string); + public abstract void setClientHitDelay(int delay); +} diff --git a/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java b/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java new file mode 100644 index 0000000..a423848 --- /dev/null +++ b/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java @@ -0,0 +1,107 @@ +package com.sijobe.spc.proxy.client; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.command.ICommandSender; +import net.minecraft.network.Packet; +import net.minecraft.network.play.client.C01PacketChatMessage; +import net.minecraft.util.ChatComponentText; +import net.minecraft.world.EnumDifficulty; + +import com.sijobe.spc.command.InstantMine; +import com.sijobe.spc.proxy.Proxy; +import com.sijobe.spc.util.AccessHelper; +import com.sijobe.spc.wrapper.Block; +import com.sijobe.spc.wrapper.Player; +import com.sijobe.spc.wrapper.World; + +public class ClientProxy extends Proxy { + @Override + public File getDataDirectory() { + return MinecraftClient.getMinecraftDirectory(); + } + + @Override + public Player getClientPlayer() { + return new Player(Minecraft.getMinecraft().thePlayer); + } + + @Override + public boolean shouldNotRenderInsideOfBlock() { + return Minecraft.getMinecraft().thePlayer.noClip; + } + + @Override + public void setDifficulty(EnumDifficulty difficulty) { + Minecraft.getMinecraft().gameSettings.difficulty = difficulty; + } + + @Override + public void toggleClientLighting(boolean isLit) { + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + if(isLit) { + player.addChatMessage(new ChatComponentText("Lighting world")); + float[] lightBrightnessTable = player.worldObj.provider.lightBrightnessTable; + for(int i = 0; i < lightBrightnessTable.length; i++) { + lightBrightnessTable[i] = 1.0F; + } + } else { + player.addChatMessage(new ChatComponentText("Restoring light levels")); + try { + AccessHelper.callMethod(player.worldObj.provider, "generateLightBrightnessTable"); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + @Override + public boolean isClientGuiScreenOpen() { + return MinecraftClient.isGuiScreenOpen(); + } + + @Override + public void sendClientChat(String message) { + NetHandlerPlayClient handler = MinecraftClient.getMinecraft().getNetHandler(); + if(handler != null) { + Packet packet = new C01PacketChatMessage(message); + handler.addToSendQueue(packet); + } + } + + @Override + public void setClientHitDelay(int delay) { + try { + AccessHelper.setInt(Minecraft.getMinecraft().playerController, "blockHitDelay", delay); + } catch (NoSuchFieldException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/wrapper/Minecraft.java b/src/main/java/com/sijobe/spc/proxy/client/MinecraftClient.java similarity index 93% rename from src/main/java/com/sijobe/spc/wrapper/Minecraft.java rename to src/main/java/com/sijobe/spc/proxy/client/MinecraftClient.java index 0a8944a..2f50002 100644 --- a/src/main/java/com/sijobe/spc/wrapper/Minecraft.java +++ b/src/main/java/com/sijobe/spc/proxy/client/MinecraftClient.java @@ -1,14 +1,16 @@ -package com.sijobe.spc.wrapper; +package com.sijobe.spc.proxy.client; import java.io.File; +import com.sijobe.spc.wrapper.Player; + /** * Provides a wrapper around the Minecraft class * * @author simo_415 * @version 1.0 */ -public class Minecraft { +public class MinecraftClient { /** * Gets the directory that Minecraft is installed in diff --git a/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java b/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java new file mode 100644 index 0000000..f3d2036 --- /dev/null +++ b/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java @@ -0,0 +1,67 @@ +package com.sijobe.spc.proxy.server; + +import java.io.File; + +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.server.dedicated.PropertyManager; + +import com.sijobe.spc.proxy.Proxy; +import com.sijobe.spc.util.AccessHelper; +import com.sijobe.spc.wrapper.Block; +import com.sijobe.spc.wrapper.MinecraftServer; +import com.sijobe.spc.wrapper.Player; +import com.sijobe.spc.wrapper.World; + +public class ServerProxy extends Proxy { + + @Override + public File getDataDirectory() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Player getClientPlayer() { + return null; + } + + @Override + public boolean shouldNotRenderInsideOfBlock() { + return false; + } + + @Override + public void setDifficulty(EnumDifficulty difficulty) { + DedicatedServer server = (DedicatedServer) MinecraftServer.getMinecraftServer(); + try { + ((PropertyManager) AccessHelper.getObj(server, "settings")).setProperty("difficulty", difficulty.getDifficultyId()); + } catch (NoSuchFieldException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Override + public void toggleClientLighting(boolean isLit) { + } + + @Override + public boolean isClientGuiScreenOpen() { + return false; + } + + @Override + public void sendClientChat(String string) { + } + + @Override + public void setClientHitDelay(int delay) { + } +} diff --git a/src/main/java/com/sijobe/spc/util/AccessHelper.java b/src/main/java/com/sijobe/spc/util/AccessHelper.java index c2185c5..5f3032c 100644 --- a/src/main/java/com/sijobe/spc/util/AccessHelper.java +++ b/src/main/java/com/sijobe/spc/util/AccessHelper.java @@ -1,6 +1,11 @@ package com.sijobe.spc.util; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.management.ServerConfigurationManager; public class AccessHelper { @@ -19,4 +24,75 @@ public static void setFloat(Object obj, String name, float value) throws NoSuchF field.setAccessible(true); field.setFloat(obj, value); } + + public static void setBoolean(Object obj, String name, boolean value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + Class clazz = obj.getClass(); + Field field; + while(true) + { + try + { + field = clazz.getDeclaredField(name); + break; + } + catch(NoSuchFieldException error) + { + if(clazz == Object.class) + { + throw(error); + } + clazz = clazz.getSuperclass(); + } + } + field.setAccessible(true); + field.setBoolean(obj, value); + } + + public static Object getObj(Object obj, String name) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + Class clazz = obj.getClass(); + Field field; + while(true) + { + try + { + field = clazz.getDeclaredField(name); + break; + } + catch(NoSuchFieldException error) + { + if(clazz == Object.class) + { + throw(error); + } + clazz = clazz.getSuperclass(); + } + } + field.setAccessible(true); + return field.get(obj); + } + + public static T callMethod(Object obj, String name, Object ... args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException + { + Class clazz = obj.getClass(); + Method method; + while(true) + { + try + { + method = clazz.getDeclaredMethod(name); + break; + } + catch(NoSuchMethodException error) + { + if(clazz == Object.class) + { + throw(error); + } + clazz = clazz.getSuperclass(); + } + } + + method.setAccessible(true); + return (T) method.invoke(obj, args); + } } diff --git a/src/main/java/com/sijobe/spc/util/KeyboardHandler.java b/src/main/java/com/sijobe/spc/util/KeyboardHandler.java index e1c39a5..ad036b4 100644 --- a/src/main/java/com/sijobe/spc/util/KeyboardHandler.java +++ b/src/main/java/com/sijobe/spc/util/KeyboardHandler.java @@ -19,7 +19,7 @@ * @see org.lwjgl.input.Keyboard */ public class KeyboardHandler extends Thread { - + /** * The delay in milliseconds that the keyboard events are checked */ @@ -36,12 +36,12 @@ public class KeyboardHandler extends Thread { public static KeyboardHandler getInstance() { return KEYBOARD; } - + /** * Holds the value of whether the instance is currently listening or not */ private boolean listening; - + /** * A List of keys that are currently registered with this listener */ @@ -50,7 +50,7 @@ public static KeyboardHandler getInstance() { * A List of keys that have currently been pressed */ private List pressed; - + /** * A Map containing the registered pressed event listeners */ @@ -59,7 +59,7 @@ public static KeyboardHandler getInstance() { * A Map containing the registered released event listeners */ private Map> registeredReleased; - + /** * Default private constructor sets up the instance */ @@ -70,7 +70,7 @@ private KeyboardHandler() { keys = new CopyOnWriteArrayList(); listening = false; } - + /** * Checks for key press and key release events * @@ -106,7 +106,7 @@ public void run() { listening = false; } } - + /** * Calls all of the necessary listeners based off the key pressed * @@ -121,7 +121,7 @@ private void keyPressed(int key) { listener.keyPressed(key); } } - + /** * Calls all of the necessary listeners based off the key released * @@ -136,14 +136,14 @@ private void keyReleased(int key) { listener.keyReleased(key); } } - + /** * Stops the instance from listening */ public void stopListening() { listening = false; } - + /** * Adds a key press listener to the specified key. See the Keyboard class * for details on the key codes. @@ -156,7 +156,7 @@ public void stopListening() { public boolean addKeyPressedListener(int key, KeyListener listener) { return addListener(key, listener, registeredPressed); } - + /** * Adds a key release listener to the specified key. See the Keyboard class * for details on the key codes. @@ -169,7 +169,7 @@ public boolean addKeyPressedListener(int key, KeyListener listener) { public boolean addKeyReleasedListener(int key, KeyListener listener) { return addListener(key, listener, registeredReleased); } - + /** * Generic implementation that adds the specified key and listener to the * provided internal listener map. @@ -220,7 +220,7 @@ public void removeKeyPressedListener(int key, KeyListener listener) { public void removeKeyReleasedListener(int key, KeyListener listener) { removeListener(key, listener, registeredReleased); } - + /** * Removes the specified key and listener instance from the specified Map * listener. @@ -242,7 +242,7 @@ private void removeListener(int key, KeyListener listener, Map conversionRegistry = new HashMap(); public static final RegistryNamespaced realBlockRegistry = net.minecraft.block.Block.blockRegistry; @@ -18,8 +20,9 @@ public static void init() for(Object i : realBlockRegistry) { net.minecraft.block.Block block = (net.minecraft.block.Block) i; + int id = realBlockRegistry.getIDForObject(block); Block wrapped = new Block(block); - blockRegistry.putObject(realBlockRegistry.getNameForObject(block), wrapped); + blockRegistry.addObject(id, realBlockRegistry.getNameForObject(block), wrapped); conversionRegistry.put(block, wrapped); } Blocks.init(); diff --git a/src/main/java/com/sijobe/spc/wrapper/CommandBase.java b/src/main/java/com/sijobe/spc/wrapper/CommandBase.java index c16f8ba..10f11ab 100644 --- a/src/main/java/com/sijobe/spc/wrapper/CommandBase.java +++ b/src/main/java/com/sijobe/spc/wrapper/CommandBase.java @@ -332,7 +332,7 @@ public static Settings loadSettings(Player player) { if (player == null) { return null; } - String directoryName = MinecraftServer.getDirectoryName(); + String directoryName = MinecraftServer.getWorldFolder(); SettingsManager manager = MANAGER.get(directoryName); if (manager == null) { File spcPlayers = new File(MinecraftServer.getWorldDirectory(), "spc/players"); diff --git a/src/main/java/com/sijobe/spc/wrapper/Item.java b/src/main/java/com/sijobe/spc/wrapper/Item.java index 133d11a..91a5347 100644 --- a/src/main/java/com/sijobe/spc/wrapper/Item.java +++ b/src/main/java/com/sijobe/spc/wrapper/Item.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Map; +import com.sijobe.spc.util.RegistryIdCompatible; + import net.minecraft.enchantment.Enchantment; import net.minecraft.item.ItemStack; import net.minecraft.util.RegistryNamespaced; @@ -16,7 +18,7 @@ public class Item { /** * A list of item names that are loaded in the game */ - public static final RegistryNamespaced itemRegistry = new RegistryNamespaced(); + public static final RegistryNamespaced itemRegistry = new RegistryIdCompatible(); public static final Map conversionRegistry = new HashMap(); public static final RegistryNamespaced realItemRegistry = net.minecraft.item.Item.itemRegistry; @@ -25,8 +27,9 @@ public static void init() for (Object i : net.minecraft.item.Item.itemRegistry) { net.minecraft.item.Item item = (net.minecraft.item.Item) i; + int id = realItemRegistry.getIDForObject(item); Item wrapped = new Item(item); - itemRegistry.putObject(realItemRegistry.getNameForObject(item), wrapped); + itemRegistry.addObject(id, realItemRegistry.getNameForObject(item), wrapped); conversionRegistry.put(item, wrapped); } } @@ -61,14 +64,7 @@ public net.minecraft.item.Item convert() * @return the id of the item. If the item doesn't exist null is returned */ public static Item getItem(String itemName) { - if(itemRegistry.containsKey(itemName)) - { - return (Item) itemRegistry.getObject(itemName); - } - else - { - return null; - } + return (Item) itemRegistry.getObject(itemName); } /*returns the converts the item to a minecraft item*/ @@ -84,7 +80,7 @@ public static Item getItem(net.minecraft.item.Item item) * @return true is returned if the id is valid, false otherwise */ public static boolean isValidItem(Item item) { - return itemRegistry.containsKey(itemRegistry.getNameForObject(item)); + return !(item == null) && itemRegistry.containsKey(itemRegistry.getNameForObject(item)); } /**TODO: remove arguement diff --git a/src/main/java/com/sijobe/spc/wrapper/MinecraftServer.java b/src/main/java/com/sijobe/spc/wrapper/MinecraftServer.java index 02cd6de..8d1fae0 100644 --- a/src/main/java/com/sijobe/spc/wrapper/MinecraftServer.java +++ b/src/main/java/com/sijobe/spc/wrapper/MinecraftServer.java @@ -1,10 +1,15 @@ package com.sijobe.spc.wrapper; import java.io.File; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; +import com.sijobe.spc.ModSpc; import com.sijobe.spc.core.Constants; +import com.sijobe.spc.util.AccessHelper; + +import cpw.mods.fml.relauncher.Side; /** * Wrapper around the MinecraftServer class providing. @@ -12,7 +17,7 @@ * @author simo_415 */ public class MinecraftServer { - + /** * Gets the instance of the Minecraft server that is running * @@ -88,7 +93,7 @@ public static String runCommand(String command) { * * @return The directory name of the world */ - public static String getDirectoryName() { + public static String getDirectoryName_() { return getMinecraftServer().getFolderName(); } @@ -98,6 +103,47 @@ public static String getDirectoryName() { * @return The location where the world is located */ public static File getWorldDirectory() { - return new File(Constants.SAVES_DIR, getDirectoryName()); + return new File(Constants.SAVES_DIR, getWorldFolder()); + } + + public static String getWorldFolder() { + return getMinecraftServer().getFolderName(); + } + + public static String getDirectoryName() { + if(ModSpc.instance.side == Side.SERVER) { + String dir = null; + try { + dir = ((File) AccessHelper.callMethod(getMinecraftServer(), "getDataDirectory")).getAbsolutePath(); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if(dir == null) { + return dir; + } + if(dir.endsWith(".")) { + dir = dir.substring(0, dir.length()-1); + } + return dir; + } + else if(ModSpc.instance.side == Side.CLIENT){ + return ModSpc.instance.proxy.getDataDirectory().getAbsolutePath(); + } + else { + return null; + } } -} +} \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/wrapper/World.java b/src/main/java/com/sijobe/spc/wrapper/World.java index d80c3b9..e569192 100644 --- a/src/main/java/com/sijobe/spc/wrapper/World.java +++ b/src/main/java/com/sijobe/spc/wrapper/World.java @@ -3,6 +3,9 @@ import java.lang.reflect.Field; import java.util.Random; +import com.sijobe.spc.ModSpc; +import com.sijobe.spc.util.AccessHelper; + import net.minecraft.client.settings.GameSettings; import net.minecraft.entity.effect.EntityLightningBolt; @@ -108,6 +111,21 @@ public boolean isCheats() { */ public void setCheats(boolean cheats) { changeWorldInfo("allowCommands", cheats); + try { + AccessHelper.setBoolean(MinecraftServer.getMinecraftServer().getConfigurationManager(), "commandsAllowedForAll", cheats); + } catch (NoSuchFieldException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } /** @@ -148,8 +166,7 @@ private void changeWorldInfo(String key, Object value) { * @return The difficulty of the world */ public EnumDifficulty getDifficulty() { - GameSettings settings = Minecraft.getMinecraft().gameSettings; - return settings.difficulty; + return MinecraftServer.getMinecraftServer().func_147135_j(); } /** @@ -158,8 +175,8 @@ public EnumDifficulty getDifficulty() { * @param difficulty - The difficulty of the world */ public void setDifficulty(EnumDifficulty difficulty) { - GameSettings settings = Minecraft.getMinecraft().gameSettings; - settings.setOptionValue(GameSettings.Options.DIFFICULTY, difficulty.getDifficultyId()-this.getDifficulty().getDifficultyId()); + MinecraftServer.getMinecraftServer().func_147139_a(difficulty); + ModSpc.instance.proxy.setDifficulty(difficulty); } /** From 9b3130e567ccb738d43820b0c11dad7981fa739c Mon Sep 17 00:00:00 2001 From: aucguy Date: Sat, 6 Dec 2014 23:10:51 -0600 Subject: [PATCH 15/20] fixed warnings and removed unused classes --- src/main/java/com/sijobe/spc/ModSpc.java | 9 +- .../com/sijobe/spc/asm/MethodPrefixer.java | 2 - .../com/sijobe/spc/asm/MethodReplacer.java | 2 - .../com/sijobe/spc/asm/MethodTransformer.java | 2 - .../com/sijobe/spc/asm/SlashPrefixer.java | 1 - .../com/sijobe/spc/command/Achievement.java | 1 - .../java/com/sijobe/spc/command/Bind.java | 5 - .../com/sijobe/spc/command/BlockReach.java | 2 +- .../java/com/sijobe/spc/command/Bring.java | 1 - .../com/sijobe/spc/command/Difficulty.java | 1 - .../java/com/sijobe/spc/command/DoDrops.java | 1 - .../com/sijobe/spc/command/InstantMine.java | 3 - .../java/com/sijobe/spc/command/Keypress.java | 11 +- .../java/com/sijobe/spc/command/KillAll.java | 1 - .../java/com/sijobe/spc/command/Light.java | 4 +- .../java/com/sijobe/spc/command/Macro.java | 3 - .../java/com/sijobe/spc/command/Noclip.java | 59 +-- .../java/com/sijobe/spc/command/Path.java | 1 - .../java/com/sijobe/spc/command/SetSpeed.java | 4 - .../com/sijobe/spc/command/SpawnPortal.java | 3 - .../sijobe/spc/command/StandardCommand.java | 1 - .../com/sijobe/spc/command/SuperHeat.java | 6 - .../com/sijobe/spc/command/UsePortal.java | 1 - .../java/com/sijobe/spc/core/Constants.java | 2 - .../com/sijobe/spc/hooks/WorldEditCUI.java | 3 - .../java/com/sijobe/spc/network/Config.java | 20 +- .../com/sijobe/spc/network/PacketConfig.java | 2 +- .../spc/overwrite/ONetServerHandler.java | 337 ------------------ .../com/sijobe/spc/proxy/DummyException.java | 5 - src/main/java/com/sijobe/spc/proxy/Proxy.java | 2 - .../sijobe/spc/proxy/client/ClientProxy.java | 4 - .../sijobe/spc/proxy/server/ServerProxy.java | 2 - .../com/sijobe/spc/updater/CheckVersion.java | 1 + .../com/sijobe/spc/util/AccessHelper.java | 16 +- .../sijobe/spc/util/DynamicClassLoader.java | 8 - .../java/com/sijobe/spc/util/ForgeHelper.java | 3 +- .../java/com/sijobe/spc/wrapper/Block.java | 1 - .../sijobe/spc/wrapper/CommandManager.java | 2 + .../java/com/sijobe/spc/wrapper/Entity.java | 2 + .../java/com/sijobe/spc/wrapper/World.java | 2 - .../com/sijobe/spc/asm/make/ItemRenderer.java | 12 + 41 files changed, 53 insertions(+), 495 deletions(-) delete mode 100644 src/main/java/com/sijobe/spc/overwrite/ONetServerHandler.java delete mode 100644 src/main/java/com/sijobe/spc/proxy/DummyException.java create mode 100644 src/make/com/sijobe/spc/asm/make/ItemRenderer.java diff --git a/src/main/java/com/sijobe/spc/ModSpc.java b/src/main/java/com/sijobe/spc/ModSpc.java index 10d2f4a..bca06cf 100644 --- a/src/main/java/com/sijobe/spc/ModSpc.java +++ b/src/main/java/com/sijobe/spc/ModSpc.java @@ -1,10 +1,8 @@ package com.sijobe.spc; -import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.event.entity.player.PlayerEvent.BreakSpeed; import net.minecraftforge.event.world.BlockEvent.BreakEvent; import cpw.mods.fml.common.FMLCommonHandler; @@ -19,14 +17,9 @@ import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.relauncher.Side; -import com.google.common.eventbus.Subscribe; - -import com.sijobe.spc.core.Constants; import com.sijobe.spc.core.HookManager; import com.sijobe.spc.core.IBlockBroken; import com.sijobe.spc.core.IBreakSpeed; -import com.sijobe.spc.core.IHook; -import com.sijobe.spc.util.DynamicClassLoader; import com.sijobe.spc.wrapper.Block; import com.sijobe.spc.wrapper.Item; import com.sijobe.spc.wrapper.Player; @@ -143,7 +136,7 @@ public void loadClientSettingHooks() { if(hook.isEnabled()) { - hook.getConfig().setHandler(hook); + hook.getConfig().setHandler((IClientConfig) hook); } } } diff --git a/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java b/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java index 944abbb..f60d0df 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java +++ b/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java @@ -4,9 +4,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import org.objectweb.asm.MethodVisitor; diff --git a/src/main/java/com/sijobe/spc/asm/MethodReplacer.java b/src/main/java/com/sijobe/spc/asm/MethodReplacer.java index 86c3564..57ab1dd 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodReplacer.java +++ b/src/main/java/com/sijobe/spc/asm/MethodReplacer.java @@ -4,9 +4,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import org.objectweb.asm.MethodVisitor; diff --git a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java index 9c16586..c9982ff 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java +++ b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java @@ -36,14 +36,12 @@ static MethodTransformer[] generateFromFunctions(Class clazz) { String annotation = method.getAnnotation(MethodReplacer.Hook.class).value(); System.out.println("found replacement for "+annotation); - String cl = annotation.split(":", 2)[0]; modifiers.add(new MethodReplacer(annotation, method)); } else if(method.isAnnotationPresent(MethodPrefixer.Hook.class)) { String annotation = method.getAnnotation(MethodPrefixer.Hook.class).value(); System.out.println("found prefix for "+annotation); - String cl = annotation.split(":", 2)[0]; modifiers.add(new MethodPrefixer(annotation, method)); } } diff --git a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java index 186dcbe..faa0cf4 100644 --- a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java +++ b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java @@ -1,6 +1,5 @@ package com.sijobe.spc.asm; -import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import com.sijobe.spc.command.PrefixSlash; diff --git a/src/main/java/com/sijobe/spc/command/Achievement.java b/src/main/java/com/sijobe/spc/command/Achievement.java index be7f174..f78949a 100644 --- a/src/main/java/com/sijobe/spc/command/Achievement.java +++ b/src/main/java/com/sijobe/spc/command/Achievement.java @@ -5,7 +5,6 @@ import com.sijobe.spc.validation.ParameterString; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.MinecraftServer; import com.sijobe.spc.wrapper.Player; import com.sijobe.spc.wrapper.Stats; diff --git a/src/main/java/com/sijobe/spc/command/Bind.java b/src/main/java/com/sijobe/spc/command/Bind.java index 82ab2ab..1d620a3 100644 --- a/src/main/java/com/sijobe/spc/command/Bind.java +++ b/src/main/java/com/sijobe/spc/command/Bind.java @@ -1,11 +1,9 @@ package com.sijobe.spc.command; import com.sijobe.spc.ModSpc; -import com.sijobe.spc.core.Constants; import com.sijobe.spc.network.Config; import com.sijobe.spc.network.IClientConfig; import com.sijobe.spc.network.PacketConfig; -import com.sijobe.spc.proxy.client.MinecraftClient; import com.sijobe.spc.util.FontColour; import com.sijobe.spc.util.KeyListener; import com.sijobe.spc.util.KeyboardHandler; @@ -15,12 +13,9 @@ import com.sijobe.spc.validation.ParameterString; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandException; -import com.sijobe.spc.wrapper.CommandManager; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.MinecraftServer; import com.sijobe.spc.wrapper.Player; -import java.io.File; import java.util.List; import org.lwjgl.input.Keyboard; diff --git a/src/main/java/com/sijobe/spc/command/BlockReach.java b/src/main/java/com/sijobe/spc/command/BlockReach.java index 9094794..a5378cc 100644 --- a/src/main/java/com/sijobe/spc/command/BlockReach.java +++ b/src/main/java/com/sijobe/spc/command/BlockReach.java @@ -82,7 +82,7 @@ public void onConfigRecieved(Float value) { } @Override - public Config getConfig() { + public Config getConfig() { return Config.BLOCK_REACH; } } diff --git a/src/main/java/com/sijobe/spc/command/Bring.java b/src/main/java/com/sijobe/spc/command/Bring.java index dd42f6f..48f0551 100644 --- a/src/main/java/com/sijobe/spc/command/Bring.java +++ b/src/main/java/com/sijobe/spc/command/Bring.java @@ -8,7 +8,6 @@ import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Entity; import com.sijobe.spc.wrapper.Player; -import net.minecraft.entity.player.EntityPlayerMP; import java.util.List; diff --git a/src/main/java/com/sijobe/spc/command/Difficulty.java b/src/main/java/com/sijobe/spc/command/Difficulty.java index 3bf02bb..9669ed9 100644 --- a/src/main/java/com/sijobe/spc/command/Difficulty.java +++ b/src/main/java/com/sijobe/spc/command/Difficulty.java @@ -43,7 +43,6 @@ public class Difficulty extends StandardCommand { @Override public void execute(CommandSender sender, List params) throws CommandException { World world = super.getSenderAsPlayer(sender).getWorld(); - int change; if (params.size() > 0) { world.setDifficulty(EnumDifficulty.getDifficultyEnum((Integer)params.get(0))); } else { diff --git a/src/main/java/com/sijobe/spc/command/DoDrops.java b/src/main/java/com/sijobe/spc/command/DoDrops.java index 6aed7cc..e24212d 100644 --- a/src/main/java/com/sijobe/spc/command/DoDrops.java +++ b/src/main/java/com/sijobe/spc/command/DoDrops.java @@ -5,7 +5,6 @@ import com.sijobe.spc.wrapper.CommandBase; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Coordinate; import com.sijobe.spc.wrapper.Player; import java.util.List; diff --git a/src/main/java/com/sijobe/spc/command/InstantMine.java b/src/main/java/com/sijobe/spc/command/InstantMine.java index 315688f..4b07653 100644 --- a/src/main/java/com/sijobe/spc/command/InstantMine.java +++ b/src/main/java/com/sijobe/spc/command/InstantMine.java @@ -5,8 +5,6 @@ import com.sijobe.spc.core.IBreakSpeed; import com.sijobe.spc.network.Config; import com.sijobe.spc.network.IClientConfig; -import com.sijobe.spc.util.AccessHelper; -import com.sijobe.spc.util.ForgeHelper; import com.sijobe.spc.util.Settings; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.Block; @@ -17,7 +15,6 @@ import java.util.List; -import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.entity.player.EntityPlayerMP; /** diff --git a/src/main/java/com/sijobe/spc/command/Keypress.java b/src/main/java/com/sijobe/spc/command/Keypress.java index 8719259..d170f3c 100644 --- a/src/main/java/com/sijobe/spc/command/Keypress.java +++ b/src/main/java/com/sijobe/spc/command/Keypress.java @@ -2,17 +2,13 @@ import java.util.List; -import net.minecraft.entity.player.EntityPlayer; - import com.sijobe.spc.util.Settings; import com.sijobe.spc.validation.Parameter; import com.sijobe.spc.validation.ParameterInteger; -import com.sijobe.spc.validation.ParameterString; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandManager; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.MinecraftServer; /** * Executes the command bound to the given key. @@ -32,10 +28,15 @@ public class Keypress extends StandardCommand { new ParameterInteger("[keycode]",true) } ); + + @Override + public Parameters getParameters() { + return PARAMETERS; + } @Override public void execute(CommandSender sender, List params) throws CommandException { - Settings settings = this.loadSettings(getSenderAsPlayer(sender)); + Settings settings = loadSettings(getSenderAsPlayer(sender)); String command = settings.getProperty(Bind.SETTINGS_PREFIX+params.get(0)); CommandManager.runCommand(sender, command); } diff --git a/src/main/java/com/sijobe/spc/command/KillAll.java b/src/main/java/com/sijobe/spc/command/KillAll.java index 8ec4e54..0e0a44a 100644 --- a/src/main/java/com/sijobe/spc/command/KillAll.java +++ b/src/main/java/com/sijobe/spc/command/KillAll.java @@ -8,7 +8,6 @@ import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Entity; import com.sijobe.spc.wrapper.Player; -import net.minecraft.entity.player.EntityPlayerMP; import java.util.List; diff --git a/src/main/java/com/sijobe/spc/command/Light.java b/src/main/java/com/sijobe/spc/command/Light.java index 7c9b1ad..f63df7a 100644 --- a/src/main/java/com/sijobe/spc/command/Light.java +++ b/src/main/java/com/sijobe/spc/command/Light.java @@ -36,7 +36,7 @@ public class Light extends StandardCommand implements IClientConfig { @Override public void execute(CommandSender sender, List params) throws CommandException { Player player = super.getSenderAsPlayer(sender); // Why super.? Meh, Cannon has it like that - Settings config = this.loadSettings(player); + Settings config = loadSettings(player); boolean lit = !config.getBoolean("light", false); config.set("light", lit); ModSpc.instance.networkHandler.sendTo(new PacketConfig(this.getConfig(), lit), (EntityPlayerMP) player.getMinecraftPlayer()); @@ -52,7 +52,7 @@ public void onConfigRecieved(Boolean value) { } @Override - public Config getConfig() { + public Config getConfig() { return Config.LIGHT; } } diff --git a/src/main/java/com/sijobe/spc/command/Macro.java b/src/main/java/com/sijobe/spc/command/Macro.java index eb8369b..03150b6 100644 --- a/src/main/java/com/sijobe/spc/command/Macro.java +++ b/src/main/java/com/sijobe/spc/command/Macro.java @@ -10,13 +10,10 @@ import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Player; -import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; -import java.io.Reader; import java.util.List; /** diff --git a/src/main/java/com/sijobe/spc/command/Noclip.java b/src/main/java/com/sijobe/spc/command/Noclip.java index 3aff61d..822e506 100644 --- a/src/main/java/com/sijobe/spc/command/Noclip.java +++ b/src/main/java/com/sijobe/spc/command/Noclip.java @@ -1,10 +1,10 @@ package com.sijobe.spc.command; import com.sijobe.spc.ModSpc; +import com.sijobe.spc.core.IPlayerMP; import com.sijobe.spc.network.Config; import com.sijobe.spc.network.IClientConfig; import com.sijobe.spc.network.PacketConfig; -import com.sijobe.spc.overwrite.ONetServerHandler; import com.sijobe.spc.util.FontColour; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandBase; @@ -15,11 +15,8 @@ import java.util.List; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.server.MinecraftServer; import net.minecraft.util.ChatComponentText; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.network.NetHandlerPlayServer; /** * Command for disabling clipping @@ -35,7 +32,7 @@ videoURL = "http://www.youtube.com/watch?v=4ZOvu3hf7k0", // video for fly command enabled = true ) -public class Noclip extends StandardCommand implements IClientConfig { +public class Noclip extends StandardCommand implements IPlayerMP, IClientConfig { @Override public void execute(CommandSender sender, List params) throws CommandException { @@ -54,14 +51,6 @@ public void execute(CommandSender sender, List params) throws CommandExceptio player.getMinecraftPlayer().noClip = (Boolean)params.get(0); } - // replace server handler - if(player.getMinecraftPlayer() instanceof EntityPlayerMP) { - updateServerHandler((EntityPlayerMP)player.getMinecraftPlayer()); - } else { - player.getMinecraftPlayer().noClip = false; - throw new CommandException("Noclip unavailable"); - } - if(player.getMinecraftPlayer().noClip == false) { ascendPlayer(player); } @@ -74,48 +63,11 @@ public Parameters getParameters() { return Parameters.DEFAULT_BOOLEAN; } - private static boolean hasXCommands() { - try { - NetHandlerPlayServer.class.getDeclaredField("clientHasXCommands"); - return true; - } catch (Throwable t) { - return false; - } - } - - /** - * Changes server handler to SPC's server handler if noclip is enabled, - * otherwise restores the default server handler. - */ - private static void updateServerHandler(EntityPlayerMP playerEntity) { - if(hasXCommands()) { - return; - } - - NetHandlerPlayServer handler = playerEntity.playerNetServerHandler; - - if(playerEntity.noClip) { - if(!(handler instanceof ONetServerHandler)) { - playerEntity.playerNetServerHandler = new ONetServerHandler(MinecraftServer.getServer(), - handler.netManager, handler.playerEntity, handler); - } - } else { - if(handler instanceof ONetServerHandler) { - NetHandlerPlayServer oldInstance = ((ONetServerHandler)handler).getOldInstance(); - if(oldInstance != null) { - handler.netManager.setNetHandler(oldInstance); - playerEntity.playerNetServerHandler = oldInstance; - } - } - } - } - public static void checkSafe(EntityPlayerMP player) { if(player.noClip && !player.capabilities.isFlying) { player.noClip = false; ModSpc.instance.networkHandler.sendTo(new PacketConfig(Config.NOCLIP, false), player); player.addChatMessage(new ChatComponentText("Noclip auto-disabled. (Player not flying)")); - updateServerHandler(player); ascendPlayer(new Player(player)); } } @@ -152,7 +104,12 @@ public void onConfigRecieved(Boolean value) { } @Override - public Config getConfig() { + public Config getConfig() { return Config.NOCLIP; } + + @Override + public void onTick(Player player) { + checkSafe((EntityPlayerMP) player.getMinecraftPlayer()); + } } \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/command/Path.java b/src/main/java/com/sijobe/spc/command/Path.java index 51bb82b..d8a2d46 100644 --- a/src/main/java/com/sijobe/spc/command/Path.java +++ b/src/main/java/com/sijobe/spc/command/Path.java @@ -11,7 +11,6 @@ import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Coordinate; -import com.sijobe.spc.wrapper.Item; import com.sijobe.spc.wrapper.Player; import java.util.HashMap; diff --git a/src/main/java/com/sijobe/spc/command/SetSpeed.java b/src/main/java/com/sijobe/spc/command/SetSpeed.java index cdb512e..12e83b7 100644 --- a/src/main/java/com/sijobe/spc/command/SetSpeed.java +++ b/src/main/java/com/sijobe/spc/command/SetSpeed.java @@ -8,13 +8,9 @@ import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Coordinate; -import com.sijobe.spc.wrapper.Player; import java.util.List; -import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.PlayerCapabilities; /** diff --git a/src/main/java/com/sijobe/spc/command/SpawnPortal.java b/src/main/java/com/sijobe/spc/command/SpawnPortal.java index bdb92c6..56446c8 100644 --- a/src/main/java/com/sijobe/spc/command/SpawnPortal.java +++ b/src/main/java/com/sijobe/spc/command/SpawnPortal.java @@ -10,10 +10,7 @@ import com.sijobe.spc.wrapper.World; import com.sijobe.spc.wrapper.Blocks; -import java.lang.reflect.Method; - import net.minecraft.block.BlockEndPortal; -import net.minecraft.entity.boss.EntityDragon; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.MathHelper; import net.minecraft.world.Teleporter; diff --git a/src/main/java/com/sijobe/spc/command/StandardCommand.java b/src/main/java/com/sijobe/spc/command/StandardCommand.java index f27229c..8404ef0 100644 --- a/src/main/java/com/sijobe/spc/command/StandardCommand.java +++ b/src/main/java/com/sijobe/spc/command/StandardCommand.java @@ -1,7 +1,6 @@ package com.sijobe.spc.command; import com.sijobe.spc.wrapper.CommandBase; -import com.sijobe.spc.wrapper.CommandSender; /** * Provides an abstract class for a standard (single) command to extend diff --git a/src/main/java/com/sijobe/spc/command/SuperHeat.java b/src/main/java/com/sijobe/spc/command/SuperHeat.java index 8927e9b..3f9f054 100644 --- a/src/main/java/com/sijobe/spc/command/SuperHeat.java +++ b/src/main/java/com/sijobe/spc/command/SuperHeat.java @@ -5,11 +5,9 @@ import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Item; import com.sijobe.spc.wrapper.Player; import java.util.List; -import java.util.Map; import net.minecraft.item.crafting.FurnaceRecipes; import net.minecraft.item.ItemStack; @@ -40,9 +38,6 @@ public class SuperHeat extends StandardCommand { @Override public void execute(CommandSender sender, List params) throws CommandException { - @SuppressWarnings("unchecked") - Map smelt = FurnaceRecipes.smelting().getSmeltingList(); - Player player = getSenderAsPlayer(sender); boolean all = false; @@ -61,7 +56,6 @@ public void execute(CommandSender sender, List params) throws CommandExceptio continue; } - net.minecraft.item.Item key = oldStack.getItem(); ItemStack newStack = FurnaceRecipes.smelting().getSmeltingResult(oldStack); if (newStack != null) { int amt = oldStack.stackSize; diff --git a/src/main/java/com/sijobe/spc/command/UsePortal.java b/src/main/java/com/sijobe/spc/command/UsePortal.java index 5d97776..0c60380 100644 --- a/src/main/java/com/sijobe/spc/command/UsePortal.java +++ b/src/main/java/com/sijobe/spc/command/UsePortal.java @@ -7,7 +7,6 @@ import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.wrapper.CommandException; import com.sijobe.spc.wrapper.CommandSender; -import com.sijobe.spc.wrapper.Entity; import com.sijobe.spc.wrapper.Player; /** diff --git a/src/main/java/com/sijobe/spc/core/Constants.java b/src/main/java/com/sijobe/spc/core/Constants.java index c070779..f7ee7ab 100644 --- a/src/main/java/com/sijobe/spc/core/Constants.java +++ b/src/main/java/com/sijobe/spc/core/Constants.java @@ -7,8 +7,6 @@ import java.io.File; import java.util.Date; -import net.minecraft.server.integrated.IntegratedServer; - /** * Contains all of the constant values that the mod uses * diff --git a/src/main/java/com/sijobe/spc/hooks/WorldEditCUI.java b/src/main/java/com/sijobe/spc/hooks/WorldEditCUI.java index b1f6950..90c4ce0 100644 --- a/src/main/java/com/sijobe/spc/hooks/WorldEditCUI.java +++ b/src/main/java/com/sijobe/spc/hooks/WorldEditCUI.java @@ -5,8 +5,6 @@ import com.sijobe.spc.util.WorldEditCUIHelper; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.Iterator; -import java.util.LinkedList; import java.util.List; public class WorldEditCUI implements ICUIEventHandler { @@ -119,7 +117,6 @@ private Object getWorldEditCUIMod() { return null; } - @SuppressWarnings("unchecked") private boolean setWorldEditCUIMod() { WorldEditCUIMod = getWorldEditCUIMod(); return (WorldEditCUIMod != null); diff --git a/src/main/java/com/sijobe/spc/network/Config.java b/src/main/java/com/sijobe/spc/network/Config.java index cc99bdb..6f6f505 100644 --- a/src/main/java/com/sijobe/spc/network/Config.java +++ b/src/main/java/com/sijobe/spc/network/Config.java @@ -1,20 +1,18 @@ package com.sijobe.spc.network; -import java.lang.reflect.Method; - public final class Config { - static Config[] configs = new Config[256]; - public static final Config BLOCK_REACH = new Config(0, Float.class); - public static final Config NOCLIP = new Config(1, Boolean.class); - public static final Config LIGHT = new Config(2, Boolean.class); - public static final Config INSTANT_MINE = new Config(3, Boolean.class); - public static final Config PREFIX_SLASH = new Config(4, Boolean.class); - public static final Config LONGER_LEGS = new Config(5, Float.class); - public static final Config BIND = new Config(6, Integer.class); + static Config[] configs = new Config[256]; + public static final Config BLOCK_REACH = new Config(0, Float.class); + public static final Config NOCLIP = new Config(1, Boolean.class); + public static final Config LIGHT = new Config(2, Boolean.class); + public static final Config INSTANT_MINE = new Config(3, Boolean.class); + public static final Config PREFIX_SLASH = new Config(4, Boolean.class); + public static final Config LONGER_LEGS = new Config(5, Float.class); + public static final Config BIND = new Config(6, Integer.class); int id; Class kind; - private IClientConfig handler; + private IClientConfig handler; private Config(int id, Class kind) { this.id = id; diff --git a/src/main/java/com/sijobe/spc/network/PacketConfig.java b/src/main/java/com/sijobe/spc/network/PacketConfig.java index 0f192f5..4d33634 100644 --- a/src/main/java/com/sijobe/spc/network/PacketConfig.java +++ b/src/main/java/com/sijobe/spc/network/PacketConfig.java @@ -10,7 +10,7 @@ public class PacketConfig implements IMessage { public PacketConfig() { } - public PacketConfig(Config config, Object value) { + public PacketConfig(Config config, Object value) { this.config = config; this.value = value; if(!this.value.getClass().equals(this.config.kind)) { diff --git a/src/main/java/com/sijobe/spc/overwrite/ONetServerHandler.java b/src/main/java/com/sijobe/spc/overwrite/ONetServerHandler.java deleted file mode 100644 index 7beb31a..0000000 --- a/src/main/java/com/sijobe/spc/overwrite/ONetServerHandler.java +++ /dev/null @@ -1,337 +0,0 @@ -package com.sijobe.spc.overwrite; - -import com.sijobe.spc.command.Noclip; -import com.sijobe.spc.util.ForgeHelper; -import com.sijobe.spc.util.Mappings; -import com.sijobe.spc.util.ReflectionHelper; - -import java.lang.reflect.Field; -import java.util.HashMap; - -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.network.NetworkManager; -import net.minecraft.network.play.client.C03PacketPlayer; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.world.WorldServer; - -/** - * Custom server handler to allow noclip - * Note: use of reflection is neccessary, - * otherwise player cannot interact with world - * - * @author q3hardcore - * @version 1.4 - */ -public final class ONetServerHandler extends NetHandlerPlayServer { - - private final NetHandlerPlayServer oldInstance; - private final MinecraftServer mcServer; - private int ticksForFloatKick; - private double lastPosX; - private double lastPosY; - private double lastPosZ; - private boolean hasMoved = true; - - private static final HashMap fieldMappings; - - // mappings valid as of: Minecraft 1.5.2 (no changes) - static { - fieldMappings = new Mappings(); - fieldMappings.put("lastPosX", new String[]{"n", "field_72579_o"}); - fieldMappings.put("lastPosY", new String[]{"o", "field_72589_p"}); - fieldMappings.put("lastPosZ", new String[]{"p", "field_72588_q"}); - fieldMappings.put("hasMoved", new String[]{"q", "field_72587_r"}); - } - - public ONetServerHandler(MinecraftServer par1, NetworkManager par2, EntityPlayerMP par3, NetHandlerPlayServer instance) { - super(par1, par2, par3); - - if(instance instanceof ONetServerHandler) { - throw new RuntimeException("SPC: Critical error encountered!"); - } - - oldInstance = instance; - mcServer = par1; - //connectionClosed = oldInstance.connectionClosed; //probably unnecessary for 1.7.2 - } - - public NetHandlerPlayServer getOldInstance() { - return oldInstance; - } - - private void updateHasMoved() { - Field field = ReflectionHelper.getField(oldInstance, fieldMappings.get("hasMoved")); - this.hasMoved = ReflectionHelper.getBoolean(field, oldInstance); - } - - private void updatePosition() { - Field field; - field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosX")); - this.lastPosX = ReflectionHelper.getDouble(field, oldInstance); - field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosY")); - this.lastPosY = ReflectionHelper.getDouble(field, oldInstance); - field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosZ")); - this.lastPosZ = ReflectionHelper.getDouble(field, oldInstance); - } - - private void setHasMoved(boolean bool) { - Field field = ReflectionHelper.getField(oldInstance, fieldMappings.get("hasMoved")); - ReflectionHelper.setField(field, oldInstance, bool); - } - - private void setPosition(double x, double y, double z) { - Field field; - field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosX")); - ReflectionHelper.setField(field, oldInstance, x); - field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosY")); - ReflectionHelper.setField(field, oldInstance, y); - field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosZ")); - ReflectionHelper.setField(field, oldInstance, z); - } - - @Override - public void processPlayer(C03PacketPlayer packet) //don't know equivalant packet in 1.7.2 - { - // we use Forge's handleFlying method - if(!ForgeHelper.HAS_FORGE) { //TODO remove this - updateHasMoved(); - updatePosition(); - } - - Noclip.checkSafe(this.playerEntity); - - // Forge has Noclip support - if(ForgeHelper.HAS_FORGE) { - super.processPlayer(packet); - return; - } - - /* removed since spc now needs forge - WorldServer var2 = this.mcServer.worldServerForDimension(oldInstance.playerEntity.dimension); - - if (!oldInstance.playerEntity.playerConqueredTheEnd) - { - double var3; - - if (!hasMoved) - { - var3 = packet.yPosition - lastPosY; - - if (packet.xPosition == lastPosX && var3 * var3 < 0.01D && packet.zPosition == lastPosZ) - { - setHasMoved(true); - hasMoved = true; - } - } - - if (hasMoved) - { - double var5; - double var7; - double var9; - double var13; - - if (oldInstance.playerEntity.ridingEntity != null) - { - float var34 = oldInstance.playerEntity.rotationYaw; - float var4 = oldInstance.playerEntity.rotationPitch; - oldInstance.playerEntity.ridingEntity.updateRiderPosition(); - var5 = oldInstance.playerEntity.posX; - var7 = oldInstance.playerEntity.posY; - var9 = oldInstance.playerEntity.posZ; - double var35 = 0.0D; - var13 = 0.0D; - - if (packet.rotating) - { - var34 = packet.yaw; - var4 = packet.pitch; - } - - if (packet.moving && packet.yPosition == -999.0D && packet.stance == -999.0D) - { - if (Math.abs(packet.xPosition) > 1.0D || Math.abs(packet.zPosition) > 1.0D) - { - System.err.println(oldInstance.playerEntity.getGameProfile().getName() + " was caught trying to crash the server with an invalid position."); - this.kickPlayerFromServer("Nope!"); - return; - } - - var35 = packet.xPosition; - var13 = packet.zPosition; - } - - this.playerEntity.onGround = packet.onGround; - this.playerEntity.onUpdateEntity(); - this.playerEntity.moveEntity(var35, 0.0D, var13); - this.playerEntity.setPositionAndRotation(var5, var7, var9, var34, var4); - this.playerEntity.motionX = var35; - this.playerEntity.motionZ = var13; - - /*TODO if (this.playerEntity.ridingEntity != null) - { - var2.uncheckedUpdateEntity(this.playerEntity.ridingEntity, true); - }* - - if (this.playerEntity.ridingEntity != null) - { - this.playerEntity.ridingEntity.updateRiderPosition(); - } - - this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); //can't find equivalant function in 1.7.2 - lastPosX = this.playerEntity.posX; - lastPosY = this.playerEntity.posY; - lastPosZ = this.playerEntity.posZ; - setPosition(lastPosX, lastPosY, lastPosZ); - var2.updateEntity(this.playerEntity); - return; - } - - if (this.playerEntity.isPlayerSleeping()) - { - this.playerEntity.onUpdateEntity(); - this.playerEntity.setPositionAndRotation(lastPosX, lastPosY, lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch); - var2.updateEntity(this.playerEntity); - return; - } - - var3 = this.playerEntity.posY; - lastPosX = this.playerEntity.posX; - lastPosY = this.playerEntity.posY; - lastPosZ = this.playerEntity.posZ; - setPosition(lastPosX, lastPosY, lastPosZ); - var5 = this.playerEntity.posX; - var7 = this.playerEntity.posY; - var9 = this.playerEntity.posZ; - float var11 = this.playerEntity.rotationYaw; - float var12 = this.playerEntity.rotationPitch; - - if (packet.moving && packet.yPosition == -999.0D && packet.stance == -999.0D) - { - packet.moving = false; - } - - if (packet.moving) - { - var5 = packet.xPosition; - var7 = packet.yPosition; - var9 = packet.zPosition; - var13 = packet.stance - packet.yPosition; - - if (!this.playerEntity.isPlayerSleeping() && (var13 > 1.65D || var13 < 0.1D)) - { - this.kickPlayerFromServer("Illegal stance"); - this.mcServer.logWarning(this.playerEntity.getCommandSenderName() + " had an illegal stance: " + var13); - return; - } - - if (Math.abs(packet.xPosition) > 3.2E7D || Math.abs(packet.zPosition) > 3.2E7D) - { - this.kickPlayerFromServer("Illegal position"); - return; - } - } - - if (packet.rotating) - { - var11 = packet.yaw; - var12 = packet.pitch; - } - - this.playerEntity.onUpdateEntity(); - this.playerEntity.ySize = 0.0F; - this.playerEntity.setPositionAndRotation(lastPosX, lastPosY, lastPosZ, var11, var12); - - if (!hasMoved) - { - return; - } - - var13 = var5 - this.playerEntity.posX; - double var15 = var7 - this.playerEntity.posY; - double var17 = var9 - this.playerEntity.posZ; - double var19 = Math.min(Math.abs(var13), Math.abs(this.playerEntity.motionX)); - double var21 = Math.min(Math.abs(var15), Math.abs(this.playerEntity.motionY)); - double var23 = Math.min(Math.abs(var17), Math.abs(this.playerEntity.motionZ)); - double var25 = var19 * var19 + var21 * var21 + var23 * var23; - - if (var25 > 100.0D && (!this.mcServer.isSinglePlayer() || !this.mcServer.getServerOwner().equals(this.playerEntity.getCommandSenderName()))) - { - this.mcServer.logWarning(this.playerEntity.getCommandSenderName() + " moved too quickly! " + var13 + "," + var15 + "," + var17 + " (" + var19 + ", " + var21 + ", " + var23 + ")"); - this.setPlayerLocation(lastPosX, lastPosY, lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch); - return; - } - - float var27 = 0.0625F; - boolean var28 = var2.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.boundingBox.copy().contract(var27, var27, var27)).isEmpty(); - - if (this.playerEntity.onGround && !packet.onGround && var15 > 0.0D) - { - this.playerEntity.addExhaustion(0.2F); - } - - this.playerEntity.moveEntity(var13, var15, var17); - this.playerEntity.onGround = packet.onGround; - this.playerEntity.addMovementStat(var13, var15, var17); - double var29 = var15; - var13 = var5 - this.playerEntity.posX; - var15 = var7 - this.playerEntity.posY; - - if (var15 > -0.5D || var15 < 0.5D) - { - var15 = 0.0D; - } - - var17 = var9 - this.playerEntity.posZ; - var25 = var13 * var13 + var15 * var15 + var17 * var17; - boolean var31 = false; - - if (var25 > 0.0625D && !this.playerEntity.isPlayerSleeping() && !this.playerEntity.theItemInWorldManager.isCreative()) - { - var31 = true; - this.mcServer.logWarning(this.playerEntity.getCommandSenderName() + " moved wrongly!"); - } - - this.playerEntity.setPositionAndRotation(var5, var7, var9, var11, var12); - boolean var32 = var2.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.boundingBox.copy().contract(var27, var27, var27)).isEmpty(); - - if(this.playerEntity.noClip) { - // do nothing - } - else if (var28 && (var31 || !var32) && !this.playerEntity.isPlayerSleeping()) - { - this.setPlayerLocation(lastPosX, lastPosY, lastPosZ, var11, var12); - return; - } - - AxisAlignedBB var33 = this.playerEntity.boundingBox.copy().expand(var27, var27, var27).addCoord(0.0D, -0.55D, 0.0D); - - if (!this.mcServer.isFlightAllowed() && !this.playerEntity.theItemInWorldManager.isCreative() && !var2.checkBlockCollision(var33)) - { - if (var29 >= -0.03125D) - { - ticksForFloatKick++; - - if (ticksForFloatKick > 80) - { - this.mcServer.logWarning(this.playerEntity.getCommandSenderName() + " was kicked for floating too long!"); - this.kickPlayerFromServer("Flying is not enabled on this server"); - return; - } - } - } - else - { - ticksForFloatKick = 0; - } - - this.playerEntity.onGround = packet.onGround; - this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); //can't find equivalant function in 1.7.2 - this.playerEntity.updateFlyingState(this.playerEntity.posY - var3, packet.onGround); - } - } - */ - } -} diff --git a/src/main/java/com/sijobe/spc/proxy/DummyException.java b/src/main/java/com/sijobe/spc/proxy/DummyException.java deleted file mode 100644 index eec3c3e..0000000 --- a/src/main/java/com/sijobe/spc/proxy/DummyException.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.sijobe.spc.proxy; - -public class DummyException extends RuntimeException { - -} diff --git a/src/main/java/com/sijobe/spc/proxy/Proxy.java b/src/main/java/com/sijobe/spc/proxy/Proxy.java index b2c0150..e89a8e7 100644 --- a/src/main/java/com/sijobe/spc/proxy/Proxy.java +++ b/src/main/java/com/sijobe/spc/proxy/Proxy.java @@ -2,10 +2,8 @@ import java.io.File; -import com.sijobe.spc.core.IBlockBroken; import com.sijobe.spc.wrapper.Player; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.EnumDifficulty; public abstract class Proxy{ diff --git a/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java b/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java index a423848..674659e 100644 --- a/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java +++ b/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java @@ -6,18 +6,14 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.command.ICommandSender; import net.minecraft.network.Packet; import net.minecraft.network.play.client.C01PacketChatMessage; import net.minecraft.util.ChatComponentText; import net.minecraft.world.EnumDifficulty; -import com.sijobe.spc.command.InstantMine; import com.sijobe.spc.proxy.Proxy; import com.sijobe.spc.util.AccessHelper; -import com.sijobe.spc.wrapper.Block; import com.sijobe.spc.wrapper.Player; -import com.sijobe.spc.wrapper.World; public class ClientProxy extends Proxy { @Override diff --git a/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java b/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java index f3d2036..7762b75 100644 --- a/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java +++ b/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java @@ -8,10 +8,8 @@ import com.sijobe.spc.proxy.Proxy; import com.sijobe.spc.util.AccessHelper; -import com.sijobe.spc.wrapper.Block; import com.sijobe.spc.wrapper.MinecraftServer; import com.sijobe.spc.wrapper.Player; -import com.sijobe.spc.wrapper.World; public class ServerProxy extends Proxy { diff --git a/src/main/java/com/sijobe/spc/updater/CheckVersion.java b/src/main/java/com/sijobe/spc/updater/CheckVersion.java index 2173fe4..9657ff2 100644 --- a/src/main/java/com/sijobe/spc/updater/CheckVersion.java +++ b/src/main/java/com/sijobe/spc/updater/CheckVersion.java @@ -45,6 +45,7 @@ public CheckVersion(ModVersion project[], String mcver, UpdateCallback callback) * * @see java.lang.Thread#run() */ + @SuppressWarnings("unchecked") public void run() { // download file File f = downloadFile(MANIFEST); diff --git a/src/main/java/com/sijobe/spc/util/AccessHelper.java b/src/main/java/com/sijobe/spc/util/AccessHelper.java index 5f3032c..7a40944 100644 --- a/src/main/java/com/sijobe/spc/util/AccessHelper.java +++ b/src/main/java/com/sijobe/spc/util/AccessHelper.java @@ -4,14 +4,11 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.management.ServerConfigurationManager; - public class AccessHelper { public static void setInt(Object obj, String name, int value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - Class clazz = obj.getClass(); + Class clazz = obj.getClass(); Field field = clazz.getDeclaredField(name); field.setAccessible(true); field.setInt(obj, value); @@ -19,14 +16,14 @@ public static void setInt(Object obj, String name, int value) throws NoSuchField public static void setFloat(Object obj, String name, float value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - Class clazz = obj.getClass(); + Class clazz = obj.getClass(); Field field = clazz.getDeclaredField(name); field.setAccessible(true); field.setFloat(obj, value); } public static void setBoolean(Object obj, String name, boolean value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - Class clazz = obj.getClass(); + Class clazz = obj.getClass(); Field field; while(true) { @@ -49,7 +46,7 @@ public static void setBoolean(Object obj, String name, boolean value) throws NoS } public static Object getObj(Object obj, String name) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { - Class clazz = obj.getClass(); + Class clazz = obj.getClass(); Field field; while(true) { @@ -71,9 +68,10 @@ public static Object getObj(Object obj, String name) throws NoSuchFieldException return field.get(obj); } - public static T callMethod(Object obj, String name, Object ... args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException + @SuppressWarnings("unchecked") + public static T callMethod(Object obj, String name, Object ... args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - Class clazz = obj.getClass(); + Class clazz = obj.getClass(); Method method; while(true) { diff --git a/src/main/java/com/sijobe/spc/util/DynamicClassLoader.java b/src/main/java/com/sijobe/spc/util/DynamicClassLoader.java index 2b52079..97da6b8 100644 --- a/src/main/java/com/sijobe/spc/util/DynamicClassLoader.java +++ b/src/main/java/com/sijobe/spc/util/DynamicClassLoader.java @@ -30,14 +30,6 @@ public class DynamicClassLoader { */ private static URLClassLoader CLASSLOADER; - /** - * Flag designates whether the populateClassLoaderWithClasses method has - * been called yet or not. - * - * @see DynamicClassLoader#populateClassLoaderWithClasses() - */ - private static boolean POPULATED = false; - /* * A vector used to store all SPC classes */ diff --git a/src/main/java/com/sijobe/spc/util/ForgeHelper.java b/src/main/java/com/sijobe/spc/util/ForgeHelper.java index 2f8698d..b474fe8 100644 --- a/src/main/java/com/sijobe/spc/util/ForgeHelper.java +++ b/src/main/java/com/sijobe/spc/util/ForgeHelper.java @@ -66,7 +66,6 @@ public static void clearDrops(EntityPlayerMP entityPlayerMP) { getCapturedDrops(entityPlayerMP).clear(); } - @SuppressWarnings("unchecked") public static void captureDrops(EntityPlayerMP entityPlayerMP, DamageSource damageSource, int recentlyHit) { setCaptureDrops(entityPlayerMP, false); Object event = createPlayerDropsEvent(entityPlayerMP, damageSource, getCapturedDrops(entityPlayerMP), recentlyHit > 0); @@ -174,7 +173,7 @@ public static void setBlockReachDistance(ItemInWorldManager manager, double dist capturedDropsField = ReflectionHelper.getField(Entity.class, "capturedDrops"); captureDropsField = ReflectionHelper.getField(Entity.class, "captureDrops"); playerDropsEventClass = ReflectionHelper.getClass("net.minecraftforge.event.entity.player.PlayerDropsEvent"); - final Class[] params = new Class[]{ EntityPlayer.class, DamageSource.class, ArrayList.class, Boolean.TYPE }; + final Class[] params = new Class[]{ EntityPlayer.class, DamageSource.class, ArrayList.class, Boolean.TYPE }; playerDropsEventConstructor = ReflectionHelper.getConstructor(playerDropsEventClass, params); watchClass = ReflectionHelper.getClass("net.minecraftforge.event.world.ChunkWatchEvent$Watch"); watchConstructor = ReflectionHelper.getConstructor(watchClass, new Class[]{ChunkCoordIntPair.class, EntityPlayerMP.class}); diff --git a/src/main/java/com/sijobe/spc/wrapper/Block.java b/src/main/java/com/sijobe/spc/wrapper/Block.java index 0bf53fa..ae2b9a6 100644 --- a/src/main/java/com/sijobe/spc/wrapper/Block.java +++ b/src/main/java/com/sijobe/spc/wrapper/Block.java @@ -1,7 +1,6 @@ package com.sijobe.spc.wrapper; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import com.sijobe.spc.util.RegistryIdCompatible; diff --git a/src/main/java/com/sijobe/spc/wrapper/CommandManager.java b/src/main/java/com/sijobe/spc/wrapper/CommandManager.java index 0d0a61b..1e22179 100644 --- a/src/main/java/com/sijobe/spc/wrapper/CommandManager.java +++ b/src/main/java/com/sijobe/spc/wrapper/CommandManager.java @@ -63,6 +63,7 @@ public static boolean doesCommandExist(String name) { * * @return A List of command names in Minecraft */ + @SuppressWarnings("unchecked") public static List getCommandNames() { return new ArrayList(getCommandManager().getCommands().keySet()); } @@ -162,6 +163,7 @@ public static boolean hasPermission(String name, Player player) { * * @return The command map */ + @SuppressWarnings("unchecked") private static Map getCommandMap() { return getCommandManager().getCommands(); } diff --git a/src/main/java/com/sijobe/spc/wrapper/Entity.java b/src/main/java/com/sijobe/spc/wrapper/Entity.java index afdd2c3..616cbfb 100644 --- a/src/main/java/com/sijobe/spc/wrapper/Entity.java +++ b/src/main/java/com/sijobe/spc/wrapper/Entity.java @@ -43,6 +43,7 @@ public class Entity { * @param value - The class of the value * @return The matching entity list, or null if not found */ + @SuppressWarnings("unchecked") private static Map getEntityList(Class key, Class value) { Map map = null; try { @@ -223,6 +224,7 @@ public static List findEntities(String entity, Coor * @param world - The world to get the loaded entities from * @return A List of loaded entities */ + @SuppressWarnings("unchecked") private static List getLoadedEntities(World world) { return world.getMinecraftWorld().loadedEntityList; } diff --git a/src/main/java/com/sijobe/spc/wrapper/World.java b/src/main/java/com/sijobe/spc/wrapper/World.java index e569192..d8cd9ae 100644 --- a/src/main/java/com/sijobe/spc/wrapper/World.java +++ b/src/main/java/com/sijobe/spc/wrapper/World.java @@ -6,8 +6,6 @@ import com.sijobe.spc.ModSpc; import com.sijobe.spc.util.AccessHelper; - -import net.minecraft.client.settings.GameSettings; import net.minecraft.entity.effect.EntityLightningBolt; import net.minecraft.inventory.IInventory; import net.minecraft.nbt.NBTTagCompound; diff --git a/src/make/com/sijobe/spc/asm/make/ItemRenderer.java b/src/make/com/sijobe/spc/asm/make/ItemRenderer.java new file mode 100644 index 0000000..305ed58 --- /dev/null +++ b/src/make/com/sijobe/spc/asm/make/ItemRenderer.java @@ -0,0 +1,12 @@ +package com.sijobe.spc.asm.make; + +import net.minecraft.util.IIcon; + +public class ItemRenderer { + @SuppressWarnings("unused") + private void renderInsideOfBlock(float par1, IIcon par2Icon) { + if(com.sijobe.spc.ModSpc.instance.proxy.shouldNotRenderInsideOfBlock()) { + return; + } + } +} From b472f49c310a4d01574c43f34d946a570caa3215 Mon Sep 17 00:00:00 2001 From: aucguy Date: Sun, 7 Dec 2014 09:53:59 -0600 Subject: [PATCH 16/20] Made prefixslash command work in multiplayer --- src/main/java/com/sijobe/spc/ModSpc.java | 2 - .../com/sijobe/spc/asm/SlashPrefixer.java | 9 ++- .../com/sijobe/spc/command/PrefixSlash.java | 33 +++------ .../java/com/sijobe/spc/network/Config.java | 5 +- .../spc/asm/make/NetHandlerPlayServer.java | 69 +++++++++++++++++++ 5 files changed, 87 insertions(+), 31 deletions(-) create mode 100644 src/make/com/sijobe/spc/asm/make/NetHandlerPlayServer.java diff --git a/src/main/java/com/sijobe/spc/ModSpc.java b/src/main/java/com/sijobe/spc/ModSpc.java index bca06cf..2c3bf7a 100644 --- a/src/main/java/com/sijobe/spc/ModSpc.java +++ b/src/main/java/com/sijobe/spc/ModSpc.java @@ -32,8 +32,6 @@ import com.sijobe.spc.network.PacketConfig; import com.sijobe.spc.proxy.Proxy; -//TODO make prefixslash work in multiplayer - @Mod(useMetadata=true, modid="spc", version="5.0") public class ModSpc { diff --git a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java index faa0cf4..6286bdc 100644 --- a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java +++ b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java @@ -1,5 +1,7 @@ package com.sijobe.spc.asm; +import net.minecraft.network.NetHandlerPlayServer; + import org.objectweb.asm.MethodVisitor; import com.sijobe.spc.command.PrefixSlash; @@ -33,7 +35,8 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc) { if(opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/lang/String") && name.equals("startsWith") && desc.equals("(Ljava/lang/String;)Z")) { - this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/asm/SlashPrefixer", "isCommand", "(Ljava/lang/String;)Z"); + this.mv.visitVarInsn(Opcodes.ALOAD, 0); + this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/asm/SlashPrefixer", "isCommand", "(Ljava/lang/String;Lnet/minecraft/network/NetHandlerPlayServer;)Z"); } else { @@ -41,8 +44,8 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc) } } - public static boolean isCommand(String s) + public static boolean isCommand(String s, NetHandlerPlayServer handler) { - return s.startsWith("/") || PrefixSlash.prefixSlash; + return s.startsWith("/") || PrefixSlash.playersUsing.contains(handler.playerEntity.getCommandSenderName()); } } diff --git a/src/main/java/com/sijobe/spc/command/PrefixSlash.java b/src/main/java/com/sijobe/spc/command/PrefixSlash.java index d64ef10..627561a 100644 --- a/src/main/java/com/sijobe/spc/command/PrefixSlash.java +++ b/src/main/java/com/sijobe/spc/command/PrefixSlash.java @@ -1,9 +1,5 @@ package com.sijobe.spc.command; -import com.sijobe.spc.ModSpc; -import com.sijobe.spc.network.Config; -import com.sijobe.spc.network.IClientConfig; -import com.sijobe.spc.network.PacketConfig; import com.sijobe.spc.util.FontColour; import com.sijobe.spc.util.Settings; import com.sijobe.spc.validation.Parameters; @@ -12,9 +8,9 @@ import com.sijobe.spc.wrapper.CommandSender; import com.sijobe.spc.wrapper.Player; +import java.util.HashSet; import java.util.List; - -import net.minecraft.entity.player.EntityPlayerMP; +import java.util.Set; /** * Command to toggle requiring '/' @@ -30,8 +26,8 @@ videoURL = "", enabled = true ) -public class PrefixSlash extends StandardCommand implements IClientConfig { - public static boolean prefixSlash = false; +public class PrefixSlash extends StandardCommand { + public static Set playersUsing = new HashSet(); @Override public boolean isEnabled() { @@ -48,9 +44,14 @@ public void execute(CommandSender sender, List params) throws CommandExceptio } else { prefixSlash = ((Boolean)params.get(0)); } + if(playersUsing.contains(sender.getSenderName()) && !prefixSlash) { + playersUsing.remove(sender.getSenderName()); + } + else if(!playersUsing.contains(sender.getSenderName()) && prefixSlash){ + playersUsing.add(sender.getSenderName()); + } config.set("prefixSlash", prefixSlash); super.saveSettings(player); - ModSpc.instance.networkHandler.sendTo(new PacketConfig(this.getConfig(), prefixSlash), (EntityPlayerMP) player.getMinecraftPlayer()); player.sendChatMessage("Slash prefixing is now " + FontColour.AQUA + (prefixSlash ? "enabled" : "disabled")); } @@ -59,18 +60,4 @@ public void execute(CommandSender sender, List params) throws CommandExceptio public Parameters getParameters() { return Parameters.DEFAULT_BOOLEAN; } - - @Override - public void init(Object... params) { - } - - @Override - public void onConfigRecieved(Boolean value) { - prefixSlash = value; - } - - @Override - public Config getConfig() { - return Config.PREFIX_SLASH; - } } \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/network/Config.java b/src/main/java/com/sijobe/spc/network/Config.java index 6f6f505..a7da875 100644 --- a/src/main/java/com/sijobe/spc/network/Config.java +++ b/src/main/java/com/sijobe/spc/network/Config.java @@ -6,9 +6,8 @@ public final class Config { public static final Config NOCLIP = new Config(1, Boolean.class); public static final Config LIGHT = new Config(2, Boolean.class); public static final Config INSTANT_MINE = new Config(3, Boolean.class); - public static final Config PREFIX_SLASH = new Config(4, Boolean.class); - public static final Config LONGER_LEGS = new Config(5, Float.class); - public static final Config BIND = new Config(6, Integer.class); + public static final Config LONGER_LEGS = new Config(4, Float.class); + public static final Config BIND = new Config(5, Integer.class); int id; Class kind; diff --git a/src/make/com/sijobe/spc/asm/make/NetHandlerPlayServer.java b/src/make/com/sijobe/spc/asm/make/NetHandlerPlayServer.java new file mode 100644 index 0000000..24260c1 --- /dev/null +++ b/src/make/com/sijobe/spc/asm/make/NetHandlerPlayServer.java @@ -0,0 +1,69 @@ +package com.sijobe.spc.asm.make; + +import org.apache.commons.lang3.StringUtils; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.play.client.C01PacketChatMessage; +import net.minecraft.network.play.server.S02PacketChat; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ChatAllowedCharacters; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.common.ForgeHooks; + +public class NetHandlerPlayServer extends net.minecraft.network.NetHandlerPlayServer { + public NetHandlerPlayServer(MinecraftServer par1MinecraftServer, + NetworkManager par2iNetworkManager, EntityPlayerMP par3EntityPlayerMP) { + super(par1MinecraftServer, par2iNetworkManager, par3EntityPlayerMP); + // TODO Auto-generated constructor stub + } + + public void processChatMessage(C01PacketChatMessage p_147354_1_) + { + if (this.playerEntity.func_147096_v() == EntityPlayer.EnumChatVisibility.HIDDEN) + { + ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("chat.cannotSend", new Object[0]); + chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.RED); + this.sendPacket(new S02PacketChat(chatcomponenttranslation)); + } + else + { + this.playerEntity.func_143004_u(); + String s = p_147354_1_.func_149439_c(); + s = StringUtils.normalizeSpace(s); + + for (int i = 0; i < s.length(); ++i) + { + if (!ChatAllowedCharacters.isAllowedCharacter(s.charAt(i))) + { + this.kickPlayerFromServer("Illegal characters in chat"); + return; + } + } + + if (com.sijobe.spc.asm.SlashPrefixer.isCommand(s, this)) + { + System.out.println(s); + //this.handleSlashCommand(s); + } + else + { + ChatComponentTranslation chatcomponenttranslation1 = new ChatComponentTranslation("chat.type.text", new Object[] {this.playerEntity.func_145748_c_(), s}); + chatcomponenttranslation1 = ForgeHooks.onServerChatEvent(this, s, chatcomponenttranslation1); + if (chatcomponenttranslation1 == null) return; + //this.serverController.getConfigurationManager().sendChatMsgImpl(chatcomponenttranslation1, false); + } + + //this.chatSpamThresholdCount += 20; + + /* + if (this.chatSpamThresholdCount > 200 && !this.serverController.getConfigurationManager().isPlayerOpped(this.playerEntity.getCommandSenderName())) + { + this.kickPlayerFromServer("disconnect.spam"); + } + */ + } + } +} From ccc097ea3a97ce39b73e05ba0cd6aaa647d74fec Mon Sep 17 00:00:00 2001 From: aucguy Date: Sun, 7 Dec 2014 21:27:30 -0600 Subject: [PATCH 17/20] formatting and doc --- src/main/java/com/sijobe/spc/ModSpc.java | 293 +++++++++++------- .../com/sijobe/spc/asm/ClassTransformer.java | 145 +++++---- .../java/com/sijobe/spc/asm/MethodHooker.java | 81 +++-- .../com/sijobe/spc/asm/MethodPrefixer.java | 64 ++-- .../com/sijobe/spc/asm/MethodReplacer.java | 64 ++-- .../com/sijobe/spc/asm/MethodTransformer.java | 108 ++++--- .../java/com/sijobe/spc/asm/Processor.java | 140 +++++---- .../java/com/sijobe/spc/asm/SimpleHooked.java | 69 +++-- .../com/sijobe/spc/asm/SlashPrefixer.java | 91 +++--- .../sijobe/spc/asm/SpcAccessTransformer.java | 13 - .../java/com/sijobe/spc/asm/SpcCoreMod.java | 59 ++-- .../java/com/sijobe/spc/asm/Transformer.java | 30 +- .../java/com/sijobe/spc/command/Bind.java | 7 + .../com/sijobe/spc/command/BlockReach.java | 6 +- .../java/com/sijobe/spc/command/DoDrops.java | 5 - .../java/com/sijobe/spc/command/Keypress.java | 4 +- .../java/com/sijobe/spc/command/Light.java | 4 +- .../com/sijobe/spc/command/LongerLegs.java | 5 - .../com/sijobe/spc/command/PrefixSlash.java | 8 +- .../java/com/sijobe/spc/command/Sudo.java | 10 - .../java/com/sijobe/spc/command/Waypoint.java | 5 - .../java/com/sijobe/spc/network/Config.java | 89 ++++-- .../spc/network/ConfigMessageHandler.java | 6 + .../com/sijobe/spc/network/IClientConfig.java | 12 +- .../com/sijobe/spc/network/PacketConfig.java | 103 +++--- src/main/java/com/sijobe/spc/proxy/Proxy.java | 69 ++++- .../sijobe/spc/proxy/client/ClientProxy.java | 2 +- .../sijobe/spc/proxy/server/ServerProxy.java | 2 +- .../java/com/sijobe/spc/wrapper/Block.java | 119 ++++--- .../java/com/sijobe/spc/wrapper/Blocks.java | 9 + .../java/com/sijobe/spc/wrapper/Item.java | 103 +++--- 31 files changed, 1036 insertions(+), 689 deletions(-) delete mode 100644 src/main/java/com/sijobe/spc/asm/SpcAccessTransformer.java diff --git a/src/main/java/com/sijobe/spc/ModSpc.java b/src/main/java/com/sijobe/spc/ModSpc.java index 2c3bf7a..e5e4b36 100644 --- a/src/main/java/com/sijobe/spc/ModSpc.java +++ b/src/main/java/com/sijobe/spc/ModSpc.java @@ -32,110 +32,191 @@ import com.sijobe.spc.network.PacketConfig; import com.sijobe.spc.proxy.Proxy; -@Mod(useMetadata=true, modid="spc", version="5.0") -public class ModSpc -{ - @Instance - public static ModSpc instance; - - protected HookManager hookManager; - protected InitialiseCommands commands; - public SimpleNetworkWrapper networkHandler; - - public Side side; - public Proxy proxy; - - public ModSpc() - { - this.hookManager = new HookManager(); - this.commands = new InitialiseCommands(); - } - - @EventHandler - public void init(FMLInitializationEvent event) throws InstantiationException, IllegalAccessException, ClassNotFoundException - { - this.side = event.getSide(); - if(this.side == Side.CLIENT) { - this.proxy = (Proxy) Class.forName("com.sijobe.spc.proxy.client.ClientProxy").newInstance(); //using reflection to prevent client class loading server side - } - else { - this.proxy = (Proxy) Class.forName("com.sijobe.spc.proxy.server.ServerProxy").newInstance(); //using reflection to prevent client class loading server side - } - - Block.init(); - Item.init(); - this.hookManager.loadHooks(IPlayerMP.class); - this.hookManager.loadHooks(ICUIEventHandler.class); - this.hookManager.loadHooks(IBreakSpeed.class); - this.hookManager.loadHooks(IBlockBroken.class); - this.hookManager.loadHooks(IClientConfig.class); - MinecraftForge.EVENT_BUS.register(this); - FMLCommonHandler.instance().bus().register(this); - this.networkHandler = new SimpleNetworkWrapper("spc.network"); - this.networkHandler.registerMessage(ConfigMessageHandler.class, PacketConfig.class, 0, Side.CLIENT); - this.loadClientSettingHooks(); - } - - @EventHandler - public void onServerStarting(FMLServerStartingEvent event) - { - System.out.println("loading spc commands..."); - this.commands.loadCommands(); - } - - //TODO make void handleHook() - @SubscribeEvent - public void onPlayerTick(PlayerTickEvent event) - { - if(event.phase == Phase.START && event.side == Side.SERVER) - { - if(event.player instanceof EntityPlayerMP) - { - Player player = new Player((EntityPlayer) event.player); - for(IPlayerMP hook : this.hookManager.getHooks(IPlayerMP.class)) - { - if(hook.isEnabled()) - { - hook.onTick(player); - } - } - } - } - } - - @SubscribeEvent - public void onBreakSpeed(BreakSpeed event) - { - for(IBreakSpeed hook : this.hookManager.getHooks(IBreakSpeed.class)) - { - if(hook.isEnabled()) - { - //TODO pass same player instance instead of creating a new one each time - event.newSpeed = hook.getBreakSpeed(new Player(event.entityPlayer), Block.fromMinecraftBlock(event.block), event.metadata, event.originalSpeed, event.x, event.y, event.z); - } - } - } - - @SubscribeEvent - public void onBlockBreak(BreakEvent event) - { - for(IBlockBroken hook : this.hookManager.getHooks(IBlockBroken.class)) - { - if(hook.isEnabled()) - { - hook.onBreakBroken(event.x, event.y, event.z, new World(event.world), Block.fromMinecraftBlock(event.block), event.blockMetadata, new Player(event.getPlayer())); - } - } - } - - public void loadClientSettingHooks() - { - for(IClientConfig hook : this.hookManager.getHooks(IClientConfig.class)) - { - if(hook.isEnabled()) - { - hook.getConfig().setHandler((IClientConfig) hook); - } - } - } +/** + * the main mod class + * + * @author aucguy + * @version 1.0 + */ +@Mod(useMetadata = true, modid = "spc", version = "5.0") +public class ModSpc { + /** + * the spc mod instance + */ + @Instance + public static ModSpc instance; + + /** + * the hook manager. Used for hooking things + */ + protected HookManager hookManager; + + /** + * the initialize commands instance. Used for initializing commands when the + * server is launched + */ + protected InitialiseCommands commands; + + /** + * the network handler instance. Used to set client sided settings (like + * light levels for the light command) + */ + public SimpleNetworkWrapper networkHandler; + + /** + * the side this mod is running on + */ + public Side side; + + /** + * the proxy instance. Used since sometimes it is neccessary to access the + * Minecraft instance. However, this is client-sided. Even though it may not + * be used on the server, loading any class that uses references the + * Minecraft instance will load net.minecraft.client.Minecraft. If this + * happens on the server, the server will crash. + */ + public Proxy proxy; + + /** + * construct me a mod! + */ + public ModSpc() { + this.hookManager = new HookManager(); + this.commands = new InitialiseCommands(); + } + + /** + * used to initialize everything + * + * @param event - the initialization event + * @throws InstantiationException - because of reflection + * @throws IllegalAccessException - because of reflection + * @throws ClassNotFoundException - because of reflection + */ + @EventHandler + public void init(FMLInitializationEvent event) + throws InstantiationException, IllegalAccessException, + ClassNotFoundException { + this.side = event.getSide(); + if (this.side == Side.CLIENT) { + // if reflection wasn't used then when this class was loaded the + // ClientProxy class would be loaded + // and since ClientProxy referrs to net.minecraft.client.Minecraft, + // that would be loaded + // loading net.minecraft.client.Minecraft on a server crashes it. + this.proxy = (Proxy) Class.forName( + "com.sijobe.spc.proxy.client.ClientProxy").newInstance(); // using + // reflection + // to + // prevent + // client + // class + // loading + // server + // side + } else { + this.proxy = (Proxy) Class.forName( + "com.sijobe.spc.proxy.server.ServerProxy").newInstance(); // using + // reflection + // to + // prevent + // client + // class + // loading + // server + // side + } + + Block.init(); + Item.init(); + this.hookManager.loadHooks(IPlayerMP.class); + this.hookManager.loadHooks(ICUIEventHandler.class); + this.hookManager.loadHooks(IBreakSpeed.class); + this.hookManager.loadHooks(IBlockBroken.class); + this.hookManager.loadHooks(IClientConfig.class); + MinecraftForge.EVENT_BUS.register(this); + FMLCommonHandler.instance().bus().register(this); + this.networkHandler = new SimpleNetworkWrapper("spc.network"); + this.networkHandler.registerMessage(ConfigMessageHandler.class, + PacketConfig.class, 0, Side.CLIENT); + this.loadClientSettingHooks(); + } + + /** + * initialize the spc commands + * + * @param event - the ServerStarting event + */ + @EventHandler + public void onServerStarting(FMLServerStartingEvent event) { + System.out.println("loading spc commands..."); + this.commands.loadCommands(); + } + + // TODO make void handleHook() + /** + * callss all of the player tick hooks + * + * @param event - the PlayerTick event + */ + @SubscribeEvent + public void onPlayerTick(PlayerTickEvent event) { + if (event.phase == Phase.START && event.side == Side.SERVER) { + if (event.player instanceof EntityPlayerMP) { + Player player = new Player((EntityPlayer) event.player); + for (IPlayerMP hook : this.hookManager.getHooks(IPlayerMP.class)) { + if (hook.isEnabled()) { + hook.onTick(player); + } + } + } + } + } + + /** + * calls of of the break speed hooks. Used to modify the time it takes to + * break something + * + * @param event - the breakSpeed event + */ + @SubscribeEvent + public void onBreakSpeed(BreakSpeed event) { + for (IBreakSpeed hook : this.hookManager.getHooks(IBreakSpeed.class)) { + if (hook.isEnabled()) { + // TODO pass same player instance instead of creating a new one each + // time + event.newSpeed = hook.getBreakSpeed(new Player(event.entityPlayer), + Block.fromMinecraftBlock(event.block), event.metadata, + event.originalSpeed, event.x, event.y, event.z); + } + } + } + + /** + * calls of the the block broken hooks + * + * @param event - the break event + */ + @SubscribeEvent + public void onBlockBreak(BreakEvent event) { + for (IBlockBroken hook : this.hookManager.getHooks(IBlockBroken.class)) { + if (hook.isEnabled()) { + hook.onBreakBroken(event.x, event.y, event.z, + new World(event.world), + Block.fromMinecraftBlock(event.block), event.blockMetadata, + new Player(event.getPlayer())); + } + } + } + + /** + * loads all the client configuration hooks + */ + public void loadClientSettingHooks() { + for (IClientConfig hook : this.hookManager.getHooks(IClientConfig.class)) { + if (hook.isEnabled()) { + hook.getConfig().setHandler((IClientConfig) hook); + } + } + } } diff --git a/src/main/java/com/sijobe/spc/asm/ClassTransformer.java b/src/main/java/com/sijobe/spc/asm/ClassTransformer.java index d19898b..9329c10 100644 --- a/src/main/java/com/sijobe/spc/asm/ClassTransformer.java +++ b/src/main/java/com/sijobe/spc/asm/ClassTransformer.java @@ -8,62 +8,91 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -class ClassTransformer extends ClassVisitor -{ - protected String name; - protected Map methodTransformers; - - ClassTransformer(String name) - { - super(Opcodes.ASM4, new ClassWriter(Opcodes.ASM4)); - this.name = name; - this.methodTransformers = new HashMap(); - } - - String getApplicableClass() - { - return this.name; - } - - ClassWriter getWriter() - { - return (ClassWriter) this.cv; - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) - { - MethodVisitor writer = super.visitMethod(access, name, desc, signature, exceptions); - String id = this.getApplicableClass()+":"+name+":"+desc; - - if(this.methodTransformers.containsKey(id)) - { - MethodTransformer transformer = this.methodTransformers.get(id); - transformer.injectMethodWriter(writer); - return transformer; - } - else - { - return writer; - } - } - - void registerMethodTransformer(MethodTransformer mt) throws IllegalArgumentException - { - String name = mt.getApplicableMethod(); - String clazz = name.split(":", 2)[0]; - if(!clazz.equals(this.getApplicableClass())) - { - throw(new IllegalArgumentException("MethodTransformer not of correct class")); - } - this.methodTransformers.put(mt.getApplicableMethod(), mt); - } - - void regsiterMethodTransformers(MethodTransformer[] mt) throws IllegalArgumentException - { - for(MethodTransformer i : mt) - { - this.registerMethodTransformer(i); - } - } +/** + * used to transform a class + * + * @author aucguy + * @version 1.0 + */ +class ClassTransformer extends ClassVisitor { + /** + * the binary name of the class this transformer modifies + */ + protected String name; + + /** + * binds method ids to methodTransformerss + */ + protected Map methodTransformers; + + /** + * creates a ClassTransformer + * + * @param name - the binary name of the class this transformer modifies + */ + ClassTransformer(String name) { + super(Opcodes.ASM4, new ClassWriter(Opcodes.ASM4)); + this.name = name; + this.methodTransformers = new HashMap(); + } + + /** + * @return the binary name of the class this transformer modifies + */ + String getApplicableClass() { + return this.name; + } + + /** + * used to modify classes + * + * @return this instance's ClassWriter + */ + ClassWriter getWriter() { + return (ClassWriter) this.cv; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, + String signature, String[] exceptions) { + MethodVisitor writer = super + .visitMethod(access, name, desc, signature, exceptions); + String id = this.getApplicableClass() + ":" + name + ":" + desc; + + if (this.methodTransformers.containsKey(id)) { + MethodTransformer transformer = this.methodTransformers.get(id); + transformer.injectMethodWriter(writer); + return transformer; + } else { + return writer; + } + } + + /** + * registers the given method transformer for the with this instance + * + * @param mt - the methodTransformer to register + * @throws IllegalArgumentExceptions - if the tranformer doesn't modify the a method of this instance's class + */ + void registerMethodTransformer(MethodTransformer mt) throws IllegalArgumentException { + String name = mt.getApplicableMethod(); + String clazz = name.split(":", 2)[0]; + if (!clazz.equals(this.getApplicableClass())) { + throw (new IllegalArgumentException( + "MethodTransformer not of correct class")); + } + this.methodTransformers.put(mt.getApplicableMethod(), mt); + } + + /** + * registers multiple methodTransformers + * + * @param mt - the MethodTransformers to register + * @throws IllegalArgumentException - if the tranformer doesn't modify the a method of this instance's class + */ + void regsiterMethodTransformers(MethodTransformer[] mt) throws IllegalArgumentException { + for (MethodTransformer i : mt) { + this.registerMethodTransformer(i); + } + } } diff --git a/src/main/java/com/sijobe/spc/asm/MethodHooker.java b/src/main/java/com/sijobe/spc/asm/MethodHooker.java index c92f1d1..448b303 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodHooker.java +++ b/src/main/java/com/sijobe/spc/asm/MethodHooker.java @@ -5,37 +5,52 @@ import java.lang.reflect.Modifier; import org.objectweb.asm.MethodVisitor; - -abstract class MethodHooker extends MethodTransformer -{ - protected Method method; - - MethodHooker(String id, Method method) throws IllegalArgumentException - { - super(id); - if(!Modifier.isStatic(method.getModifiers())) - { - throw(new IllegalArgumentException("MethodTransformer not of correct class")); - } - this.method = method; - } - - protected abstract MethodVisitor getWriter(); - - @Override - public void visitCode() - { - try { - this.method.invoke(null, this.getWriter()); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvocationTargetException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } +/** + * base class for simple method transformers based on methods like in SimpleHooked + * @author aucguy + * @version 1.0 + */ +abstract class MethodHooker extends MethodTransformer { + /** + * the method that will call the necessary 'visit' methods of the methodWriter instead of or before the vanilla method. + */ + protected Method method; + + /** + * constructs a MethodHooker + * @param id - the id of the method to modify + * @param method - the method that will call the necessary 'visit' methods + * @throws IllegalArgumentException - the method is not static + */ + MethodHooker(String id, Method method) throws IllegalArgumentException { + super(id); + if (!Modifier.isStatic(method.getModifiers())) { + throw (new IllegalArgumentException( + "MethodTransformer not of correct class")); + } + this.method = method; + } + + /** + * returns this instance's methodWriter + * + * @return + */ + protected abstract MethodVisitor getWriter(); + + @Override + public void visitCode() { + try { + this.method.invoke(null, this.getWriter()); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } diff --git a/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java b/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java index f60d0df..c9054a8 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java +++ b/src/main/java/com/sijobe/spc/asm/MethodPrefixer.java @@ -8,29 +8,43 @@ import org.objectweb.asm.MethodVisitor; -class MethodPrefixer extends MethodHooker -{ - MethodPrefixer(String id, Method method) throws IllegalArgumentException - { - super(id, method); - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - @interface Hook - { - String value(); - } - - @Override - void injectMethodWriter(MethodVisitor mv) - { - this.mv = mv; - } - - @Override - protected MethodVisitor getWriter() - { - return this.mv; - } +/** + * used to prefix vanilla methods with custom code + * + * @author aucguy + * @version 1.0 + */ +class MethodPrefixer extends MethodHooker { + /** + * constructs a MethodPrefixer + * + * @param id - the id of the vanilla method + * @param method - the method that calls the necessary 'visit' methods + * @throws IllegalArgumentException - if the method is not static + */ + MethodPrefixer(String id, Method method) throws IllegalArgumentException { + super(id, method); + } + + /** + * used to signify that a method is supposed to be used with a MethodPrefixer + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + @interface Hook { + /** + * the id of the vanilla method + */ + String value(); + } + + @Override + void injectMethodWriter(MethodVisitor mv) { + this.mv = mv; + } + + @Override + protected MethodVisitor getWriter() { + return this.mv; + } } diff --git a/src/main/java/com/sijobe/spc/asm/MethodReplacer.java b/src/main/java/com/sijobe/spc/asm/MethodReplacer.java index 57ab1dd..25ab08d 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodReplacer.java +++ b/src/main/java/com/sijobe/spc/asm/MethodReplacer.java @@ -8,31 +8,41 @@ import org.objectweb.asm.MethodVisitor; -class MethodReplacer extends MethodHooker -{ - protected MethodVisitor writer; - - MethodReplacer(String id, Method method) throws IllegalArgumentException - { - super(id, method); - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - @interface Hook - { - String value(); - } - - @Override - void injectMethodWriter(MethodVisitor mv) - { - this.writer = mv; - } - - @Override - protected MethodVisitor getWriter() - { - return this.writer; - } +/** + * used to replace vanilla methods + * + * @author aucguy + * @version 1.0 + */ +class MethodReplacer extends MethodHooker { + /** + * the MethodWriter instance. the normal 'mv' field is't used because if it were 'visit' methods would get called on it + */ + protected MethodVisitor writer; + + MethodReplacer(String id, Method method) throws IllegalArgumentException { + super(id, method); + } + + /** + * used to signify that a method is supposed to be used with a MethodReplacer + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + @interface Hook { + /** + * the id of the vanilla method + */ + String value(); + } + + @Override + void injectMethodWriter(MethodVisitor mv) { + this.writer = mv; + } + + @Override + protected MethodVisitor getWriter() { + return this.writer; + } } diff --git a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java index c9982ff..2e8f59e 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java +++ b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java @@ -8,46 +8,70 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -abstract class MethodTransformer extends MethodVisitor -{ - String id; - - MethodTransformer(String id) - { - super(Opcodes.ASM4); - this.id = id; - } - - String getApplicableMethod() - { - return this.id; - } - - abstract void injectMethodWriter(MethodVisitor mv); - - static MethodTransformer[] generateFromFunctions(Class clazz) - { - List modifiers = new LinkedList(); - for(Method method : clazz.getDeclaredMethods()) - { - if(Modifier.isStatic(method.getModifiers())) - { - if(method.isAnnotationPresent(MethodReplacer.Hook.class)) - { - String annotation = method.getAnnotation(MethodReplacer.Hook.class).value(); - System.out.println("found replacement for "+annotation); - modifiers.add(new MethodReplacer(annotation, method)); - } - else if(method.isAnnotationPresent(MethodPrefixer.Hook.class)) - { - String annotation = method.getAnnotation(MethodPrefixer.Hook.class).value(); - System.out.println("found prefix for "+annotation); - modifiers.add(new MethodPrefixer(annotation, method)); - } - } - } - - MethodTransformer[] r = new MethodTransformer[modifiers.size()]; - return modifiers.toArray(r); - } +/** + * used to transform methods + * + * @author aucguy + * @version 1.0 + */ +abstract class MethodTransformer extends MethodVisitor { + + /** + * the method id of this transformer a method id is in the format 'class:method:descriptor' + */ + String id; + + /** + * constructs a MethodTransformer + * + * @param id - the id for this instance + */ + MethodTransformer(String id) { + super(Opcodes.ASM4); + this.id = id; + } + + /** + * gets teh applicable method + * + * @return the id of the method that this transformer modifies + */ + String getApplicableMethod() { + return this.id; + } + + /** + * gives this MethodTrasnformer the method writer instance + * + * @param mv - the MethodWriter created for this instance. Made just before this instance will visit things + */ + abstract void injectMethodWriter(MethodVisitor mv); + + /** + * generates an array of MethodTransformers from a class of annotations. This allows for easy use of ASM modifications See com.sijobe.asm.SimpleHooked for an example. + * + * @param clazz - the class containing the modification methods. + * @return an array of MethodTransformers that were generated + */ + static MethodTransformer[] generateFromFunctions(Class clazz) { + List modifiers = new LinkedList(); + for (Method method : clazz.getDeclaredMethods()) { + if (Modifier.isStatic(method.getModifiers())) { + if (method.isAnnotationPresent(MethodReplacer.Hook.class)) { + String annotation = method + .getAnnotation(MethodReplacer.Hook.class).value(); + System.out.println("found replacement for " + annotation); + modifiers.add(new MethodReplacer(annotation, method)); + } else if (method.isAnnotationPresent(MethodPrefixer.Hook.class)) { + String annotation = method + .getAnnotation(MethodPrefixer.Hook.class).value(); + System.out.println("found prefix for " + annotation); + modifiers.add(new MethodPrefixer(annotation, method)); + } + } + } + + MethodTransformer[] r = new MethodTransformer[modifiers.size()]; + return modifiers.toArray(r); + } } diff --git a/src/main/java/com/sijobe/spc/asm/Processor.java b/src/main/java/com/sijobe/spc/asm/Processor.java index 1ab670f..e8d341c 100644 --- a/src/main/java/com/sijobe/spc/asm/Processor.java +++ b/src/main/java/com/sijobe/spc/asm/Processor.java @@ -5,59 +5,89 @@ import org.objectweb.asm.ClassReader; -class Processor -{ - private static Processor instance = new Processor(); - - static Processor getInstance() - { - return instance; - } - - protected Map classTransformers; - - Processor() - { - this.classTransformers = new HashMap(); - } - - byte[] process(String name, byte[] data) - { - if(this.classTransformers.containsKey(name)) - { - ClassTransformer transformer = this.classTransformers.get(name); - this.classTransformers.remove(name); - ClassReader reader = new ClassReader(data); - reader.accept(transformer, 0); - return transformer.getWriter().toByteArray(); - } - else - { - return data; - } - } - - void registerClassTransformer(ClassTransformer ct) - { - this.classTransformers.put(ct.getApplicableClass(), ct); - } - - void registerMethodTransformer(MethodTransformer mt) - { - String id = mt.getApplicableMethod(); - String clazz = id.split(":", 2)[0]; - if(!this.classTransformers.containsKey(clazz)) - { - this.classTransformers.put(clazz, new ClassTransformer(clazz)); - } - this.classTransformers.get(clazz).registerMethodTransformer(mt); - } - - void registerMethodTransformers(MethodTransformer[] mt) - { - for(MethodTransformer i : mt) - { - this.registerMethodTransformer(i); - } - } +/** + * Give it some bytecode and it will modify that class with the previously given transformers + * + * @author aucguy + * @version 1.0 + */ +class Processor { + /** + * the instance + */ + private static Processor instance = new Processor(); + + /** + * how to get the processor instance + * + * @return the Processor instance + */ + static Processor getInstance() { + return instance; + } + + /** + * maps class binary names to classTransformers + */ + protected Map classTransformers; + + /** + * makes a Processor + */ + Processor() { + this.classTransformers = new HashMap(); + } + + /** + * modifies the given bytecode with previously given Transformers + * + * @param name - the binary name of the class + * @param data - the class's bytecode + * @return the modified bytecode + */ + byte[] process(String name, byte[] data) { + if (this.classTransformers.containsKey(name)) { + ClassTransformer transformer = this.classTransformers.get(name); + this.classTransformers.remove(name); + ClassReader reader = new ClassReader(data); + reader.accept(transformer, 0); + return transformer.getWriter().toByteArray(); + } else { + return data; + } + } + + /** + * registers a classTransformer with this Processor + * + * @param ct - the classTransformer to register + */ + void registerClassTransformer(ClassTransformer ct) { + this.classTransformers.put(ct.getApplicableClass(), ct); + } + + /** + * registers the given method transformer with whatever classTransformer it goes with + * + * @param mt - the methodTransformer to register + */ + void registerMethodTransformer(MethodTransformer mt) { + String id = mt.getApplicableMethod(); + String clazz = id.split(":", 2)[0]; + if (!this.classTransformers.containsKey(clazz)) { + this.classTransformers.put(clazz, new ClassTransformer(clazz)); + } + this.classTransformers.get(clazz).registerMethodTransformer(mt); + } + + /** + * registers multiple method transformers + * + * @param mt - the methodTransformers to register + */ + void registerMethodTransformers(MethodTransformer[] mt) { + for (MethodTransformer i : mt) { + this.registerMethodTransformer(i); + } + } } diff --git a/src/main/java/com/sijobe/spc/asm/SimpleHooked.java b/src/main/java/com/sijobe/spc/asm/SimpleHooked.java index 63465f5..052eab1 100644 --- a/src/main/java/com/sijobe/spc/asm/SimpleHooked.java +++ b/src/main/java/com/sijobe/spc/asm/SimpleHooked.java @@ -4,29 +4,48 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -public class SimpleHooked -{ - @MethodReplacer.Hook("net.minecraft.client.multiplayer.PlayerControllerMP:getBlockReachDistance:()F") - public static void getBlockReachDistance(MethodVisitor mv) - { - mv.visitCode(); - mv.visitFieldInsn(Opcodes.GETSTATIC, "com/sijobe/spc/command/BlockReach", "reachDistance", "F"); - mv.visitInsn(Opcodes.FRETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - - @MethodPrefixer.Hook("net.minecraft.client.renderer.ItemRenderer:renderInsideOfBlock:(FLnet/minecraft/util/IIcon;)V") - public static void renderInsideOfBlock(MethodVisitor mv) - { - mv.visitCode(); - mv.visitFieldInsn(Opcodes.GETSTATIC, "com/sijobe/spc/ModSpc", "instance", "Lcom/sijobe/spc/ModSpc;"); - mv.visitFieldInsn(Opcodes.GETFIELD, "com/sijobe/spc/ModSpc", "proxy", "Lcom/sijobe/spc/proxy/Proxy;"); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/sijobe/spc/proxy/Proxy", "shouldNotRenderInsideOfBlock", "()Z"); - Label l0 = new Label(); - mv.visitJumpInsn(Opcodes.IFEQ, l0); - mv.visitInsn(Opcodes.RETURN); - mv.visitLabel(l0); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - } +/** + * simple ASM hooks that either replace or prefix methos + * + * @author aucguy + * @version 1.0 + */ +public class SimpleHooked { + /** + * Allows spc to have control over client-sided block reach + * effectively makes the method this: + * return com.sijobe.spc.command.BlockReach.reachDistance; + * + * @param mv - the MethodWriter instance + */ + @MethodReplacer.Hook("net.minecraft.client.multiplayer.PlayerControllerMP:getBlockReachDistance:()F") + public static void getBlockReachDistance(MethodVisitor mv) { + mv.visitCode(); + mv.visitFieldInsn(Opcodes.GETSTATIC, "com/sijobe/spc/command/BlockReach", "reachDistance", "F"); + mv.visitInsn(Opcodes.FRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + + /** + * Allows spc to have control over whether or not the inside of blocks are rendered + * effectivly prefixes the method with this + * if(com.sijobe.spc.ModSpc.instance.proxy.shouldNotRenderInsideOfBlock()) { + * return; + * } + * + * @param mv - the MethodWriter + */ + @MethodPrefixer.Hook("net.minecraft.client.renderer.ItemRenderer:renderInsideOfBlock:(FLnet/minecraft/util/IIcon;)V") + public static void renderInsideOfBlock(MethodVisitor mv) { + mv.visitCode(); + mv.visitFieldInsn(Opcodes.GETSTATIC, "com/sijobe/spc/ModSpc", "instance", "Lcom/sijobe/spc/ModSpc;"); + mv.visitFieldInsn(Opcodes.GETFIELD, "com/sijobe/spc/ModSpc", "proxy", "Lcom/sijobe/spc/proxy/Proxy;"); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/sijobe/spc/proxy/Proxy", "shouldNotRenderInsideOfBlock", "()Z"); + Label l0 = new Label(); + mv.visitJumpInsn(Opcodes.IFEQ, l0); + mv.visitInsn(Opcodes.RETURN); + mv.visitLabel(l0); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + } } diff --git a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java index 6286bdc..0b1e016 100644 --- a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java +++ b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java @@ -7,45 +7,54 @@ import com.sijobe.spc.command.PrefixSlash; import com.sun.xml.internal.ws.org.objectweb.asm.Opcodes; -public class SlashPrefixer extends MethodTransformer -{ - - SlashPrefixer() - { - super("net.minecraft.network.NetHandlerPlayServer:processChatMessage:(Lnet/minecraft/network/play/client/C01PacketChatMessage;)V"); - } - - @Override - void injectMethodWriter(MethodVisitor mv) - { - this.mv = mv; - } - - @Override - public void visitLdcInsn(Object cst) - { - if(!cst.equals("/")) - { - this.mv.visitLdcInsn(cst); - } - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc) - { - if(opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/lang/String") && name.equals("startsWith") && desc.equals("(Ljava/lang/String;)Z")) - { - this.mv.visitVarInsn(Opcodes.ALOAD, 0); - this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/asm/SlashPrefixer", "isCommand", "(Ljava/lang/String;Lnet/minecraft/network/NetHandlerPlayServer;)Z"); - } - else - { - this.mv.visitMethodInsn(opcode, owner, name, desc); - } - } - - public static boolean isCommand(String s, NetHandlerPlayServer handler) - { - return s.startsWith("/") || PrefixSlash.playersUsing.contains(handler.playerEntity.getCommandSenderName()); - } +/** + * prefixes slashes onto commands if the player has it enabled + * effectivly replaces + * if(s.startsWith("/")) { + * this.handleSlashCommand(s); + * } + * to: + * if(com.sijobe.spc.asm.SlashPrefixer.isCommand(this, s)) { + * this.handleSlashCommand(s); + * } + * + * @author aucguy + * @version 1.0 + */ +public class SlashPrefixer extends MethodTransformer { + + SlashPrefixer() { + super("net.minecraft.network.NetHandlerPlayServer:processChatMessage:(Lnet/minecraft/network/play/client/C01PacketChatMessage;)V"); + } + + @Override + void injectMethodWriter(MethodVisitor mv) { + this.mv = mv; + } + + @Override + public void visitLdcInsn(Object cst) { + if (!cst.equals("/")) { + this.mv.visitLdcInsn(cst); + } + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc) { + if (opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/lang/String") && name.equals("startsWith") && desc.equals("(Ljava/lang/String;)Z")) { + this.mv.visitVarInsn(Opcodes.ALOAD, 0); + this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/asm/SlashPrefixer", "isCommand", "(Ljava/lang/String;Lnet/minecraft/network/NetHandlerPlayServer;)Z"); + } else { + this.mv.visitMethodInsn(opcode, owner, name, desc); + } + } + + /** + * @param s - the chat that was sent + * @param handler - the netHandler instance for that player + * @return - whether of not the chat should be treated as a command + */ + public static boolean isCommand(String s, NetHandlerPlayServer handler) { + return s.startsWith("/") || PrefixSlash.playersUsing.contains(handler.playerEntity.getCommandSenderName()); + } } diff --git a/src/main/java/com/sijobe/spc/asm/SpcAccessTransformer.java b/src/main/java/com/sijobe/spc/asm/SpcAccessTransformer.java deleted file mode 100644 index dd54935..0000000 --- a/src/main/java/com/sijobe/spc/asm/SpcAccessTransformer.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.sijobe.spc.asm; - -import java.io.IOException; - -import cpw.mods.fml.common.asm.transformers.AccessTransformer; - -public class SpcAccessTransformer extends AccessTransformer -{ - public SpcAccessTransformer() throws IOException - { - super("com/sijobe/spc/asm/spc_at.txt"); - } -} diff --git a/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java b/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java index 6d4bebc..321e28a 100644 --- a/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java +++ b/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java @@ -7,37 +7,36 @@ import cpw.mods.fml.relauncher.IFMLLoadingPlugin.Name; import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions; +/** + * the spc coremod class + * @author aucguy + * @version 1.0 + */ @MCVersion("1.7.2") @Name("spc Coremod") @TransformerExclusions("com.sijobe.spc.asm") -public class SpcCoreMod implements IFMLLoadingPlugin -{ - @Override - public String[] getASMTransformerClass() - { - return new String[]{Transformer.class.getName(), SpcAccessTransformer.class.getName()}; - } - - @Override - public String getModContainerClass() - { - return null; - } - - @Override - public String getSetupClass() - { - return null; - } - - @Override - public void injectData(Map data) - { - } - - @Override - public String getAccessTransformerClass() - { - return null; - } +public class SpcCoreMod implements IFMLLoadingPlugin { + @Override + public String[] getASMTransformerClass() { + return new String[] { Transformer.class.getName() }; + } + + @Override + public String getModContainerClass() { + return null; + } + + @Override + public String getSetupClass() { + return null; + } + + @Override + public void injectData(Map data) { + } + + @Override + public String getAccessTransformerClass() { + return null; + } } diff --git a/src/main/java/com/sijobe/spc/asm/Transformer.java b/src/main/java/com/sijobe/spc/asm/Transformer.java index b9557c2..e762afb 100644 --- a/src/main/java/com/sijobe/spc/asm/Transformer.java +++ b/src/main/java/com/sijobe/spc/asm/Transformer.java @@ -2,18 +2,20 @@ import net.minecraft.launchwrapper.IClassTransformer; -public class Transformer implements IClassTransformer -{ - public Transformer() - { - Processor processor = Processor.getInstance(); - processor.registerMethodTransformers(MethodTransformer.generateFromFunctions(SimpleHooked.class)); - processor.registerMethodTransformer(new SlashPrefixer()); - } - - @Override - public byte[] transform(String name, String transformedName, byte[] basicClass) - { - return Processor.getInstance().process(name, basicClass); - } +/** + * the ASMtransformer + * @author aucguy + * @version 1.0 + */ +public class Transformer implements IClassTransformer { + public Transformer() { + Processor processor = Processor.getInstance(); + processor.registerMethodTransformers(MethodTransformer.generateFromFunctions(SimpleHooked.class)); + processor.registerMethodTransformer(new SlashPrefixer()); + } + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + return Processor.getInstance().process(name, basicClass); + } } diff --git a/src/main/java/com/sijobe/spc/command/Bind.java b/src/main/java/com/sijobe/spc/command/Bind.java index 1d620a3..db0d43c 100644 --- a/src/main/java/com/sijobe/spc/command/Bind.java +++ b/src/main/java/com/sijobe/spc/command/Bind.java @@ -29,7 +29,14 @@ * @version 1.1 */ public class Bind extends MultipleCommands implements KeyListener, IClientConfig { + /** + * the settings prefix + */ public static final String SETTINGS_PREFIX = "keybinding-"; + + /** + * the command that is sent everytime a bound key is pressed + */ public static final String KEYPRESS_COMMAND = "/keypress "; /** diff --git a/src/main/java/com/sijobe/spc/command/BlockReach.java b/src/main/java/com/sijobe/spc/command/BlockReach.java index a5378cc..6eea3ca 100644 --- a/src/main/java/com/sijobe/spc/command/BlockReach.java +++ b/src/main/java/com/sijobe/spc/command/BlockReach.java @@ -38,7 +38,11 @@ public class BlockReach extends StandardCommand implements IClientConfig{ } ); - public static float reachDistance = 4.5F; //refered to through ASM modifications and is client sided + /** + * the block reachDistance for the client + * refered to through ASM modifications and is client sided + */ + public static float reachDistance = 4.5F; /** * @see com.sijobe.spc.wrapper.CommandBase#execute(com.sijobe.spc.wrapper.CommandSender, java.util.List) diff --git a/src/main/java/com/sijobe/spc/command/DoDrops.java b/src/main/java/com/sijobe/spc/command/DoDrops.java index e24212d..e376d9c 100644 --- a/src/main/java/com/sijobe/spc/command/DoDrops.java +++ b/src/main/java/com/sijobe/spc/command/DoDrops.java @@ -27,11 +27,6 @@ public class DoDrops extends StandardCommand implements IPlayerMP { private static boolean removeDrops = false; - @Override - public boolean isEnabled() { - return true; - } - @Override public void execute(CommandSender sender, List params) throws CommandException { Player player = CommandBase.getSenderAsPlayer(sender); diff --git a/src/main/java/com/sijobe/spc/command/Keypress.java b/src/main/java/com/sijobe/spc/command/Keypress.java index d170f3c..ae4257c 100644 --- a/src/main/java/com/sijobe/spc/command/Keypress.java +++ b/src/main/java/com/sijobe/spc/command/Keypress.java @@ -38,6 +38,6 @@ public Parameters getParameters() { public void execute(CommandSender sender, List params) throws CommandException { Settings settings = loadSettings(getSenderAsPlayer(sender)); String command = settings.getProperty(Bind.SETTINGS_PREFIX+params.get(0)); - CommandManager.runCommand(sender, command); - } + CommandManager.runCommand(sender, command); + } } diff --git a/src/main/java/com/sijobe/spc/command/Light.java b/src/main/java/com/sijobe/spc/command/Light.java index f63df7a..315719b 100644 --- a/src/main/java/com/sijobe/spc/command/Light.java +++ b/src/main/java/com/sijobe/spc/command/Light.java @@ -27,7 +27,7 @@ version = "1.4" ) public class Light extends StandardCommand implements IClientConfig { - + public static boolean isLit = false; // is current world lit? client sided /** @@ -48,7 +48,7 @@ public void init(Object... params) { @Override public void onConfigRecieved(Boolean value) { - ModSpc.instance.proxy.toggleClientLighting(value); + ModSpc.instance.proxy.setClientLighting(value); } @Override diff --git a/src/main/java/com/sijobe/spc/command/LongerLegs.java b/src/main/java/com/sijobe/spc/command/LongerLegs.java index 8871425..44fc526 100644 --- a/src/main/java/com/sijobe/spc/command/LongerLegs.java +++ b/src/main/java/com/sijobe/spc/command/LongerLegs.java @@ -32,11 +32,6 @@ ) public class LongerLegs extends StandardCommand implements IClientConfig { - @Override - public boolean isEnabled() { - return true; - } - @Override public void execute(CommandSender sender, List params) throws CommandException { diff --git a/src/main/java/com/sijobe/spc/command/PrefixSlash.java b/src/main/java/com/sijobe/spc/command/PrefixSlash.java index 627561a..341ed33 100644 --- a/src/main/java/com/sijobe/spc/command/PrefixSlash.java +++ b/src/main/java/com/sijobe/spc/command/PrefixSlash.java @@ -27,13 +27,11 @@ enabled = true ) public class PrefixSlash extends StandardCommand { + /** + * a list of players that have slashes prefixed + */ public static Set playersUsing = new HashSet(); - @Override - public boolean isEnabled() { - return true; - } - @Override public void execute(CommandSender sender, List params) throws CommandException { Player player = CommandBase.getSenderAsPlayer(sender); diff --git a/src/main/java/com/sijobe/spc/command/Sudo.java b/src/main/java/com/sijobe/spc/command/Sudo.java index 2173edd..10db27b 100644 --- a/src/main/java/com/sijobe/spc/command/Sudo.java +++ b/src/main/java/com/sijobe/spc/command/Sudo.java @@ -37,16 +37,6 @@ public class Sudo extends StandardCommand { } ); - /** - * Command is only enabled in LAN/SMP mode - * - * @see com.sijobe.spc.wrapper.CommandBase#isEnabled() - */ - /*@Override - public boolean isEnabled() { - return !Minecraft.isSinglePlayer(); - }*/ - @Override public void execute(CommandSender sender, List params) throws CommandException { Player su = (Player)params.get(0); diff --git a/src/main/java/com/sijobe/spc/command/Waypoint.java b/src/main/java/com/sijobe/spc/command/Waypoint.java index 395fbe9..72c8d06 100644 --- a/src/main/java/com/sijobe/spc/command/Waypoint.java +++ b/src/main/java/com/sijobe/spc/command/Waypoint.java @@ -38,11 +38,6 @@ public Waypoint(String name) { super(name); } - @Override - public boolean isEnabled() { - return true; - } - @Override public String[] getCommands() { return new String[] {"set", "rem", "goto"}; diff --git a/src/main/java/com/sijobe/spc/network/Config.java b/src/main/java/com/sijobe/spc/network/Config.java index a7da875..dad05db 100644 --- a/src/main/java/com/sijobe/spc/network/Config.java +++ b/src/main/java/com/sijobe/spc/network/Config.java @@ -1,31 +1,66 @@ package com.sijobe.spc.network; +/** + * used to keep track of client side configuration somethings have to be done client side, + * like lighting up the world + * + * @author aucguy + * @version 1.0 + * @param + */ public final class Config { - static Config[] configs = new Config[256]; - public static final Config BLOCK_REACH = new Config(0, Float.class); - public static final Config NOCLIP = new Config(1, Boolean.class); - public static final Config LIGHT = new Config(2, Boolean.class); - public static final Config INSTANT_MINE = new Config(3, Boolean.class); - public static final Config LONGER_LEGS = new Config(4, Float.class); - public static final Config BIND = new Config(5, Integer.class); - - int id; - Class kind; - private IClientConfig handler; - - private Config(int id, Class kind) { - this.id = id; - this.kind = kind; - configs[this.id] = this; - } - - void callHook(T value) { - if(this.handler != null) { - this.handler.onConfigRecieved(value); - } - } - - public void setHandler(IClientConfig handler) { - this.handler = handler; - } + /** + * the array of configs. used to bind configs to ids + */ + static Config[] configs = new Config[256]; + public static final Config BLOCK_REACH = new Config(0, Float.class); + public static final Config NOCLIP = new Config(1, Boolean.class); + public static final Config LIGHT = new Config(2, Boolean.class); + public static final Config INSTANT_MINE = new Config(3, Boolean.class); + public static final Config LONGER_LEGS = new Config(4, Float.class); + public static final Config BIND = new Config(5, Integer.class); + + /** + * the id of the Config. Used to find out the contents of a PacketConfig + */ + int id; + + /** + * the payload of the packet and its config type. Used as a workaround of Paramatized types + */ + Class kind; + + /** + * the command that uses the client configurations + */ + private IClientConfig handler; + + /** + * constructs a Config + * @param id - the id of this config + * @param kind - the payload type of this config + */ + private Config(int id, Class kind) { + this.id = id; + this.kind = kind; + configs[this.id] = this; + } + + /** + * Sets the client configuration + * @param value - the value of the config set from the server + */ + void callHook(T value) { + if (this.handler != null) { + this.handler.onConfigRecieved(value); + } + } + + /** + * sets the command that uses this config + * @param handler - the command + */ + public void setHandler(IClientConfig handler) { + this.handler = handler; + } } diff --git a/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java b/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java index 64fba73..eb95d9c 100644 --- a/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java +++ b/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java @@ -5,6 +5,12 @@ import cpw.mods.fml.common.network.simpleimpl.MessageContext; import cpw.mods.fml.relauncher.Side; +/** + * handles Config Packets from the server + * + * @author aucguy + * @version 1.0 + */ public class ConfigMessageHandler implements IMessageHandler { @Override public IMessage onMessage(PacketConfig message, MessageContext ctx) { diff --git a/src/main/java/com/sijobe/spc/network/IClientConfig.java b/src/main/java/com/sijobe/spc/network/IClientConfig.java index 5f3bfc2..f0bc5db 100644 --- a/src/main/java/com/sijobe/spc/network/IClientConfig.java +++ b/src/main/java/com/sijobe/spc/network/IClientConfig.java @@ -2,7 +2,15 @@ import com.sijobe.spc.core.IHook; +/** + * used to signify that a command uses client-sided configurations + * + * @author aucguy + * + * @param - the payload and configuration type + */ public interface IClientConfig extends IHook { - public void onConfigRecieved(T value); - Config getConfig(); + public void onConfigRecieved(T value); + + Config getConfig(); } diff --git a/src/main/java/com/sijobe/spc/network/PacketConfig.java b/src/main/java/com/sijobe/spc/network/PacketConfig.java index 4d33634..09f32c3 100644 --- a/src/main/java/com/sijobe/spc/network/PacketConfig.java +++ b/src/main/java/com/sijobe/spc/network/PacketConfig.java @@ -3,57 +3,56 @@ import io.netty.buffer.ByteBuf; import cpw.mods.fml.common.network.simpleimpl.IMessage; +/** + * Sets client configurations + * + * @author aucguy + * @version 1.0 + */ public class PacketConfig implements IMessage { - Config config; - Object value; - - public PacketConfig() { - } - - public PacketConfig(Config config, Object value) { - this.config = config; - this.value = value; - if(!this.value.getClass().equals(this.config.kind)) { - throw(new IllegalArgumentException("value must be of type "+this.config.kind.getName()+ - " but instead was of type "+this.value.getClass().getName())); - } - } - - @Override - public void fromBytes(ByteBuf buf) { - byte id = buf.readByte(); - if(id > Config.configs.length || Config.configs[id] == null) { - return; - } - this.config = Config.configs[id]; - if(this.config.kind.equals(Boolean.class)) { - this.value = buf.readBoolean(); - } - else if(this.config.kind.equals(Integer.class)) { - this.value = buf.readInt(); - } - else if(this.config.kind.equals(Double.class)) { - this.value = buf.readDouble(); - } - else if(this.config.kind.equals(Float.class)) { - this.value = buf.readFloat(); - } - } - - @Override - public void toBytes(ByteBuf buf) { - buf.writeByte(this.config.id); - if(this.config.kind.equals(Boolean.class)) { - buf.writeBoolean((Boolean) this.value); - } - else if(this.config.kind.equals(Integer.class)) { - buf.writeInt((Integer) this.value); - } - else if(this.config.kind.equals(Double.class)) { - buf.writeDouble((Double) this.value); - } - else if(this.config.kind.equals(Float.class)) { - buf.writeFloat((Float) this.value); - } - } + Config config; + Object value; + + public PacketConfig() { + } + + public PacketConfig(Config config, Object value) { + this.config = config; + this.value = value; + if (!this.value.getClass().equals(this.config.kind)) { + throw (new IllegalArgumentException("value must be of type " + this.config.kind.getName() + " but instead was of type " + this.value.getClass().getName())); + } + } + + @Override + public void fromBytes(ByteBuf buf) { + byte id = buf.readByte(); + if (id > Config.configs.length || Config.configs[id] == null) { + return; + } + this.config = Config.configs[id]; + if (this.config.kind.equals(Boolean.class)) { + this.value = buf.readBoolean(); + } else if (this.config.kind.equals(Integer.class)) { + this.value = buf.readInt(); + } else if (this.config.kind.equals(Double.class)) { + this.value = buf.readDouble(); + } else if (this.config.kind.equals(Float.class)) { + this.value = buf.readFloat(); + } + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeByte(this.config.id); + if (this.config.kind.equals(Boolean.class)) { + buf.writeBoolean((Boolean) this.value); + } else if (this.config.kind.equals(Integer.class)) { + buf.writeInt((Integer) this.value); + } else if (this.config.kind.equals(Double.class)) { + buf.writeDouble((Double) this.value); + } else if (this.config.kind.equals(Float.class)) { + buf.writeFloat((Float) this.value); + } + } } diff --git a/src/main/java/com/sijobe/spc/proxy/Proxy.java b/src/main/java/com/sijobe/spc/proxy/Proxy.java index e89a8e7..ab39085 100644 --- a/src/main/java/com/sijobe/spc/proxy/Proxy.java +++ b/src/main/java/com/sijobe/spc/proxy/Proxy.java @@ -6,13 +6,64 @@ import net.minecraft.world.EnumDifficulty; -public abstract class Proxy{ - public abstract File getDataDirectory(); - public abstract Player getClientPlayer(); - public abstract boolean shouldNotRenderInsideOfBlock(); - public abstract void setDifficulty(EnumDifficulty difficulty); - public abstract void toggleClientLighting(boolean isLit); - public abstract boolean isClientGuiScreenOpen(); - public abstract void sendClientChat(String string); - public abstract void setClientHitDelay(int delay); +/** + * used so that side specific classes don't load on the wrong side + * + * @author aucguy + * @version 1.0 + */ +public abstract class Proxy { + /** + * @return file directory for the Minecraft Client + */ + public abstract File getDataDirectory(); + + /** + * @return the player on the client + */ + public abstract Player getClientPlayer(); + + /** + * @return whethor or not minecraft should render the inside of a block while + * inside of a block + */ + public abstract boolean shouldNotRenderInsideOfBlock(); + + /** + * sets the difficulty client-side (so it displays up correctly on the pause + * menu) + * + * @param difficulty - what to set the difficulty to + */ + public abstract void setDifficulty(EnumDifficulty difficulty); + + /** + * sets the client lighting status + * + * @param isLit - false if the world is lit normally, true if the world is to + * be fully lit + */ + public abstract void setClientLighting(boolean isLit); + + /** + * returns whether or not the client has a gui screen open + * + * @return + */ + public abstract boolean isClientGuiScreenOpen(); + + /** + * sends a chat packet to the server + * + * @param string - the chat to send + */ + public abstract void sendClientChat(String string); + + /** + * sets the block hit delay for the client. The block hit delay is how long to + * wait before the player starts the mine the next block + * + * @param delay - the block hit delay + */ + public abstract void setClientHitDelay(int delay); } diff --git a/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java b/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java index 674659e..f7f435e 100644 --- a/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java +++ b/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java @@ -37,7 +37,7 @@ public void setDifficulty(EnumDifficulty difficulty) { } @Override - public void toggleClientLighting(boolean isLit) { + public void setClientLighting(boolean isLit) { EntityPlayer player = Minecraft.getMinecraft().thePlayer; if(isLit) { player.addChatMessage(new ChatComponentText("Lighting world")); diff --git a/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java b/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java index 7762b75..07a80f5 100644 --- a/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java +++ b/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java @@ -47,7 +47,7 @@ public void setDifficulty(EnumDifficulty difficulty) { } @Override - public void toggleClientLighting(boolean isLit) { + public void setClientLighting(boolean isLit) { } @Override diff --git a/src/main/java/com/sijobe/spc/wrapper/Block.java b/src/main/java/com/sijobe/spc/wrapper/Block.java index ae2b9a6..3e10830 100644 --- a/src/main/java/com/sijobe/spc/wrapper/Block.java +++ b/src/main/java/com/sijobe/spc/wrapper/Block.java @@ -7,48 +7,79 @@ import net.minecraft.util.RegistryNamespaced; -public class Block -{ - public static final RegistryNamespaced blockRegistry = new RegistryIdCompatible(); - public static final Map conversionRegistry = new HashMap(); - public static final RegistryNamespaced realBlockRegistry = net.minecraft.block.Block.blockRegistry; - - public static void init() - { - /*registers blocks*/ - for(Object i : realBlockRegistry) - { - net.minecraft.block.Block block = (net.minecraft.block.Block) i; - int id = realBlockRegistry.getIDForObject(block); - Block wrapped = new Block(block); - blockRegistry.addObject(id, realBlockRegistry.getNameForObject(block), wrapped); - conversionRegistry.put(block, wrapped); - } - Blocks.init(); - } - - /*returns the block with the given id*/ - public static Block fromId(int id) - { - return (Block) blockRegistry.getObject(realBlockRegistry.getNameForObject(realBlockRegistry.getObjectById(id))); - } - - /*converts a minecraft block to a wrapped block. opposite of Block.convert()*/ - public static Block fromMinecraftBlock(net.minecraft.block.Block block) - { - return conversionRegistry.get(block); - } - - protected net.minecraft.block.Block block; - - public Block(net.minecraft.block.Block block) - { - this.block = block; - } - - /*returns the equivant minecraft block*/ - public net.minecraft.block.Block convert() - { - return this.block; - } +/** + * a wrapper block class + * + * @author aucguy + * @version 1.0 + */ +public class Block { + /** + * the wrapped block registry + */ + public static final RegistryNamespaced blockRegistry = new RegistryIdCompatible(); + + /** + * minecraft to wrapped block bindings + */ + public static final Map conversionRegistry = new HashMap(); + + /** + * the minecraft block registry + */ + public static final RegistryNamespaced realBlockRegistry = net.minecraft.block.Block.blockRegistry; + + /** + * initializes the block and conversion registry + */ + public static void init() { + /* registers blocks */ + for (Object i : realBlockRegistry) { + net.minecraft.block.Block block = (net.minecraft.block.Block) i; + int id = realBlockRegistry.getIDForObject(block); + Block wrapped = new Block(block); + blockRegistry.addObject(id, realBlockRegistry.getNameForObject(block), wrapped); + conversionRegistry.put(block, wrapped); + } + Blocks.init(); + } + + /** + * + * @param id - the id of the block + * @return the block with the given id + */ + public static Block fromId(int id) { + return (Block) blockRegistry.getObject(realBlockRegistry.getNameForObject(realBlockRegistry.getObjectById(id))); + } + + /** + * converts a minecraft block to a wrapped block. opposite of Block.convert() + * + * @param block - the minecraft block to convert + * @return - the wrapped block + */ + public static Block fromMinecraftBlock(net.minecraft.block.Block block) { + return conversionRegistry.get(block); + } + + /** + * the minecraft block associated with this instance + */ + protected net.minecraft.block.Block block; + + /** + * constructs a wrapped block + * @param block - the minecraft block + */ + public Block(net.minecraft.block.Block block) { + this.block = block; + } + + /** + * @return the equivant minecraft block + */ + public net.minecraft.block.Block convert() { + return this.block; + } } diff --git a/src/main/java/com/sijobe/spc/wrapper/Blocks.java b/src/main/java/com/sijobe/spc/wrapper/Blocks.java index b9be7c4..cf6d910 100644 --- a/src/main/java/com/sijobe/spc/wrapper/Blocks.java +++ b/src/main/java/com/sijobe/spc/wrapper/Blocks.java @@ -1,5 +1,11 @@ package com.sijobe.spc.wrapper; +/** + * kinda like net.minecraft.init.Blocks, but a wrapper + * + * @author aucguy + * @version 1.0 + */ public class Blocks { public static Block air; @@ -10,6 +16,9 @@ public class Blocks public static Block torch; public static Block dragon_egg; + /** + * initializes the blocks + */ static void init() { air = (Block) Block.blockRegistry.getObject("minecraft:air"); diff --git a/src/main/java/com/sijobe/spc/wrapper/Item.java b/src/main/java/com/sijobe/spc/wrapper/Item.java index 91a5347..3b5ec28 100644 --- a/src/main/java/com/sijobe/spc/wrapper/Item.java +++ b/src/main/java/com/sijobe/spc/wrapper/Item.java @@ -14,65 +14,70 @@ import net.minecraft.util.StatCollector; public class Item { - /** * A list of item names that are loaded in the game */ - public static final RegistryNamespaced itemRegistry = new RegistryIdCompatible(); - public static final Map conversionRegistry = new HashMap(); - public static final RegistryNamespaced realItemRegistry = net.minecraft.item.Item.itemRegistry; - - public static void init() - { - for (Object i : net.minecraft.item.Item.itemRegistry) - { - net.minecraft.item.Item item = (net.minecraft.item.Item) i; - int id = realItemRegistry.getIDForObject(item); - Item wrapped = new Item(item); - itemRegistry.addObject(id, realItemRegistry.getNameForObject(item), wrapped); - conversionRegistry.put(item, wrapped); - } - } + public static final RegistryNamespaced itemRegistry = new RegistryIdCompatible(); - protected net.minecraft.item.Item item; + /** + * binds minecraft items to wrapped items + */ + public static final Map conversionRegistry = new HashMap(); - public Item(net.minecraft.item.Item item) - { - this.item = item; + /** + * the minecraft item registry + */ + public static final RegistryNamespaced realItemRegistry = net.minecraft.item.Item.itemRegistry; + + /** + * initializes the itemRegistry and conversionRegistry + */ + public static void init() { + for (Object i : net.minecraft.item.Item.itemRegistry) { + net.minecraft.item.Item item = (net.minecraft.item.Item) i; + int id = realItemRegistry.getIDForObject(item); + Item wrapped = new Item(item); + itemRegistry.addObject(id, realItemRegistry.getNameForObject(item), wrapped); + conversionRegistry.put(item, wrapped); + } } - /*convert a wrapped item into a minecraft item*/ - public net.minecraft.item.Item convert() - { - return this.item; + /** + * the equivalent minecraft item + */ + protected net.minecraft.item.Item item; + + public Item(net.minecraft.item.Item item) { + this.item = item; } /** - * Translates the item code name into the item display name - * - * @param toTranslate - The item name to translate - * @return The display name of the item + * convert a wrapped item into a minecraft item + * @return the wrapped item */ - /*public static String translateItemName(String toTranslate) { - return StringTranslate.getInstance().translateNamedKey(toTranslate).toString().trim(); - }*/ - -/** + public net.minecraft.item.Item convert() { + return this.item; + } + + /** * Gets the item id of the specified item denoted by the string name * - * @param itemName - The name of the item + * @param itemName - The name of the item * @return the id of the item. If the item doesn't exist null is returned */ public static Item getItem(String itemName) { - return (Item) itemRegistry.getObject(itemName); + return (Item) itemRegistry.getObject(itemName); } - /*returns the converts the item to a minecraft item*/ - public static Item getItem(net.minecraft.item.Item item) - { - return conversionRegistry.get(item); + /** + * the converts the item to a minecraft item + * @param item - the minecraft item + * @return - the wrapped item + */ + public static Item getMinecraftItem(net.minecraft.item.Item item) { + return conversionRegistry.get(item); } - + /** * Returns true if the specified item id denotes a valid item * @@ -80,19 +85,19 @@ public static Item getItem(net.minecraft.item.Item item) * @return true is returned if the id is valid, false otherwise */ public static boolean isValidItem(Item item) { - return !(item == null) && itemRegistry.containsKey(itemRegistry.getNameForObject(item)); + return !(item == null) && itemRegistry.containsKey(itemRegistry.getNameForObject(item)); } - - /**TODO: remove arguement - * Gets the maximum stack size of the specified item + + /** + * TODO: remove arguement Gets the maximum stack size of the specified item * * @param id - does nothing * @return The stack size of the item, or 0 if not valid */ public int getMaxStack(Item id) { - return this.item.getItemStackLimit(); + return this.item.getItemStackLimit(); } - + /** * Gets a list containing all of the loaded enchantments * @@ -110,11 +115,11 @@ public static List getEnchantments() { } return names; } - + /** - * Adds the specified enchantment to the currently selected item in the + * Adds the specified enchantment to the currently selected item in the * players inventory - * + * * @param player - The player to add the enchantment to * @param enchantment - The enchantment to add * @param level - The level of the enchantment From 9db98d98f801895ddaf0f2d2b5d6978180820610 Mon Sep 17 00:00:00 2001 From: aucguy Date: Tue, 9 Dec 2014 23:02:31 -0600 Subject: [PATCH 18/20] Added obfuscated enviroment support and added lamp-post as an author --- src/build.gradle | 74 +++++++ src/main/java/com/sijobe/spc/ModSpc.java | 48 ++--- .../com/sijobe/spc/asm/MethodTransformer.java | 70 +++++- .../java/com/sijobe/spc/asm/Processor.java | 26 +++ .../com/sijobe/spc/asm/SlashPrefixer.java | 2 +- .../java/com/sijobe/spc/asm/SpcCoreMod.java | 6 + .../java/com/sijobe/spc/asm/Transformer.java | 7 + .../com/sijobe/spc/command/BlockReach.java | 3 +- .../java/com/sijobe/spc/command/SetSpeed.java | 24 +-- .../spc/network/ConfigMessageHandler.java | 4 +- .../com/sijobe/spc/network/DummyMessage.java | 15 ++ .../sijobe/spc/proxy/client/ClientProxy.java | 150 ++++++------- .../sijobe/spc/proxy/server/ServerProxy.java | 19 +- .../com/sijobe/spc/util/AccessHelper.java | 96 --------- .../java/com/sijobe/spc/util/ForgeHelper.java | 196 ----------------- .../com/sijobe/spc/util/ReflectionHelper.java | 200 +++++++++++------- .../sijobe/spc/wrapper/MinecraftServer.java | 7 +- .../java/com/sijobe/spc/wrapper/World.java | 18 +- src/main/resources/mcmod.info | 2 +- .../com/sijobe/spc/asm/make/ItemRenderer.java | 12 -- .../spc/asm/make/NetHandlerPlayServer.java | 69 ------ 21 files changed, 412 insertions(+), 636 deletions(-) create mode 100644 src/build.gradle create mode 100644 src/main/java/com/sijobe/spc/network/DummyMessage.java delete mode 100644 src/main/java/com/sijobe/spc/util/AccessHelper.java delete mode 100644 src/main/java/com/sijobe/spc/util/ForgeHelper.java delete mode 100644 src/make/com/sijobe/spc/asm/make/ItemRenderer.java delete mode 100644 src/make/com/sijobe/spc/asm/make/NetHandlerPlayServer.java diff --git a/src/build.gradle b/src/build.gradle new file mode 100644 index 0000000..0099f2e --- /dev/null +++ b/src/build.gradle @@ -0,0 +1,74 @@ +buildscript { + repositories { + mavenCentral() + maven { + name = "forge" + url = "http://files.minecraftforge.net/maven" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" + } + } + dependencies { + classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' + } +} + +apply plugin: 'forge' + +version = "5.0" +group= "com.sijobe.spc" // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = "spc" + +minecraft { + version = "1.7.2-10.12.2.1121" + assetDir = "eclipse/assets" +} + +dependencies { + // you may put jars on which you depend on in ./libs + // or you may define them like so.. + //compile "some.group:artifact:version:classifier" + //compile "some.group:artifact:version" + + // real examples + //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env + //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env + + // for more info... + // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html + // http://www.gradle.org/docs/current/userguide/dependency_management.html + +} + +processResources +{ + // this will ensure that this task is redone when the versions change. + inputs.property "version", project.version + inputs.property "mcversion", project.minecraft.version + + // replace stuff in mcmod.info, nothing else + from(sourceSets.main.resources.srcDirs) { + include 'mcmod.info' + + // replace version and mcversion + expand 'version':project.version, 'mcversion':project.minecraft.version + } + + // copy everything else, thats not the mcmod.info + from(sourceSets.main.resources.srcDirs) { + exclude 'mcmod.info' + } +} + +jar +{ + manifest + { + attributes( + "FMLCorePlugin": "com.sijobe.spc.asm.SpcCoreMod", + "FMLCorePluginContainsFMLMod": "true" + ) + } +} diff --git a/src/main/java/com/sijobe/spc/ModSpc.java b/src/main/java/com/sijobe/spc/ModSpc.java index e5e4b36..c28d35f 100644 --- a/src/main/java/com/sijobe/spc/ModSpc.java +++ b/src/main/java/com/sijobe/spc/ModSpc.java @@ -38,8 +38,11 @@ * @author aucguy * @version 1.0 */ -@Mod(useMetadata = true, modid = "spc", version = "5.0") -public class ModSpc { +@Mod( + useMetadata = true, + modid = "spc", + version = "5.0") +public class ModSpc { /** * the spc mod instance */ @@ -94,9 +97,7 @@ public ModSpc() { * @throws ClassNotFoundException - because of reflection */ @EventHandler - public void init(FMLInitializationEvent event) - throws InstantiationException, IllegalAccessException, - ClassNotFoundException { + public void init(FMLInitializationEvent event) throws InstantiationException, IllegalAccessException, ClassNotFoundException { this.side = event.getSide(); if (this.side == Side.CLIENT) { // if reflection wasn't used then when this class was loaded the @@ -104,27 +105,10 @@ public void init(FMLInitializationEvent event) // and since ClientProxy referrs to net.minecraft.client.Minecraft, // that would be loaded // loading net.minecraft.client.Minecraft on a server crashes it. - this.proxy = (Proxy) Class.forName( - "com.sijobe.spc.proxy.client.ClientProxy").newInstance(); // using - // reflection - // to - // prevent - // client - // class - // loading - // server - // side + this.proxy = (Proxy) Class.forName("com.sijobe.spc.proxy.client.ClientProxy").newInstance(); } else { - this.proxy = (Proxy) Class.forName( - "com.sijobe.spc.proxy.server.ServerProxy").newInstance(); // using - // reflection - // to - // prevent - // client - // class - // loading - // server - // side + // using reflection to prevent client classes loading server side + this.proxy = (Proxy) Class.forName("com.sijobe.spc.proxy.server.ServerProxy").newInstance(); } Block.init(); @@ -137,8 +121,7 @@ public void init(FMLInitializationEvent event) MinecraftForge.EVENT_BUS.register(this); FMLCommonHandler.instance().bus().register(this); this.networkHandler = new SimpleNetworkWrapper("spc.network"); - this.networkHandler.registerMessage(ConfigMessageHandler.class, - PacketConfig.class, 0, Side.CLIENT); + this.networkHandler.registerMessage(ConfigMessageHandler.class, PacketConfig.class, 0, Side.CLIENT); this.loadClientSettingHooks(); } @@ -185,9 +168,8 @@ public void onBreakSpeed(BreakSpeed event) { if (hook.isEnabled()) { // TODO pass same player instance instead of creating a new one each // time - event.newSpeed = hook.getBreakSpeed(new Player(event.entityPlayer), - Block.fromMinecraftBlock(event.block), event.metadata, - event.originalSpeed, event.x, event.y, event.z); + event.newSpeed = hook + .getBreakSpeed(new Player(event.entityPlayer), Block.fromMinecraftBlock(event.block), event.metadata, event.originalSpeed, event.x, event.y, event.z); } } } @@ -201,10 +183,8 @@ public void onBreakSpeed(BreakSpeed event) { public void onBlockBreak(BreakEvent event) { for (IBlockBroken hook : this.hookManager.getHooks(IBlockBroken.class)) { if (hook.isEnabled()) { - hook.onBreakBroken(event.x, event.y, event.z, - new World(event.world), - Block.fromMinecraftBlock(event.block), event.blockMetadata, - new Player(event.getPlayer())); + hook.onBreakBroken(event.x, event.y, event.z, new World(event.world), Block.fromMinecraftBlock(event.block), event.blockMetadata, new Player( + event.getPlayer())); } } } diff --git a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java index 2e8f59e..f8162dc 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java +++ b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java @@ -4,6 +4,7 @@ import java.lang.reflect.Modifier; import java.util.LinkedList; import java.util.List; +import java.util.Map; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -17,7 +18,8 @@ abstract class MethodTransformer extends MethodVisitor { /** - * the method id of this transformer a method id is in the format 'class:method:descriptor' + * the method id of this transformer a method id is in the format + * 'class:method:descriptor' */ String id; @@ -28,7 +30,58 @@ abstract class MethodTransformer extends MethodVisitor { */ MethodTransformer(String id) { super(Opcodes.ASM4); - this.id = id; + this.id = this.convertId(id); + } + + /** + * converts the given development-named id to the obfuscated id if necessary. + * + * @param id - the unobfuscated id + */ + protected String convertId(String id) { + if(Processor.getInstance().obfuscated) { + Map mappings = Processor.getInstance().mappings; + String[] parts = id.split(":"); + String oldClass = parts[0]; + String oldMethod = parts[1]; + String oldDescriptor = parts[2]; + String newClass = mappings.get(oldClass); + String newMethod = mappings.get(oldClass + "." + oldMethod); + + String[] partsDesc = oldDescriptor.split("\\)"); + String oldArgs = partsDesc[0].replace("(", ""); + String oldReturn = partsDesc[1]; + + String newArgs = ""; + for(int i=0; i < oldArgs.length(); i++) { + if(oldArgs.charAt(i) == 'L') { + i++; + String arg = ""; + for(; oldArgs.charAt(i) != ';'; i++) { + arg += oldArgs.charAt(i); + } + newArgs += "L" + mappings.get(arg.replace('/', '.')) + ";"; + } + else { + newArgs += oldArgs.charAt(i); + } + } + + String newReturn; + if(oldReturn.startsWith("L")) { + newReturn = "L"+mappings.get(oldReturn.substring(1, oldReturn.length()-1).replace('/', '.'))+";"; + } + else { + newReturn = oldReturn; + } + + String newId = newClass+":"+newMethod+":("+newArgs+")"+newReturn; + System.out.println("methodtranformer id '"+id+"' changed to '"+newId+"'."); + return newId; + } + else { + return id; + } } /** @@ -43,12 +96,15 @@ String getApplicableMethod() { /** * gives this MethodTrasnformer the method writer instance * - * @param mv - the MethodWriter created for this instance. Made just before this instance will visit things + * @param mv - the MethodWriter created for this instance. Made just before + * this instance will visit things */ abstract void injectMethodWriter(MethodVisitor mv); /** - * generates an array of MethodTransformers from a class of annotations. This allows for easy use of ASM modifications See com.sijobe.asm.SimpleHooked for an example. + * generates an array of MethodTransformers from a class of annotations. This + * allows for easy use of ASM modifications See com.sijobe.asm.SimpleHooked + * for an example. * * @param clazz - the class containing the modification methods. * @return an array of MethodTransformers that were generated @@ -58,13 +114,11 @@ static MethodTransformer[] generateFromFunctions(Class clazz) { for (Method method : clazz.getDeclaredMethods()) { if (Modifier.isStatic(method.getModifiers())) { if (method.isAnnotationPresent(MethodReplacer.Hook.class)) { - String annotation = method - .getAnnotation(MethodReplacer.Hook.class).value(); + String annotation = method.getAnnotation(MethodReplacer.Hook.class).value(); System.out.println("found replacement for " + annotation); modifiers.add(new MethodReplacer(annotation, method)); } else if (method.isAnnotationPresent(MethodPrefixer.Hook.class)) { - String annotation = method - .getAnnotation(MethodPrefixer.Hook.class).value(); + String annotation = method.getAnnotation(MethodPrefixer.Hook.class).value(); System.out.println("found prefix for " + annotation); modifiers.add(new MethodPrefixer(annotation, method)); } diff --git a/src/main/java/com/sijobe/spc/asm/Processor.java b/src/main/java/com/sijobe/spc/asm/Processor.java index e8d341c..a52a770 100644 --- a/src/main/java/com/sijobe/spc/asm/Processor.java +++ b/src/main/java/com/sijobe/spc/asm/Processor.java @@ -26,18 +26,44 @@ static Processor getInstance() { return instance; } + /** + * obfuscated name storage + */ + public Map mappings; + /** * maps class binary names to classTransformers */ protected Map classTransformers; + /** + * whether or not the class files are obfuscated + */ + public boolean obfuscated; + /** * makes a Processor */ Processor() { this.classTransformers = new HashMap(); + this.mappings = new HashMap(); + this.loadMappings(); } + /** + * loads the obfuscated name mappings + */ + protected void loadMappings() { + this.mappings.put("net.minecraft.client.multiplayer.PlayerControllerMP", "biy"); + this.mappings.put("net.minecraft.client.multiplayer.PlayerControllerMP.getBlockReachDistance", "d"); + this.mappings.put("net.minecraft.client.renderer.ItemRenderer", "blq"); + this.mappings.put("net.minecraft.client.renderer.ItemRenderer.renderInsideOfBlock", "a"); + this.mappings.put("net.minecraft.util.IIcon", "ps"); + this.mappings.put("net.minecraft.network.NetHandlerPlayServer", "mx"); + this.mappings.put("net.minecraft.network.NetHandlerPlayServer.processChatMessage", "a"); + this.mappings.put("net.minecraft.network.play.client.C01PacketChatMessage", "ie"); + } + /** * modifies the given bytecode with previously given Transformers * diff --git a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java index 0b1e016..a025cbc 100644 --- a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java +++ b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java @@ -5,7 +5,7 @@ import org.objectweb.asm.MethodVisitor; import com.sijobe.spc.command.PrefixSlash; -import com.sun.xml.internal.ws.org.objectweb.asm.Opcodes; +import org.objectweb.asm.Opcodes; /** * prefixes slashes onto commands if the player has it enabled diff --git a/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java b/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java index 321e28a..4e8c129 100644 --- a/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java +++ b/src/main/java/com/sijobe/spc/asm/SpcCoreMod.java @@ -6,6 +6,7 @@ import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion; import cpw.mods.fml.relauncher.IFMLLoadingPlugin.Name; import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.SortingIndex; /** * the spc coremod class @@ -15,6 +16,7 @@ @MCVersion("1.7.2") @Name("spc Coremod") @TransformerExclusions("com.sijobe.spc.asm") +@SortingIndex() //ensure notch names public class SpcCoreMod implements IFMLLoadingPlugin { @Override public String[] getASMTransformerClass() { @@ -33,6 +35,10 @@ public String getSetupClass() { @Override public void injectData(Map data) { + Processor processor = Processor.getInstance(); + processor.obfuscated = (Boolean) data.get("runtimeDeobfuscationEnabled"); + System.out.println("running in a" + (processor.obfuscated ? "n " : " de") + "obfuscated enviroment."); + Transformer.instance.hookTransformers(); } @Override diff --git a/src/main/java/com/sijobe/spc/asm/Transformer.java b/src/main/java/com/sijobe/spc/asm/Transformer.java index e762afb..cd5f8a7 100644 --- a/src/main/java/com/sijobe/spc/asm/Transformer.java +++ b/src/main/java/com/sijobe/spc/asm/Transformer.java @@ -4,11 +4,18 @@ /** * the ASMtransformer + * * @author aucguy * @version 1.0 */ public class Transformer implements IClassTransformer { + static Transformer instance; + public Transformer() { + instance = this; + } + + void hookTransformers() { Processor processor = Processor.getInstance(); processor.registerMethodTransformers(MethodTransformer.generateFromFunctions(SimpleHooked.class)); processor.registerMethodTransformer(new SlashPrefixer()); diff --git a/src/main/java/com/sijobe/spc/command/BlockReach.java b/src/main/java/com/sijobe/spc/command/BlockReach.java index 6eea3ca..91fb8fd 100644 --- a/src/main/java/com/sijobe/spc/command/BlockReach.java +++ b/src/main/java/com/sijobe/spc/command/BlockReach.java @@ -4,7 +4,6 @@ import com.sijobe.spc.network.Config; import com.sijobe.spc.network.IClientConfig; import com.sijobe.spc.network.PacketConfig; -import com.sijobe.spc.util.ForgeHelper; import com.sijobe.spc.validation.Parameter; import com.sijobe.spc.validation.Parameters; import com.sijobe.spc.validation.ParameterDouble; @@ -56,7 +55,7 @@ public void execute(CommandSender sender, List params) throws CommandExceptio EntityPlayerMP playerEntity = (EntityPlayerMP)player.getMinecraftPlayer(); if(params.size() == 0) { sender.sendMessageToPlayer("Current block reach distance: " + - ForgeHelper.getBlockReachDistance(playerEntity.theItemInWorldManager)); + playerEntity.theItemInWorldManager.getBlockReachDistance()); } else { double newReach = (Double)params.get(0); if(newReach < 4.5D || newReach > 255.0D) { diff --git a/src/main/java/com/sijobe/spc/command/SetSpeed.java b/src/main/java/com/sijobe/spc/command/SetSpeed.java index 12e83b7..b40dfee 100644 --- a/src/main/java/com/sijobe/spc/command/SetSpeed.java +++ b/src/main/java/com/sijobe/spc/command/SetSpeed.java @@ -1,7 +1,7 @@ package com.sijobe.spc.command; -import com.sijobe.spc.util.AccessHelper; import com.sijobe.spc.util.FontColour; +import com.sijobe.spc.util.ReflectionHelper; import com.sijobe.spc.util.Settings; import com.sijobe.spc.validation.Parameter; import com.sijobe.spc.validation.ParameterString; @@ -62,24 +62,10 @@ public void execute(CommandSender sender, List params) throws CommandExceptio try { float speed = Float.parseFloat((String)params.get(0)); config.set(CONFIG_KEY, speed); - try { - PlayerCapabilities capabilities = super.getSenderAsPlayer(sender).getMinecraftPlayer().capabilities; - AccessHelper.setFloat(capabilities, "walkSpeed", speed/10); - AccessHelper.setFloat(capabilities, "flySpeed", speed/20); - super.getSenderAsPlayer(sender).getMinecraftPlayer().sendPlayerAbilities(); - } catch (NoSuchFieldException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + PlayerCapabilities capabilities = super.getSenderAsPlayer(sender).getMinecraftPlayer().capabilities; + ReflectionHelper.setField(ReflectionHelper.walkSpeed, capabilities, speed/10); + ReflectionHelper.setField(ReflectionHelper.flySpeed, capabilities, speed/20); + super.getSenderAsPlayer(sender).getMinecraftPlayer().sendPlayerAbilities(); } catch (NumberFormatException e) { throw new CommandException("Could not parse " + (String)params.get(0) + " as a speed."); } diff --git a/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java b/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java index eb95d9c..82e5e1a 100644 --- a/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java +++ b/src/main/java/com/sijobe/spc/network/ConfigMessageHandler.java @@ -11,9 +11,9 @@ * @author aucguy * @version 1.0 */ -public class ConfigMessageHandler implements IMessageHandler { +public class ConfigMessageHandler implements IMessageHandler { @Override - public IMessage onMessage(PacketConfig message, MessageContext ctx) { + public DummyMessage onMessage(PacketConfig message, MessageContext ctx) { if(ctx.side != Side.CLIENT) { System.out.println("Config packet handled on server side. Abandon Ship!"); return null; diff --git a/src/main/java/com/sijobe/spc/network/DummyMessage.java b/src/main/java/com/sijobe/spc/network/DummyMessage.java new file mode 100644 index 0000000..6b60682 --- /dev/null +++ b/src/main/java/com/sijobe/spc/network/DummyMessage.java @@ -0,0 +1,15 @@ +package com.sijobe.spc.network; + +import io.netty.buffer.ByteBuf; +import cpw.mods.fml.common.network.simpleimpl.IMessage; + +public class DummyMessage implements IMessage { + + @Override + public void fromBytes(ByteBuf buf) { + } + + @Override + public void toBytes(ByteBuf buf) { + } +} diff --git a/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java b/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java index f7f435e..156eee4 100644 --- a/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java +++ b/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java @@ -1,8 +1,6 @@ package com.sijobe.spc.proxy.client; import java.io.File; -import java.lang.reflect.InvocationTargetException; - import net.minecraft.client.Minecraft; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.entity.player.EntityPlayer; @@ -12,92 +10,70 @@ import net.minecraft.world.EnumDifficulty; import com.sijobe.spc.proxy.Proxy; -import com.sijobe.spc.util.AccessHelper; +import com.sijobe.spc.util.ReflectionHelper; import com.sijobe.spc.wrapper.Player; public class ClientProxy extends Proxy { - @Override - public File getDataDirectory() { - return MinecraftClient.getMinecraftDirectory(); - } - - @Override - public Player getClientPlayer() { - return new Player(Minecraft.getMinecraft().thePlayer); - } - - @Override - public boolean shouldNotRenderInsideOfBlock() { - return Minecraft.getMinecraft().thePlayer.noClip; - } - - @Override - public void setDifficulty(EnumDifficulty difficulty) { - Minecraft.getMinecraft().gameSettings.difficulty = difficulty; - } - - @Override - public void setClientLighting(boolean isLit) { - EntityPlayer player = Minecraft.getMinecraft().thePlayer; - if(isLit) { - player.addChatMessage(new ChatComponentText("Lighting world")); - float[] lightBrightnessTable = player.worldObj.provider.lightBrightnessTable; - for(int i = 0; i < lightBrightnessTable.length; i++) { - lightBrightnessTable[i] = 1.0F; - } - } else { - player.addChatMessage(new ChatComponentText("Restoring light levels")); - try { - AccessHelper.callMethod(player.worldObj.provider, "generateLightBrightnessTable"); - } catch (NoSuchMethodException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvocationTargetException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - - @Override - public boolean isClientGuiScreenOpen() { - return MinecraftClient.isGuiScreenOpen(); - } - - @Override - public void sendClientChat(String message) { - NetHandlerPlayClient handler = MinecraftClient.getMinecraft().getNetHandler(); - if(handler != null) { - Packet packet = new C01PacketChatMessage(message); - handler.addToSendQueue(packet); - } - } - - @Override - public void setClientHitDelay(int delay) { - try { - AccessHelper.setInt(Minecraft.getMinecraft().playerController, "blockHitDelay", delay); - } catch (NoSuchFieldException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + @Override + public File getDataDirectory() { + return MinecraftClient.getMinecraftDirectory(); + } + + @Override + public Player getClientPlayer() { + return new Player(Minecraft.getMinecraft().thePlayer); + } + + @Override + public boolean shouldNotRenderInsideOfBlock() { + return Minecraft.getMinecraft().thePlayer.noClip; + } + + @Override + public void setDifficulty(EnumDifficulty difficulty) { + Minecraft.getMinecraft().gameSettings.difficulty = difficulty; + } + + @Override + public void setClientLighting(boolean isLit) { + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + if (isLit) { + player.addChatMessage(new ChatComponentText("Lighting world")); + float[] lightBrightnessTable = player.worldObj.provider.lightBrightnessTable; + for (int i = 0; i < lightBrightnessTable.length; i++) { + lightBrightnessTable[i] = 1.0F; + } + } else { + player.addChatMessage(new ChatComponentText("Restoring light levels")); + /*copied from WorldProvider.generateLightBrightnessTable*/ + float f = 0.0F; + + for (int i = 0; i <= 15; ++i) { + float f1 = 1.0F - (float) i / 15.0F; + player.worldObj.provider.lightBrightnessTable[i] = (1.0F - f1) / (f1 * 3.0F + 1.0F) + * (1.0F - f) + f; + } + } + } + + @Override + public boolean isClientGuiScreenOpen() { + return MinecraftClient.isGuiScreenOpen(); + } + + @Override + public void sendClientChat(String message) { + NetHandlerPlayClient handler = MinecraftClient.getMinecraft() + .getNetHandler(); + if (handler != null) { + Packet packet = new C01PacketChatMessage(message); + handler.addToSendQueue(packet); + } + } + + @Override + public void setClientHitDelay(int delay) { + ReflectionHelper.setField(ReflectionHelper.blockHitDelay, Minecraft + .getMinecraft().playerController, delay); + } } \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java b/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java index 07a80f5..430cc64 100644 --- a/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java +++ b/src/main/java/com/sijobe/spc/proxy/server/ServerProxy.java @@ -1,18 +1,20 @@ package com.sijobe.spc.proxy.server; import java.io.File; +import java.lang.reflect.Field; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.world.EnumDifficulty; import net.minecraft.server.dedicated.PropertyManager; import com.sijobe.spc.proxy.Proxy; -import com.sijobe.spc.util.AccessHelper; +import com.sijobe.spc.util.ReflectionHelper; import com.sijobe.spc.wrapper.MinecraftServer; import com.sijobe.spc.wrapper.Player; public class ServerProxy extends Proxy { - + public static final Field settingsField = ReflectionHelper.getField(DedicatedServer.class, "settings", "l", "field_71340_o"); + @Override public File getDataDirectory() { // TODO Auto-generated method stub @@ -32,18 +34,7 @@ public boolean shouldNotRenderInsideOfBlock() { @Override public void setDifficulty(EnumDifficulty difficulty) { DedicatedServer server = (DedicatedServer) MinecraftServer.getMinecraftServer(); - try { - ((PropertyManager) AccessHelper.getObj(server, "settings")).setProperty("difficulty", difficulty.getDifficultyId()); - } catch (NoSuchFieldException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + ((PropertyManager) ReflectionHelper.getObj(settingsField, server)).setProperty("difficulty", difficulty.getDifficultyId()); } @Override diff --git a/src/main/java/com/sijobe/spc/util/AccessHelper.java b/src/main/java/com/sijobe/spc/util/AccessHelper.java deleted file mode 100644 index 7a40944..0000000 --- a/src/main/java/com/sijobe/spc/util/AccessHelper.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.sijobe.spc.util; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class AccessHelper -{ - public static void setInt(Object obj, String name, int value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException - { - Class clazz = obj.getClass(); - Field field = clazz.getDeclaredField(name); - field.setAccessible(true); - field.setInt(obj, value); - } - - public static void setFloat(Object obj, String name, float value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException - { - Class clazz = obj.getClass(); - Field field = clazz.getDeclaredField(name); - field.setAccessible(true); - field.setFloat(obj, value); - } - - public static void setBoolean(Object obj, String name, boolean value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - Class clazz = obj.getClass(); - Field field; - while(true) - { - try - { - field = clazz.getDeclaredField(name); - break; - } - catch(NoSuchFieldException error) - { - if(clazz == Object.class) - { - throw(error); - } - clazz = clazz.getSuperclass(); - } - } - field.setAccessible(true); - field.setBoolean(obj, value); - } - - public static Object getObj(Object obj, String name) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { - Class clazz = obj.getClass(); - Field field; - while(true) - { - try - { - field = clazz.getDeclaredField(name); - break; - } - catch(NoSuchFieldException error) - { - if(clazz == Object.class) - { - throw(error); - } - clazz = clazz.getSuperclass(); - } - } - field.setAccessible(true); - return field.get(obj); - } - - @SuppressWarnings("unchecked") - public static T callMethod(Object obj, String name, Object ... args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException - { - Class clazz = obj.getClass(); - Method method; - while(true) - { - try - { - method = clazz.getDeclaredMethod(name); - break; - } - catch(NoSuchMethodException error) - { - if(clazz == Object.class) - { - throw(error); - } - clazz = clazz.getSuperclass(); - } - } - - method.setAccessible(true); - return (T) method.invoke(obj, args); - } -} diff --git a/src/main/java/com/sijobe/spc/util/ForgeHelper.java b/src/main/java/com/sijobe/spc/util/ForgeHelper.java deleted file mode 100644 index b474fe8..0000000 --- a/src/main/java/com/sijobe/spc/util/ForgeHelper.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.sijobe.spc.util; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; - -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.DamageSource; -import net.minecraft.entity.Entity; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.server.management.ItemInWorldManager; -import net.minecraft.world.WorldProvider; - -/** - * Helper for compatiblity with Minecraft Forge - * - * @author q3hardcore - * @version 1.0 - */ -public final class ForgeHelper { - - public static final boolean HAS_FORGE = getHasForge(); - - private final static Class forgeClass; - private final static Field eventBusField; - private final static Class eventClass; - private final static Class eventBusClass; - private final static Method post; - private final static Field capturedDropsField; - private final static Field captureDropsField; - private final static Class playerDropsEventClass; - private final static Constructor playerDropsEventConstructor; - private final static Class watchClass; - private final static Constructor watchConstructor; - private final static Method getBlockReachDistance; - private final static Method setBlockReachDistance; - private final static Class forgeHooksClass; - private final static Method onLivingDeath; - - private static boolean getHasForge() { - try { - Class.forName("net.minecraftforge.common.MinecraftForge"); - return true; - } catch (Throwable t) { - return false; - } - } - - public static ChunkCoordinates getRandomizedSpawnPoint(WorldProvider provider) { - ChunkCoordinates spawnPoint = new ChunkCoordinates(0, 64, 0); - try { - spawnPoint = (ChunkCoordinates)provider.getClass().getMethod("getRandomizedSpawnPoint").invoke(provider); - } catch (Throwable t) { - t.printStackTrace(); - } - return spawnPoint; - } - - public static void clearDrops(EntityPlayerMP entityPlayerMP) { - setCaptureDrops(entityPlayerMP, true); - getCapturedDrops(entityPlayerMP).clear(); - } - - public static void captureDrops(EntityPlayerMP entityPlayerMP, DamageSource damageSource, int recentlyHit) { - setCaptureDrops(entityPlayerMP, false); - Object event = createPlayerDropsEvent(entityPlayerMP, damageSource, getCapturedDrops(entityPlayerMP), recentlyHit > 0); - if(!postEvent(event)) { - for(EntityItem entityItem : getCapturedDrops(entityPlayerMP)) { - entityPlayerMP.worldObj.spawnEntityInWorld(entityItem); - } - } - } - - private static boolean postEvent(Object event) { - if(event == null) { - System.err.println("SPC/Forge: No event to post."); - return false; - } - try { - Object returnVal = post.invoke(eventBusField.get(null), new Object[]{event}); - return Boolean.parseBoolean(returnVal.toString()); - } catch (Throwable t) { - t.printStackTrace(); - return false; - } - } - - public static void watchChunk(ChunkCoordIntPair chunkCoord, EntityPlayerMP player) { - try { - Object event = watchConstructor.newInstance(new Object[]{chunkCoord, player}); - postEvent(event); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - private static Object createPlayerDropsEvent(EntityPlayer player, DamageSource damageSource, - ArrayList drops, boolean wasRecentlyHit) { - Object playerDropsEvent = null; - try { - playerDropsEvent = playerDropsEventConstructor.newInstance(new Object[]{player, damageSource, drops, wasRecentlyHit}); - } catch (Throwable t) { - t.printStackTrace(); - } - return playerDropsEvent; - } - - private static void setCaptureDrops(Entity entity, boolean val) { - try { - captureDropsField.set(entity, val); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - @SuppressWarnings("unchecked") - private static ArrayList getCapturedDrops(Entity entity) { - ArrayList capturedDrops = new ArrayList(); - try { - Object returnVal = capturedDropsField.get(entity); - if(returnVal instanceof ArrayList) { - capturedDrops = (ArrayList)returnVal; - } else { - System.err.println("SPC/Forge: Couldn't determine captured drops."); - } - } catch (Throwable t) { - t.printStackTrace(); - } - return capturedDrops; - } - - public static boolean onLivingDeath(EntityPlayerMP entityPlayerMP, DamageSource damageSource) { - try { - Object returnVal = onLivingDeath.invoke(null, entityPlayerMP, damageSource); - return Boolean.parseBoolean(returnVal.toString()); - } catch (Throwable t) { - t.printStackTrace(); - return false; - } - } - - public static double getBlockReachDistance(ItemInWorldManager manager) { - try { - Object returnVal = getBlockReachDistance.invoke(manager); - return Double.parseDouble(returnVal.toString()); - } catch (Throwable t) { - t.printStackTrace(); - return 5.0D; - } - } - - public static void setBlockReachDistance(ItemInWorldManager manager, double distance) { - try { - setBlockReachDistance.invoke(manager, distance); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - static { - if(HAS_FORGE) { - System.out.println("SPC: Detected Forge."); - forgeClass = ReflectionHelper.getClass("net.minecraftforge.common.MinecraftForge"); - eventBusField = ReflectionHelper.getField(forgeClass, "EVENT_BUS"); - eventClass = ReflectionHelper.getClass("net.minecraftforge.event.Event"); - eventBusClass = ReflectionHelper.getClass("net.minecraftforge.event.EventBus"); - post = ReflectionHelper.getMethod(eventBusClass, "post", eventClass); - capturedDropsField = ReflectionHelper.getField(Entity.class, "capturedDrops"); - captureDropsField = ReflectionHelper.getField(Entity.class, "captureDrops"); - playerDropsEventClass = ReflectionHelper.getClass("net.minecraftforge.event.entity.player.PlayerDropsEvent"); - final Class[] params = new Class[]{ EntityPlayer.class, DamageSource.class, ArrayList.class, Boolean.TYPE }; - playerDropsEventConstructor = ReflectionHelper.getConstructor(playerDropsEventClass, params); - watchClass = ReflectionHelper.getClass("net.minecraftforge.event.world.ChunkWatchEvent$Watch"); - watchConstructor = ReflectionHelper.getConstructor(watchClass, new Class[]{ChunkCoordIntPair.class, EntityPlayerMP.class}); - getBlockReachDistance = ReflectionHelper.getMethod(ItemInWorldManager.class, "getBlockReachDistance"); - setBlockReachDistance = ReflectionHelper.getMethod(ItemInWorldManager.class, "setBlockReachDistance", Double.TYPE); - forgeHooksClass = ReflectionHelper.getClass("net.minecraftforge.common.ForgeHooks"); - onLivingDeath = ReflectionHelper.getMethod(forgeHooksClass, "onLivingDeath", EntityLiving.class, DamageSource.class); - } else { - System.out.println("SPC: Forge not detected."); - forgeClass = null; eventBusField = null; - eventClass = null; eventBusClass = null; - post = null; - capturedDropsField = null; captureDropsField = null; - playerDropsEventClass = null; playerDropsEventConstructor = null; - watchClass = null; watchConstructor = null; - getBlockReachDistance = null; setBlockReachDistance = null; - forgeHooksClass = null; onLivingDeath = null; - } - } -} \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/util/ReflectionHelper.java b/src/main/java/com/sijobe/spc/util/ReflectionHelper.java index e0c32f3..f446e44 100644 --- a/src/main/java/com/sijobe/spc/util/ReflectionHelper.java +++ b/src/main/java/com/sijobe/spc/util/ReflectionHelper.java @@ -4,55 +4,76 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; +import net.minecraft.client.multiplayer.PlayerControllerMP; +import net.minecraft.entity.player.PlayerCapabilities; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.management.ServerConfigurationManager; + /** * Helper class for reflection - * + * * @author q3hardcore - * @version 1.4 + * @version 1.5 */ public class ReflectionHelper { - + /** + * stores obfuscation names + */ + public static final Mappings mappings = new Mappings(); + + /** + * a bunch of stuff that is accessed through reflection + */ + public static final Field blockHitDelay = getField(PlayerControllerMP.class, "blockHitDelay", "i", "field_78781_i"); + public static final Field walkSpeed = getField(PlayerCapabilities.class, "walkSpeed", "g", "field_75097_g"); + public static final Field flySpeed = getField(PlayerCapabilities.class, "flySpeed", "f", "field_75096_f"); + public static final Field commandsAllowedForAll = getField(ServerConfigurationManager.class, "commandsAllowedForAll", "o", "field_72407_n"); + public static final Method getDataDirectory = getMethod(MinecraftServer.class, new String[] { + "getDataDirectory", "r", "func_71238_n" }); + /** * The only blacklisted class - */ - private static final String blacklistedClass = "java.lang.Object"; - + */ + private static final String blacklistedClass = "java.lang.Object"; + /** * Gets the highest non-blacklisted superclass for a given class - * + * * @param clazz - The class to find the 'base class' of * @return The base class - */ + */ public static Class getBaseClass(Class clazz) { - if(clazz == null) { - System.err.println("No class specified."); - return null; - } - Class baseClass; - while((baseClass = clazz.getSuperclass()) != null && !baseClass.getName().equals(blacklistedClass)) { - clazz = baseClass; - } - return clazz; - } + if (clazz == null) { + System.err.println("No class specified."); + return null; + } + Class baseClass; + while ((baseClass = clazz.getSuperclass()) != null + && !baseClass.getName().equals(blacklistedClass)) { + clazz = baseClass; + } + return clazz; + } /** - * Finds the first method with that matches the specified name and parameters length - * + * Finds the first method with that matches the specified name and parameters + * length + * * @param clazz - The class to search * @param name - The method name * @param length - The parameter length * @return The first matching method, or null - */ + */ public static Method getPublicMethodWithParamsLength(Class clazz, String name, int length) { - if(clazz == null) { + if (clazz == null) { System.err.println("No class specified."); return null; } try { Method[] methods = clazz.getMethods(); - for(Method method : methods) { + for (Method method : methods) { boolean correctName = method.getName().equals(name); - if(correctName && method.getParameterTypes().length == length) { + if (correctName && method.getParameterTypes().length == length) { return method; } } @@ -65,19 +86,20 @@ public static Method getPublicMethodWithParamsLength(Class clazz, String name /** * Finds the first class that matches one of the names specified - * + * * @param classes - A list of all class names * @return The first class found, or null - */ - public static Class getClass(String ... classes) { - if(classes.length == 0) { + */ + public static Class getClass(String... classes) { + if (classes.length == 0) { System.err.println("No classes specified."); return null; } - for(String name : classes) { + for (String name : classes) { try { return Class.forName(name); - } catch (Throwable t) {} + } catch (Throwable t) { + } } return null; @@ -91,18 +113,19 @@ public static Class getClass(String ... classes) { * @return The value of the field */ public static boolean getBoolean(Field field, Object instance) { - if(field == null) { + if (field == null) { System.err.println("Null field"); return false; } try { return field.getBoolean(instance); } catch (Exception e) { - System.err.println(field.getType() + " not assignable from " + Boolean.TYPE); + System.err.println(field.getType() + " not assignable from " + + Boolean.TYPE); return false; } } - + /** * Gets a double value from the specified field * @@ -111,18 +134,19 @@ public static boolean getBoolean(Field field, Object instance) { * @return The value of the field */ public static double getDouble(Field field, Object instance) { - if(field == null) { + if (field == null) { System.err.println("Null field"); return -1.0D; } try { return field.getDouble(instance); } catch (Exception e) { - System.err.println(field.getType() + " not assignable from " + Double.TYPE); + System.err.println(field.getType() + " not assignable from " + + Double.TYPE); return -1.0D; } } - + /** * Gets an integer value from the specified field * @@ -131,50 +155,72 @@ public static double getDouble(Field field, Object instance) { * @return The value of the field */ public static int getInt(Field field, Object instance) { - if(field == null) { + if (field == null) { System.err.println("Null field"); return -1; } try { return field.getInt(instance); } catch (Exception e) { - System.err.println(field.getType() + " not assignable from " + Integer.TYPE); + System.err.println(field.getType() + " not assignable from " + + Integer.TYPE); return -1; } } - /** - * Sets the specified field to the specified value in the instance. + * Gets an object value from the specified field + * + * @param field - The field to get the value for + * @param instance - The instance to retrieve the value from + * @return The value of the field + */ + public static Object getObj(Field field, Object instance) { + if (field == null) { + System.err.println("Null field"); + return null; + } + try { + return field.get(instance); + } catch (Exception e) { + System.err.println(field.getType() + " not assignable from " + + Integer.TYPE); + return null; + } + } + + /** + * Sets the specified field to the specified value in the instance. * * @param field - The field to set * @param instance - The instance of the field to set * @param value - The value to set the field - * @return True if setting the field was successful. + * @return True if setting the field was successful. */ public static boolean setField(Field field, Object instance, Object value) { - if(field == null) { + if (field == null) { System.err.println("Null field"); return false; } try { field.set(instance, value); } catch (Exception e) { - System.err.println(field.getType() + " not assignable from " + value.getClass()); + System.err.println(field.getType() + " not assignable from " + + value.getClass()); return false; } return true; } - + /** * Attempts to get a constructor from the specified class - * + * * @param class - The class to retrieve constructor from * @param params - The parameters for the constructor * @return The constructor if found, otherwise null - */ - public static Constructor getConstructor(Class clazz, Class ... params) { - if(clazz == null) { + */ + public static Constructor getConstructor(Class clazz, Class... params) { + if (clazz == null) { System.err.println("No class specified."); return null; } @@ -183,13 +229,15 @@ public static Constructor getConstructor(Class clazz, Class ... params) constructor = clazz.getDeclaredConstructor(params); } catch (NoSuchMethodException nsme) { } - if(constructor == null) { - System.err.println(clazz.getName() + "does not have specified constructor"); + if (constructor == null) { + System.err.println(clazz.getName() + + "does not have specified constructor"); return null; } else { try { constructor.setAccessible(true); - } catch (SecurityException se) {} + } catch (SecurityException se) { + } return constructor; } } @@ -202,8 +250,8 @@ public static Constructor getConstructor(Class clazz, Class ... params) * @param params - A list of the methods parameters * @return The Method that matched, or null */ - public static Method getMethod(Class clazz, String methodName, Class ... params) { - return getMethod(clazz, new String[]{methodName}, params); + public static Method getMethod(Class clazz, String methodName, Class... params) { + return getMethod(clazz, new String[] { methodName }, params); } /** @@ -214,17 +262,17 @@ public static Method getMethod(Class clazz, String methodName, Class ... p * @param params - A list of the methods parameters * @return The Method that matched, or null */ - public static Method getMethod(Class clazz, String[] methodNames, Class ... params) { - if(clazz == null) { + public static Method getMethod(Class clazz, String[] methodNames, Class... params) { + if (clazz == null) { System.err.println("No class specified."); return null; } - if(methodNames == null || methodNames.length < 1) { + if (methodNames == null || methodNames.length < 1) { System.err.println("No methodNames specified."); return null; } Method method = null; - for(String methodName : methodNames) { + for (String methodName : methodNames) { try { method = clazz.getDeclaredMethod(methodName, params); break; @@ -234,16 +282,18 @@ public static Method getMethod(Class clazz, String[] methodNames, Class .. continue; } } - if(method == null) { - System.err.println(clazz.getName() + " does not have method " + methodNames[0]); - return null; + if (method == null) { + System.err.println(clazz.getName() + " does not have method " + + methodNames[0]); + return null; } else { try { method.setAccessible(true); - } catch (SecurityException se) {} + } catch (SecurityException se) { + } return method; } - } + } /** * Gets a field based off the field names provided by return the first one @@ -253,17 +303,17 @@ public static Method getMethod(Class clazz, String[] methodNames, Class .. * @param clazz - The class to retrieve the field from * @return The Field that matched, or null */ - public static Field getField(Class clazz, String ... fieldNames) { - if(clazz == null) { + public static Field getField(Class clazz, String... fieldNames) { + if (clazz == null) { System.err.println("No class specified."); return null; } - if(fieldNames == null || fieldNames.length < 1) { + if (fieldNames == null || fieldNames.length < 1) { System.err.println("No field name(s) specified."); return null; } Field field = null; - for(String fieldName : fieldNames) { + for (String fieldName : fieldNames) { try { field = clazz.getDeclaredField(fieldName); break; @@ -271,17 +321,19 @@ public static Field getField(Class clazz, String ... fieldNames) { continue; } } - if(field == null) { - System.err.println(clazz.getName() + " does not have field " + fieldNames[0]); - return null; + if (field == null) { + System.err.println(clazz.getName() + " does not have field " + + fieldNames[0]); + return null; } else { try { field.setAccessible(true); - } catch (SecurityException se) {} + } catch (SecurityException se) { + } return field; } } - + /** * Gets the field that matches the field names * @@ -289,12 +341,12 @@ public static Field getField(Class clazz, String ... fieldNames) { * @param instance - The instance (class) of the field * @return The field if found, or null */ - public static Field getField(Object instance, String ... fieldNames) { - if(instance != null) { + public static Field getField(Object instance, String... fieldNames) { + if (instance != null) { return getField(instance.getClass(), fieldNames); } else { return null; } } - + } \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/wrapper/MinecraftServer.java b/src/main/java/com/sijobe/spc/wrapper/MinecraftServer.java index 8d1fae0..4061fe8 100644 --- a/src/main/java/com/sijobe/spc/wrapper/MinecraftServer.java +++ b/src/main/java/com/sijobe/spc/wrapper/MinecraftServer.java @@ -7,7 +7,7 @@ import com.sijobe.spc.ModSpc; import com.sijobe.spc.core.Constants; -import com.sijobe.spc.util.AccessHelper; +import com.sijobe.spc.util.ReflectionHelper; import cpw.mods.fml.relauncher.Side; @@ -114,10 +114,7 @@ public static String getDirectoryName() { if(ModSpc.instance.side == Side.SERVER) { String dir = null; try { - dir = ((File) AccessHelper.callMethod(getMinecraftServer(), "getDataDirectory")).getAbsolutePath(); - } catch (NoSuchMethodException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + dir = ((File) ReflectionHelper.getDataDirectory.invoke(getMinecraftServer())).getAbsolutePath(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/src/main/java/com/sijobe/spc/wrapper/World.java b/src/main/java/com/sijobe/spc/wrapper/World.java index d8cd9ae..50308b1 100644 --- a/src/main/java/com/sijobe/spc/wrapper/World.java +++ b/src/main/java/com/sijobe/spc/wrapper/World.java @@ -4,7 +4,7 @@ import java.util.Random; import com.sijobe.spc.ModSpc; -import com.sijobe.spc.util.AccessHelper; +import com.sijobe.spc.util.ReflectionHelper; import net.minecraft.entity.effect.EntityLightningBolt; import net.minecraft.inventory.IInventory; @@ -109,21 +109,7 @@ public boolean isCheats() { */ public void setCheats(boolean cheats) { changeWorldInfo("allowCommands", cheats); - try { - AccessHelper.setBoolean(MinecraftServer.getMinecraftServer().getConfigurationManager(), "commandsAllowedForAll", cheats); - } catch (NoSuchFieldException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + ReflectionHelper.setField(ReflectionHelper.commandsAllowedForAll, MinecraftServer.getMinecraftServer().getConfigurationManager(), cheats); } /** diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 1fca447..e8830b0 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -7,7 +7,7 @@ "mcversion": "1.7.2", "url": "", "updateUrl": "", - "authorList": ["sijobe", "q3hardcore", "aucguy"], + "authorList": ["sijobe", "q3hardcore", "Lamp-Post", "aucguy"], "credits": "simo_415 for making this mod in the first place, q3hardcore and Lamp-Post for adding some commands and aucguy for updating the mod to minecraft 1.7.2", diff --git a/src/make/com/sijobe/spc/asm/make/ItemRenderer.java b/src/make/com/sijobe/spc/asm/make/ItemRenderer.java deleted file mode 100644 index 305ed58..0000000 --- a/src/make/com/sijobe/spc/asm/make/ItemRenderer.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.sijobe.spc.asm.make; - -import net.minecraft.util.IIcon; - -public class ItemRenderer { - @SuppressWarnings("unused") - private void renderInsideOfBlock(float par1, IIcon par2Icon) { - if(com.sijobe.spc.ModSpc.instance.proxy.shouldNotRenderInsideOfBlock()) { - return; - } - } -} diff --git a/src/make/com/sijobe/spc/asm/make/NetHandlerPlayServer.java b/src/make/com/sijobe/spc/asm/make/NetHandlerPlayServer.java deleted file mode 100644 index 24260c1..0000000 --- a/src/make/com/sijobe/spc/asm/make/NetHandlerPlayServer.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.sijobe.spc.asm.make; - -import org.apache.commons.lang3.StringUtils; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.network.NetworkManager; -import net.minecraft.network.play.client.C01PacketChatMessage; -import net.minecraft.network.play.server.S02PacketChat; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.ChatAllowedCharacters; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.EnumChatFormatting; -import net.minecraftforge.common.ForgeHooks; - -public class NetHandlerPlayServer extends net.minecraft.network.NetHandlerPlayServer { - public NetHandlerPlayServer(MinecraftServer par1MinecraftServer, - NetworkManager par2iNetworkManager, EntityPlayerMP par3EntityPlayerMP) { - super(par1MinecraftServer, par2iNetworkManager, par3EntityPlayerMP); - // TODO Auto-generated constructor stub - } - - public void processChatMessage(C01PacketChatMessage p_147354_1_) - { - if (this.playerEntity.func_147096_v() == EntityPlayer.EnumChatVisibility.HIDDEN) - { - ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("chat.cannotSend", new Object[0]); - chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.RED); - this.sendPacket(new S02PacketChat(chatcomponenttranslation)); - } - else - { - this.playerEntity.func_143004_u(); - String s = p_147354_1_.func_149439_c(); - s = StringUtils.normalizeSpace(s); - - for (int i = 0; i < s.length(); ++i) - { - if (!ChatAllowedCharacters.isAllowedCharacter(s.charAt(i))) - { - this.kickPlayerFromServer("Illegal characters in chat"); - return; - } - } - - if (com.sijobe.spc.asm.SlashPrefixer.isCommand(s, this)) - { - System.out.println(s); - //this.handleSlashCommand(s); - } - else - { - ChatComponentTranslation chatcomponenttranslation1 = new ChatComponentTranslation("chat.type.text", new Object[] {this.playerEntity.func_145748_c_(), s}); - chatcomponenttranslation1 = ForgeHooks.onServerChatEvent(this, s, chatcomponenttranslation1); - if (chatcomponenttranslation1 == null) return; - //this.serverController.getConfigurationManager().sendChatMsgImpl(chatcomponenttranslation1, false); - } - - //this.chatSpamThresholdCount += 20; - - /* - if (this.chatSpamThresholdCount > 200 && !this.serverController.getConfigurationManager().isPlayerOpped(this.playerEntity.getCommandSenderName())) - { - this.kickPlayerFromServer("disconnect.spam"); - } - */ - } - } -} From af437e7478f81072c2bef1775a09dc3a0c7b82d3 Mon Sep 17 00:00:00 2001 From: aucguy Date: Sun, 21 Dec 2014 21:30:28 -0600 Subject: [PATCH 19/20] actually works in an obfuscated enviroment --- .../com/sijobe/spc/asm/ClassTransformer.java | 2 +- .../sijobe/spc/asm/EntityReacherClient.java | 66 ++++++++++ .../sijobe/spc/asm/EntityReacherServer.java | 42 ++++++ .../com/sijobe/spc/asm/MethodTransformer.java | 95 +++++++++----- .../com/sijobe/spc/asm/ObfuscationData.java | 89 +++++++++++++ .../java/com/sijobe/spc/asm/Processor.java | 36 +++-- .../com/sijobe/spc/asm/SlashPrefixer.java | 8 +- .../java/com/sijobe/spc/asm/Transformer.java | 4 + .../sijobe/spc/asm/make/EntityRenderer.java | 123 ++++++++++++++++++ .../java/com/sijobe/spc/command/Macro.java | 1 + .../sijobe/spc/proxy/client/ClientProxy.java | 7 +- .../sijobe/spc/util/DynamicClassLoader.java | 1 + .../java/com/sijobe/spc/util/Mappings.java | 62 --------- .../com/sijobe/spc/util/ReflectionHelper.java | 7 - .../resources/com/sijobe/spc/asm/renames.txt | 14 ++ .../resources/com/sijobe/spc/asm/spc_at.txt | 2 - 16 files changed, 427 insertions(+), 132 deletions(-) create mode 100644 src/main/java/com/sijobe/spc/asm/EntityReacherClient.java create mode 100644 src/main/java/com/sijobe/spc/asm/EntityReacherServer.java create mode 100644 src/main/java/com/sijobe/spc/asm/ObfuscationData.java create mode 100644 src/main/java/com/sijobe/spc/asm/make/EntityRenderer.java delete mode 100644 src/main/java/com/sijobe/spc/util/Mappings.java create mode 100644 src/main/resources/com/sijobe/spc/asm/renames.txt delete mode 100644 src/main/resources/com/sijobe/spc/asm/spc_at.txt diff --git a/src/main/java/com/sijobe/spc/asm/ClassTransformer.java b/src/main/java/com/sijobe/spc/asm/ClassTransformer.java index 9329c10..0c31be5 100644 --- a/src/main/java/com/sijobe/spc/asm/ClassTransformer.java +++ b/src/main/java/com/sijobe/spc/asm/ClassTransformer.java @@ -62,7 +62,7 @@ public MethodVisitor visitMethod(int access, String name, String desc, if (this.methodTransformers.containsKey(id)) { MethodTransformer transformer = this.methodTransformers.get(id); transformer.injectMethodWriter(writer); - return transformer; + return transformer.new Wrapper(transformer); } else { return writer; } diff --git a/src/main/java/com/sijobe/spc/asm/EntityReacherClient.java b/src/main/java/com/sijobe/spc/asm/EntityReacherClient.java new file mode 100644 index 0000000..9511f0d --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/EntityReacherClient.java @@ -0,0 +1,66 @@ +package com.sijobe.spc.asm; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * makes the client allow customized reach distance for entities effectively + * removes the code: + * + * if (this.mc.playerController.extendedReach()) { d0 = 6.0D; d1 = 6.0D; } else + * { if (d0 > 3.0D) { d1 = 3.0D; } + * + * d0 = d1; } + * + * @author aucguy + * @version 1.0 + */ +public class EntityReacherClient extends MethodTransformer { + State state; + MethodVisitor writer; + + EntityReacherClient() { + super("net.minecraft.client.renderer.EntityRenderer:getMouseOver:(F)V"); + } + + @Override + void injectMethodWriter(MethodVisitor mv) { + this.mv = mv; + this.writer = mv; + } + + @Override + public void visitCode() { + this.state = State.PRE_CHANGE; + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc) { + if (this.state == State.PRE_CHANGE && opcode == Opcodes.INVOKEVIRTUAL + && owner.equals("net/minecraft/client/multiplayer/PlayerControllerMP") && name.equals("extendedReach") + && desc.equals("()Z")) { + this.state = State.AFTER_EXTEND; + this.mv = null; + this.writer.visitInsn(Opcodes.POP); + } else { + super.visitMethodInsn(opcode, owner, name, desc); + } + } + + @Override + public void visitVarInsn(int opcode, int var) { + if (this.state == State.AFTER_EXTEND && var == 0) { + this.state = State.POST_CHANGE; + this.mv = this.writer; + super.visitVarInsn(opcode, var); + } else { + super.visitVarInsn(opcode, var); + } + } + + enum State { + PRE_CHANGE, // before extendedReach() is called + AFTER_EXTEND, // after extendedReach() is called + POST_CHANGE; // after all the changes + } +} diff --git a/src/main/java/com/sijobe/spc/asm/EntityReacherServer.java b/src/main/java/com/sijobe/spc/asm/EntityReacherServer.java new file mode 100644 index 0000000..2523af1 --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/EntityReacherServer.java @@ -0,0 +1,42 @@ +package com.sijobe.spc.asm; + +import net.minecraft.network.NetHandlerPlayServer; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * makes the server allow customized reach distance for entities effectively + * changes the line in NetHandlerPlayServer.processUseEntity double d0 = 36.0 to + * double d0 = ReachChanger.getEntityReachDistance(this); + * + * @author aucguy + * @version 1.0 + * + */ +public class EntityReacherServer extends MethodTransformer { + + EntityReacherServer() { + super("net.minecraft.network.NetHandlerPlayServer:processUseEntity:(Lnet/minecraft/network/play/client/C02PacketUseEntity;)V"); + } + + @Override + void injectMethodWriter(MethodVisitor mv) { + this.mv = mv; + } + + @Override + public void visitLdcInsn(Object cst) { + if(cst.equals(36.0D)) { + super.visitVarInsn(Opcodes.ALOAD, 0); + super.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/asm/EntityReacherServer", "getEntityReachDistance", "(Lnet/minecraft/network/NetHandlerPlayServer;)D"); + } + else{ + super.visitLdcInsn(cst); + } + } + + public static double getEntityReachDistance(NetHandlerPlayServer handler) { + return Math.pow(handler.playerEntity.theItemInWorldManager.getBlockReachDistance(), 2); + } +} diff --git a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java index f8162dc..f174acb 100644 --- a/src/main/java/com/sijobe/spc/asm/MethodTransformer.java +++ b/src/main/java/com/sijobe/spc/asm/MethodTransformer.java @@ -16,6 +16,22 @@ * @version 1.0 */ abstract class MethodTransformer extends MethodVisitor { + /** + * allows for deobfuscated names to go through the visit methods + */ + final class Wrapper extends MethodVisitor { + Wrapper(MethodVisitor mv) { + super(Opcodes.ASM4, mv); + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc) { + String[] parts = convertMethod(owner.replace('/', '.'), name.replace('/', '.'), desc.replace('/', '.'), Processor + .getInstance().reversedMappings); + super.visitMethodInsn(opcode, parts[0].replace('.', '/'), parts[1].replace('.', '/'), parts[2] + .replace('.', '/')); + } + } /** * the method id of this transformer a method id is in the format @@ -30,60 +46,71 @@ abstract class MethodTransformer extends MethodVisitor { */ MethodTransformer(String id) { super(Opcodes.ASM4); - this.id = this.convertId(id); + String[] parts = id.split(":"); + String[] changed = convertMethod(parts[0], parts[1], parts[2]); + this.id = changed[0] + ":" + changed[1] + ":" + changed[2]; + System.out.println("id changed from "+id+" to "+this.id); + } + + protected String[] convertMethod(String oldOwner, String oldName, String oldDesc) { + return convertMethod(oldOwner, oldName, oldDesc, Processor.getInstance().mappings); } /** - * converts the given development-named id to the obfuscated id if necessary. + * converts the given development-named method to the obfuscated method if + * necessary. * - * @param id - the unobfuscated id + * @param oldOwner - the deobfuscated name of the class with the given method + * @param oldName - the deobfuscated name of the method + * @param oldDesc - the deobfuscated method descriptor + * @param slashes - whether or not the names contain slashes */ - protected String convertId(String id) { - if(Processor.getInstance().obfuscated) { - Map mappings = Processor.getInstance().mappings; - String[] parts = id.split(":"); - String oldClass = parts[0]; - String oldMethod = parts[1]; - String oldDescriptor = parts[2]; - String newClass = mappings.get(oldClass); - String newMethod = mappings.get(oldClass + "." + oldMethod); + protected static String[] convertMethod(String oldOwner, String oldName, String oldDesc, Map mappings) { + if (Processor.getInstance().obfuscated) { + String newOwner = mappings.get(oldOwner); + String[] parts = mappings.get(oldOwner + "." + oldName).split("\\."); + String newName = parts[parts.length-1]; - String[] partsDesc = oldDescriptor.split("\\)"); + String[] partsDesc = oldDesc.split("\\)"); String oldArgs = partsDesc[0].replace("(", ""); String oldReturn = partsDesc[1]; String newArgs = ""; - for(int i=0; i < oldArgs.length(); i++) { - if(oldArgs.charAt(i) == 'L') { + for (int i = 0; i < oldArgs.length(); i++) { + if (oldArgs.charAt(i) == 'L') { i++; String arg = ""; - for(; oldArgs.charAt(i) != ';'; i++) { + for (; oldArgs.charAt(i) != ';'; i++) { arg += oldArgs.charAt(i); } - newArgs += "L" + mappings.get(arg.replace('/', '.')) + ";"; - } - else { + newArgs += "L" + mappings.get(arg) + ";"; + } else { newArgs += oldArgs.charAt(i); } } String newReturn; - if(oldReturn.startsWith("L")) { - newReturn = "L"+mappings.get(oldReturn.substring(1, oldReturn.length()-1).replace('/', '.'))+";"; - } - else { + if (oldReturn.startsWith("L")) { + newReturn = "L" + mappings.get(oldReturn.substring(1, oldReturn.length() - 1)) + ";"; + } else { newReturn = oldReturn; } - String newId = newClass+":"+newMethod+":("+newArgs+")"+newReturn; - System.out.println("methodtranformer id '"+id+"' changed to '"+newId+"'."); + String[] newId = new String[] { newOwner, newName, "(" + newArgs + ")" + newReturn }; return newId; - } - else { - return id; + } else { + return new String[] { oldOwner, oldName, oldDesc }; } } + /** + * gives this MethodTrasnformer the method writer instance + * + * @param mv - the MethodWriter created for this instance. Made just before + * this instance will visit things + */ + abstract void injectMethodWriter(MethodVisitor mv); + /** * gets teh applicable method * @@ -93,13 +120,11 @@ String getApplicableMethod() { return this.id; } - /** - * gives this MethodTrasnformer the method writer instance - * - * @param mv - the MethodWriter created for this instance. Made just before - * this instance will visit things - */ - abstract void injectMethodWriter(MethodVisitor mv); + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc) { + String[] parts = convertMethod(owner.replace('/', '.'), name.replace('/', '.'), desc.replace('/', '.')); + super.visitMethodInsn(opcode, parts[0].replace('.', '/'), parts[1].replace('.', '/'), parts[2].replace('.', '/')); + } /** * generates an array of MethodTransformers from a class of annotations. This diff --git a/src/main/java/com/sijobe/spc/asm/ObfuscationData.java b/src/main/java/com/sijobe/spc/asm/ObfuscationData.java new file mode 100644 index 0000000..23fdb8a --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/ObfuscationData.java @@ -0,0 +1,89 @@ +package com.sijobe.spc.asm; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map.Entry; + +/** + * stores obfuscation mappings + * + * @author aucguy + * @version 1.0 + */ +class ObfuscationData extends HashMap { + private static final long serialVersionUID = 8501973207922800333L; + /** + * whether or not to warn about having no obfuscated mapping + */ + boolean shouldWarn = false; + + @Override + public String get(Object key) { + String str = ((String) key).replace('/', '.'); + if (this.containsKey(str)) { + return super.get(str); + } else { + if (shouldWarn && str.startsWith("net.minecraft.")) { + System.err.println("no obfuscated mapped for " + str); + } + return str; + } + } + + /** + * @param key - the key + * @param converted - if true, all '.' are replaced with '/' + * @return + */ + public String get(Object key, boolean converted) { + String value = this.get(key); + if(converted) { + value = value.replace('.', '/'); + } + return value; + } + + /** + * returns the value to key map of this + */ + + public ObfuscationData reverse() { + ObfuscationData map = new ObfuscationData(); + for(Entry entry : this.entrySet()) { + map.put(entry.getValue(), entry.getKey()); + } + return map; + } + + /** + * loads the obfuscated name mappings + */ + protected void loadMappings() { + try { + InputStream file = this.getClass().getResourceAsStream("renames.txt"); + if(file == null) { + throw(new IOException()); + } + byte[] data = new byte[file.available()]; + file.read(data); + String[] lines = new String(data).replace("\r", "\n").split("\n"); + for(String line : lines) { + if(line.length() == 0) { + continue; // blank line + } + line = line.split("#", 2)[0]; + String[] parts = line.split(" "); + if(parts.length != 2) { + continue; //invalid syntax + } + String deobfuscated = parts[0]; + String obfuscated = parts[1]; + this.put(deobfuscated, obfuscated); + } + } catch (IOException error) { + System.err.println("couldn't read obfuscation mappings"); + error.printStackTrace(); + } + } +} diff --git a/src/main/java/com/sijobe/spc/asm/Processor.java b/src/main/java/com/sijobe/spc/asm/Processor.java index a52a770..b030ca4 100644 --- a/src/main/java/com/sijobe/spc/asm/Processor.java +++ b/src/main/java/com/sijobe/spc/asm/Processor.java @@ -6,7 +6,8 @@ import org.objectweb.asm.ClassReader; /** - * Give it some bytecode and it will modify that class with the previously given transformers + * Give it some bytecode and it will modify that class with the previously given + * transformers * * @author aucguy * @version 1.0 @@ -29,7 +30,8 @@ static Processor getInstance() { /** * obfuscated name storage */ - public Map mappings; + public ObfuscationData mappings; + public ObfuscationData reversedMappings; /** * maps class binary names to classTransformers @@ -46,24 +48,11 @@ static Processor getInstance() { */ Processor() { this.classTransformers = new HashMap(); - this.mappings = new HashMap(); - this.loadMappings(); + this.mappings = new ObfuscationData(); + this.mappings.loadMappings(); + this.reversedMappings = this.mappings.reverse(); } - /** - * loads the obfuscated name mappings - */ - protected void loadMappings() { - this.mappings.put("net.minecraft.client.multiplayer.PlayerControllerMP", "biy"); - this.mappings.put("net.minecraft.client.multiplayer.PlayerControllerMP.getBlockReachDistance", "d"); - this.mappings.put("net.minecraft.client.renderer.ItemRenderer", "blq"); - this.mappings.put("net.minecraft.client.renderer.ItemRenderer.renderInsideOfBlock", "a"); - this.mappings.put("net.minecraft.util.IIcon", "ps"); - this.mappings.put("net.minecraft.network.NetHandlerPlayServer", "mx"); - this.mappings.put("net.minecraft.network.NetHandlerPlayServer.processChatMessage", "a"); - this.mappings.put("net.minecraft.network.play.client.C01PacketChatMessage", "ie"); - } - /** * modifies the given bytecode with previously given Transformers * @@ -76,7 +65,12 @@ byte[] process(String name, byte[] data) { ClassTransformer transformer = this.classTransformers.get(name); this.classTransformers.remove(name); ClassReader reader = new ClassReader(data); - reader.accept(transformer, 0); + try { + reader.accept(transformer, 0); + } catch (RuntimeException error) { + error.printStackTrace(); + throw(error); + } return transformer.getWriter().toByteArray(); } else { return data; @@ -93,12 +87,14 @@ void registerClassTransformer(ClassTransformer ct) { } /** - * registers the given method transformer with whatever classTransformer it goes with + * registers the given method transformer with whatever classTransformer it + * goes with * * @param mt - the methodTransformer to register */ void registerMethodTransformer(MethodTransformer mt) { String id = mt.getApplicableMethod(); + System.out.println("registering method transformer " + id); String clazz = id.split(":", 2)[0]; if (!this.classTransformers.containsKey(clazz)) { this.classTransformers.put(clazz, new ClassTransformer(clazz)); diff --git a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java index a025cbc..966ff6e 100644 --- a/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java +++ b/src/main/java/com/sijobe/spc/asm/SlashPrefixer.java @@ -35,17 +35,17 @@ void injectMethodWriter(MethodVisitor mv) { @Override public void visitLdcInsn(Object cst) { if (!cst.equals("/")) { - this.mv.visitLdcInsn(cst); + super.visitLdcInsn(cst); } } @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { if (opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/lang/String") && name.equals("startsWith") && desc.equals("(Ljava/lang/String;)Z")) { - this.mv.visitVarInsn(Opcodes.ALOAD, 0); - this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/asm/SlashPrefixer", "isCommand", "(Ljava/lang/String;Lnet/minecraft/network/NetHandlerPlayServer;)Z"); + super.visitVarInsn(Opcodes.ALOAD, 0); + super.visitMethodInsn(Opcodes.INVOKESTATIC, "com/sijobe/spc/asm/SlashPrefixer", "isCommand", "(Ljava/lang/String;Lnet/minecraft/network/NetHandlerPlayServer;)Z"); } else { - this.mv.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc); } } diff --git a/src/main/java/com/sijobe/spc/asm/Transformer.java b/src/main/java/com/sijobe/spc/asm/Transformer.java index cd5f8a7..1a4a2eb 100644 --- a/src/main/java/com/sijobe/spc/asm/Transformer.java +++ b/src/main/java/com/sijobe/spc/asm/Transformer.java @@ -17,8 +17,12 @@ public Transformer() { void hookTransformers() { Processor processor = Processor.getInstance(); + processor.mappings.shouldWarn = true; processor.registerMethodTransformers(MethodTransformer.generateFromFunctions(SimpleHooked.class)); processor.registerMethodTransformer(new SlashPrefixer()); + processor.registerMethodTransformer(new EntityReacherClient()); + processor.registerMethodTransformer(new EntityReacherServer()); + processor.mappings.shouldWarn = false; } @Override diff --git a/src/main/java/com/sijobe/spc/asm/make/EntityRenderer.java b/src/main/java/com/sijobe/spc/asm/make/EntityRenderer.java new file mode 100644 index 0000000..53e9c59 --- /dev/null +++ b/src/main/java/com/sijobe/spc/asm/make/EntityRenderer.java @@ -0,0 +1,123 @@ +package com.sijobe.spc.asm.make; + +import java.util.List; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityItemFrame; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; + +public class EntityRenderer extends net.minecraft.client.renderer.EntityRenderer { + private Entity pointedEntity; + private Minecraft mc; + + public EntityRenderer(Minecraft p_i45076_1_, IResourceManager p_i45076_2_) { + super(p_i45076_1_, p_i45076_2_); + } + + /** + * Finds what block or object the mouse is over at the specified partial tick time. Args: partialTickTime + */ + public void getMouseOver(float par1) + { + if (this.mc.renderViewEntity != null) + { + if (this.mc.theWorld != null) + { + this.mc.pointedEntity = null; + double d0 = (double)this.mc.playerController.getBlockReachDistance(); + this.mc.objectMouseOver = this.mc.renderViewEntity.rayTrace(d0, par1); + double d1 = d0; + Vec3 vec3 = this.mc.renderViewEntity.getPosition(par1); + if (this.mc.playerController.extendedReach()) + { + d0 = 6.0D; + d1 = 6.0D; + } + else + { + if (d0 > 3.0D) + { + d1 = 3.0D; + } + + d0 = d1; + } + + d0 = this.mc.playerController.getBlockReachDistance(); + d1 = d0; + + if (this.mc.objectMouseOver != null) + { + d1 = this.mc.objectMouseOver.hitVec.distanceTo(vec3); + } + + Vec3 vec31 = this.mc.renderViewEntity.getLook(par1); + Vec3 vec32 = vec3.addVector(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0); + this.pointedEntity = null; + Vec3 vec33 = null; + float f1 = 1.0F; + List list = this.mc.theWorld.getEntitiesWithinAABBExcludingEntity(this.mc.renderViewEntity, this.mc.renderViewEntity.boundingBox.addCoord(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0).expand((double)f1, (double)f1, (double)f1)); + double d2 = d1; + + for (int i = 0; i < list.size(); ++i) + { + Entity entity = (Entity)list.get(i); + + if (entity.canBeCollidedWith()) + { + float f2 = entity.getCollisionBorderSize(); + AxisAlignedBB axisalignedbb = entity.boundingBox.expand((double)f2, (double)f2, (double)f2); + MovingObjectPosition movingobjectposition = axisalignedbb.calculateIntercept(vec3, vec32); + + if (axisalignedbb.isVecInside(vec3)) + { + if (0.0D < d2 || d2 == 0.0D) + { + this.pointedEntity = entity; + vec33 = movingobjectposition == null ? vec3 : movingobjectposition.hitVec; + d2 = 0.0D; + } + } + else if (movingobjectposition != null) + { + double d3 = vec3.distanceTo(movingobjectposition.hitVec); + + if (d3 < d2 || d2 == 0.0D) + { + if (entity == this.mc.renderViewEntity.ridingEntity && !entity.canRiderInteract()) + { + if (d2 == 0.0D) + { + this.pointedEntity = entity; + vec33 = movingobjectposition.hitVec; + } + } + else + { + this.pointedEntity = entity; + vec33 = movingobjectposition.hitVec; + d2 = d3; + } + } + } + } + } + + if (this.pointedEntity != null && (d2 < d1 || this.mc.objectMouseOver == null)) + { + this.mc.objectMouseOver = new MovingObjectPosition(this.pointedEntity, vec33); + + if (this.pointedEntity instanceof EntityLivingBase || this.pointedEntity instanceof EntityItemFrame) + { + this.mc.pointedEntity = this.pointedEntity; + } + } + } + } + } +} diff --git a/src/main/java/com/sijobe/spc/command/Macro.java b/src/main/java/com/sijobe/spc/command/Macro.java index 03150b6..2f259eb 100644 --- a/src/main/java/com/sijobe/spc/command/Macro.java +++ b/src/main/java/com/sijobe/spc/command/Macro.java @@ -172,6 +172,7 @@ public String getMacro(String name, CommandSender sender) } byte[] data = new byte[(int) file.length()]; reader.read(data); + reader.close(); return new String(data); } diff --git a/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java b/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java index 156eee4..5922d17 100644 --- a/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java +++ b/src/main/java/com/sijobe/spc/proxy/client/ClientProxy.java @@ -1,7 +1,10 @@ package com.sijobe.spc.proxy.client; import java.io.File; +import java.lang.reflect.Field; + import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.network.Packet; @@ -14,6 +17,8 @@ import com.sijobe.spc.wrapper.Player; public class ClientProxy extends Proxy { + public static final Field blockHitDelayField = ReflectionHelper.getField(PlayerControllerMP.class, "blockHitDelay", "i", "field_78781_i"); + @Override public File getDataDirectory() { return MinecraftClient.getMinecraftDirectory(); @@ -73,7 +78,7 @@ public void sendClientChat(String message) { @Override public void setClientHitDelay(int delay) { - ReflectionHelper.setField(ReflectionHelper.blockHitDelay, Minecraft + ReflectionHelper.setField(blockHitDelayField, Minecraft .getMinecraft().playerController, delay); } } \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/util/DynamicClassLoader.java b/src/main/java/com/sijobe/spc/util/DynamicClassLoader.java index 97da6b8..efdd620 100644 --- a/src/main/java/com/sijobe/spc/util/DynamicClassLoader.java +++ b/src/main/java/com/sijobe/spc/util/DynamicClassLoader.java @@ -234,6 +234,7 @@ public static List> loadSPCClassesFromJAR(File jar) { } catch (Throwable t) { } } + jf.close(); } catch (Exception e) { e.printStackTrace(); return null; diff --git a/src/main/java/com/sijobe/spc/util/Mappings.java b/src/main/java/com/sijobe/spc/util/Mappings.java deleted file mode 100644 index b4e7d97..0000000 --- a/src/main/java/com/sijobe/spc/util/Mappings.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.sijobe.spc.util; - -import java.util.HashMap; - -/** - * Class for storing obfuscation mappings - * - * @author q3hardcore - * @version 1.3 - */ -public class Mappings extends HashMap { - - private static final long serialVersionUID = 1L; - - /** - * Adds a value to the map with all the alternate mappings - * - * @see java.util.HashMap#put(java.lang.Object, java.lang.Object) - */ - @Override - public String[] put(String mcpName, String[] alternateMappings) { - return super.put(mcpName, makeMapping(mcpName, alternateMappings)); - } - - /** - * Adds a value to the map without alteration - * - * @see java.util.HashMap#put(java.lang.Object, java.lang.Object) - */ - public String[] superPut(String key, String[] value) { - return super.put(key, value); - } - - /** - * Gets mappings for the specified value - * - * @see java.util.HashMap#get(java.lang.Object) - */ - @Override - public String[] get(Object key) { - String[] mappings = super.get(key); - if(mappings == null) { - return new String[]{ key.toString() }; - } else { - return mappings; - } - } - - /** - * @param mcpName - * @param mappings - * @return mappings with mcpName prepended - */ - private String[] makeMapping(String mcpName, String[] mappings) { - String[] newMappings = new String[mappings.length + 1]; - newMappings[0] = mcpName; - for(int i = 0; i < mappings.length; i++) { - newMappings[i+1] = mappings[i]; - } - return newMappings; - } -} \ No newline at end of file diff --git a/src/main/java/com/sijobe/spc/util/ReflectionHelper.java b/src/main/java/com/sijobe/spc/util/ReflectionHelper.java index f446e44..0a2980b 100644 --- a/src/main/java/com/sijobe/spc/util/ReflectionHelper.java +++ b/src/main/java/com/sijobe/spc/util/ReflectionHelper.java @@ -4,7 +4,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; -import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.entity.player.PlayerCapabilities; import net.minecraft.server.MinecraftServer; import net.minecraft.server.management.ServerConfigurationManager; @@ -16,15 +15,9 @@ * @version 1.5 */ public class ReflectionHelper { - /** - * stores obfuscation names - */ - public static final Mappings mappings = new Mappings(); - /** * a bunch of stuff that is accessed through reflection */ - public static final Field blockHitDelay = getField(PlayerControllerMP.class, "blockHitDelay", "i", "field_78781_i"); public static final Field walkSpeed = getField(PlayerCapabilities.class, "walkSpeed", "g", "field_75097_g"); public static final Field flySpeed = getField(PlayerCapabilities.class, "flySpeed", "f", "field_75096_f"); public static final Field commandsAllowedForAll = getField(ServerConfigurationManager.class, "commandsAllowedForAll", "o", "field_72407_n"); diff --git a/src/main/resources/com/sijobe/spc/asm/renames.txt b/src/main/resources/com/sijobe/spc/asm/renames.txt new file mode 100644 index 0000000..280d6d0 --- /dev/null +++ b/src/main/resources/com/sijobe/spc/asm/renames.txt @@ -0,0 +1,14 @@ +#mc version 1.7.2 +net.minecraft.client.multiplayer.PlayerControllerMP biy +net.minecraft.client.multiplayer.PlayerControllerMP.getBlockReachDistance biy.d +net.minecraft.client.multiplayer.PlayerControllerMP.extendedReach biy.i +net.minecraft.client.renderer.ItemRenderer blq +net.minecraft.client.renderer.ItemRenderer.renderInsideOfBlock blq.a +net.minecraft.util.IIcon ps +net.minecraft.network.NetHandlerPlayServer mx +net.minecraft.network.NetHandlerPlayServer.processChatMessage mx.a +net.minecraft.network.NetHandlerPlayServer.processUseEntity mx.a +net.minecraft.network.play.client.C01PacketChatMessage ie +net.minecraft.network.play.client.C02PacketUseEntity io +net.minecraft.client.renderer.EntityRenderer bll +net.minecraft.client.renderer.EntityRenderer.getMouseOver bll.a \ No newline at end of file diff --git a/src/main/resources/com/sijobe/spc/asm/spc_at.txt b/src/main/resources/com/sijobe/spc/asm/spc_at.txt deleted file mode 100644 index 2ef3da6..0000000 --- a/src/main/resources/com/sijobe/spc/asm/spc_at.txt +++ /dev/null @@ -1,2 +0,0 @@ -#public int blockHitDelay -#public net.minecraft.entity.Player.PlayerCapabilities walkSpeed \ No newline at end of file From 7fa65f275156f7919fb7f552f61a31b1198e77bb Mon Sep 17 00:00:00 2001 From: aucguy Date: Sun, 21 Dec 2014 21:34:19 -0600 Subject: [PATCH 20/20] removed unecessary files --- .../sijobe/spc/asm/make/EntityRenderer.java | 123 ------------------ 1 file changed, 123 deletions(-) delete mode 100644 src/main/java/com/sijobe/spc/asm/make/EntityRenderer.java diff --git a/src/main/java/com/sijobe/spc/asm/make/EntityRenderer.java b/src/main/java/com/sijobe/spc/asm/make/EntityRenderer.java deleted file mode 100644 index 53e9c59..0000000 --- a/src/main/java/com/sijobe/spc/asm/make/EntityRenderer.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.sijobe.spc.asm.make; - -import java.util.List; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.IResourceManager; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityItemFrame; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; - -public class EntityRenderer extends net.minecraft.client.renderer.EntityRenderer { - private Entity pointedEntity; - private Minecraft mc; - - public EntityRenderer(Minecraft p_i45076_1_, IResourceManager p_i45076_2_) { - super(p_i45076_1_, p_i45076_2_); - } - - /** - * Finds what block or object the mouse is over at the specified partial tick time. Args: partialTickTime - */ - public void getMouseOver(float par1) - { - if (this.mc.renderViewEntity != null) - { - if (this.mc.theWorld != null) - { - this.mc.pointedEntity = null; - double d0 = (double)this.mc.playerController.getBlockReachDistance(); - this.mc.objectMouseOver = this.mc.renderViewEntity.rayTrace(d0, par1); - double d1 = d0; - Vec3 vec3 = this.mc.renderViewEntity.getPosition(par1); - if (this.mc.playerController.extendedReach()) - { - d0 = 6.0D; - d1 = 6.0D; - } - else - { - if (d0 > 3.0D) - { - d1 = 3.0D; - } - - d0 = d1; - } - - d0 = this.mc.playerController.getBlockReachDistance(); - d1 = d0; - - if (this.mc.objectMouseOver != null) - { - d1 = this.mc.objectMouseOver.hitVec.distanceTo(vec3); - } - - Vec3 vec31 = this.mc.renderViewEntity.getLook(par1); - Vec3 vec32 = vec3.addVector(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0); - this.pointedEntity = null; - Vec3 vec33 = null; - float f1 = 1.0F; - List list = this.mc.theWorld.getEntitiesWithinAABBExcludingEntity(this.mc.renderViewEntity, this.mc.renderViewEntity.boundingBox.addCoord(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0).expand((double)f1, (double)f1, (double)f1)); - double d2 = d1; - - for (int i = 0; i < list.size(); ++i) - { - Entity entity = (Entity)list.get(i); - - if (entity.canBeCollidedWith()) - { - float f2 = entity.getCollisionBorderSize(); - AxisAlignedBB axisalignedbb = entity.boundingBox.expand((double)f2, (double)f2, (double)f2); - MovingObjectPosition movingobjectposition = axisalignedbb.calculateIntercept(vec3, vec32); - - if (axisalignedbb.isVecInside(vec3)) - { - if (0.0D < d2 || d2 == 0.0D) - { - this.pointedEntity = entity; - vec33 = movingobjectposition == null ? vec3 : movingobjectposition.hitVec; - d2 = 0.0D; - } - } - else if (movingobjectposition != null) - { - double d3 = vec3.distanceTo(movingobjectposition.hitVec); - - if (d3 < d2 || d2 == 0.0D) - { - if (entity == this.mc.renderViewEntity.ridingEntity && !entity.canRiderInteract()) - { - if (d2 == 0.0D) - { - this.pointedEntity = entity; - vec33 = movingobjectposition.hitVec; - } - } - else - { - this.pointedEntity = entity; - vec33 = movingobjectposition.hitVec; - d2 = d3; - } - } - } - } - } - - if (this.pointedEntity != null && (d2 < d1 || this.mc.objectMouseOver == null)) - { - this.mc.objectMouseOver = new MovingObjectPosition(this.pointedEntity, vec33); - - if (this.pointedEntity instanceof EntityLivingBase || this.pointedEntity instanceof EntityItemFrame) - { - this.mc.pointedEntity = this.pointedEntity; - } - } - } - } - } -}