Compare commits

..
243 Commits
Author SHA1 Message Date
Myles 9a781d940f Bump version 2016-03-09 14:29:30 +00:00
Myles fed36c9487 synchronize all the things! 2016-03-09 14:12:50 +00:00
Myles 463327c2a7 Bump version to 0.6.1 snapshot 2016-03-09 12:09:24 +00:00
Myles b0050d4a8d Add config option for blocking and fix crash due to synchronization 2016-03-09 12:08:21 +00:00
Myles a743895c3f Bump version to 0.6.0-SNAPSHOT 2016-03-09 01:13:24 +00:00
Myles f65666b7a6 Better support for ServerConnection detection, and also adding injectors. (Basic late-bind support is now available, but does not work with ProtocolLib due to it injecting first.) 2016-03-09 00:51:50 +00:00
Myles 3a217503fc Merge pull request #179 from HugoDaBosss/master
Stop error fetching hand item spamming console.
2016-03-08 21:24:47 +00:00
Myles c71b75e13b Oops 2016-03-08 21:23:57 +00:00
HugoDaBosss 0c890c3a30 Print errors while in debug mode 2016-03-08 22:23:36 +01:00
HugoDaBosss f38bb0ca22 Stop error fetching hand item spamming console. 2016-03-08 22:20:52 +01:00
Myles 2144fa1837 Handle any exception so it doesn't implode. (Still prints to the console.) 2016-03-08 21:16:34 +00:00
Myles fc4a617da7 Don't send chunk packets with no chunks :) 2016-03-08 21:13:15 +00:00
Myles 126ee6e03f Formatting 2016-03-08 20:54:03 +00:00
Myles 498867032f Merge pull request #178 from HugoDaBosss/master
Fix animation for bows
2016-03-08 20:51:02 +00:00
HugoDaBosss aef8eca790 Fix animation for bows 2016-03-08 21:48:21 +01:00
Myles d8bbb51721 Merge branch 'master' of https://github.com/MylesIsCool/ViaVersion 2016-03-08 19:27:24 +00:00
Myles 6e4fd5a63b Only show blocking if it knows that we're blocking #176 2016-03-08 19:27:04 +00:00
Myles e7bd6245c2 Merge pull request #175 from Matsv/master
Reimplement bossbar methods
2016-03-08 14:02:18 +00:00
Mats 6242cb0b47 Merge remote-tracking branch 'origin/master' 2016-03-08 13:48:20 +01:00
Mats bf5072e1cf Add removed bossbar methods 2016-03-08 13:48:03 +01:00
Mats c24b673550 Add removed bossbar methods 2016-03-08 13:46:30 +01:00
Myles dfc1e1cf51 Merge pull request #174 from Matsv/master
Add /viaversion debug to the commandlist
2016-03-08 12:42:16 +00:00
Mats c600ab6dd1 Add /viaversion debug to the commandlist 2016-03-08 13:30:53 +01:00
Myles 29754c0787 Bump version 2016-03-07 23:53:15 +00:00
Myles 9144980474 Read full dig packet 2016-03-07 23:52:12 +00:00
Myles 6a449f8db1 Allow the suppressing of metadata errors. 2016-03-07 22:55:57 +00:00
Myles 3780210f76 Merge branch 'master' of https://github.com/MylesIsCool/ViaVersion 2016-03-07 22:21:47 +00:00
Myles 67bad0dec8 Add it so when you're on 1.9 you can block using shields. Also change ConnectionInfo to use lombok. 2016-03-07 22:21:32 +00:00
Hugo Kerstens 79291fd7d9 Merge pull request #171 from Matsv/jukeboxfixje
Fix jukebox
2016-03-07 23:10:23 +01:00
Mats ee9d8d6365 Add comment for other people 2016-03-07 23:08:34 +01:00
Mats cc354db464 Formatting 2016-03-07 23:07:17 +01:00
Mats 2b29d27b0d Fix jukebox 2016-03-07 23:04:24 +01:00
Myles 75db62ee6f Merge pull request #167 from rj0495/patch-1
Added fallback options on CommandHandler
2016-03-07 20:53:11 +00:00
Myles 7cd7b5ba24 Be nice and set a user agent for updater 2016-03-07 20:13:01 +00:00
Ryan James a3bfcefdca Added fallback options on CommandHandler 2016-03-07 19:39:10 +00:00
Myles 098b787355 Update to 0.5.8-SNAPSHOT 2016-03-07 19:36:47 +00:00
Myles abb9665813 Merge pull request #166 from StamBoom/master
Change DataInputStream / DataOutputStream to readNBT / writeNBT
2016-03-07 19:30:41 +00:00
Myles 012eec47b5 Temp arrays are evil, (memory optimisation) 2016-03-07 19:19:14 +00:00
Mats 2d40afa3a1 Change DataInputstream / Outputstream to readNBT / writeNBT 2016-03-07 19:58:07 +01:00
Myles a92a7d6e02 Merge pull request #165 from StamBoom/savedthehorses
Fixed horses inventory/elytra exception
2016-03-07 18:52:11 +00:00
Myles fc7cdb4244 Clear bytes instead of reading them, close streams when done. (May fix a few memory leaks) 2016-03-07 18:51:18 +00:00
Mats d5b375b264 Fixed horses inventory/elytra exception 2016-03-07 19:45:00 +01:00
Myles 99eadbe343 Update readme 2016-03-07 16:50:50 +00:00
Myles 38d33dba16 Remove more methods (Sorry last one didn't build!) 2016-03-07 16:44:55 +00:00
Myles b3de4de0cd Remove us.myles.ViaVersion.chunks, I must have looked past this but it's not used. 2016-03-07 16:34:22 +00:00
Myles 6b5c166a22 Merge pull request #162 from phenomax/master
General code improvements
2016-03-07 16:28:04 +00:00
Phenomax 1aea00036f [~] smaller bugfixes]
[~] switched back to jdk 7
2016-03-07 16:22:11 +01:00
Phenomax 1262847a0e [+] added lombok in order to smaller code by removing unnecessary getter, setter and constructors
[~] switched to bytecode version 1.8 (lambda expressions)
[~] general code cleanup (lambda expressions, for each, collapsed catch blocks, diamond maps)
2016-03-07 15:43:31 +01:00
Myles 21cfb1297f Fix powered minecart data 2016-03-07 11:51:51 +00:00
Myles 0b1cb61986 Send team at difficulty to avoid any issues with bungee #161 2016-03-07 11:31:04 +00:00
Myles 44907b3e8d Add /viaversion autoteam to toggle auto teaming for 1.8 colliding. 2016-03-07 11:09:43 +00:00
Myles dac616d72c Bump snapshot version up 2016-03-06 23:42:27 +00:00
Myles 528b234d5a Add collision options, fixes #95. (By default auto teams players until they're added to a team so you can't push!) 2016-03-06 23:22:45 +00:00
HugoDaBosss e4288383f4 Merge pull request #159 from HugoDaBosss/patch
Change package name from bossbarapi to lowercase.
2016-03-06 23:39:52 +01:00
BuildTools bb17eb01b8 Update 2016-03-06 23:17:51 +01:00
Myles ca6638c740 return null if the item is null :) 2016-03-06 21:40:15 +00:00
Myles d8ce66ce29 Merge pull request #158 from StamBoom/bossbar
Implement 1.9 BossBarAPI for developers
2016-03-06 18:35:55 +00:00
Mats 8460c157a5 Commit API 2016-03-06 19:27:26 +01:00
Mats 0b807569ad Implement 1.9 BossBarAPI for developers 2016-03-06 19:20:39 +01:00
Myles 75d001d09b Merge pull request #157 from rj0495/patch-3
Travis Build Status
2016-03-06 17:37:37 +00:00
Ryan James 2118379cf7 Travis Build Status 2016-03-06 17:35:54 +00:00
Myles cd2441ee52 Update README.md 2016-03-06 17:22:56 +00:00
Myles ffb4fb5c5a Merge pull request #155 from sgdc3/master
Improve POM and fix dead code
2016-03-06 16:48:41 +00:00
Myles c404f2206c Blame a class when the childHandler doesn't inject 2016-03-06 16:16:26 +00:00
Gabriele C aec5aa48da Bump 2016-03-06 16:38:58 +01:00
Gabriele C b63051a796 Improve POM and fix dead code 2016-03-06 16:36:54 +01:00
Myles ea4650000e Bump to 0.5.5 2016-03-06 15:16:36 +00:00
Myles 2d2018b8d0 Disable latest feature due to it breaking signs (no more sync chunks for now) 2016-03-06 15:10:54 +00:00
HugoDaBosss 736a853a85 Merge pull request #153 from HugoDaBosss/patch
Make Metadata Rewriter exception output more clear
2016-03-06 16:00:50 +01:00
HugoDaBosss dfd4c5f93e Formatting 2016-03-06 15:55:53 +01:00
HugoDaBosss 2ac87acc8a Make Metadata Rewriter exception output more clear 2016-03-06 15:52:06 +01:00
Myles 3c5a6a3b7b Fix README, also change a bit of the fixJson so that it can handle quotes on signs. 2016-03-06 14:40:23 +00:00
Myles 6efb5c1b64 Merge pull request #151 from HugoDaBosss/patch
Fix checkforupdates changing from false to true
2016-03-06 14:20:45 +00:00
HugoDaBosss 91de7e5a22 Fix checkforupdates changing from false to true
FIXED:
When starting the server when checkforupdates is false, it won't register the listener.
So when you enable checkforupdates using /viaversion dontbugme it won't send you messages until a restart.
2016-03-06 15:11:36 +01:00
Myles 1c42ae1ee8 Update version to 0.5.4 2016-03-06 13:52:38 +00:00
Myles c5ac3c9b3d Don't freeze current thread when sending chunks 2016-03-06 13:49:33 +00:00
Myles 0ea32b3318 Merge pull request #150 from HugoDaBosss/patch
Fix mob spawners when no EntityId is given
2016-03-06 13:45:56 +00:00
Myles 8afc850ed3 Add new config option "sync-chunks", chunks will now be sent in sync with the MC thread when true, this fixes timings (paper spigot mostly issue) 2016-03-06 13:45:26 +00:00
HugoDaBosss 3c6dcfe5bf Update OutgoingTransformer.java 2016-03-06 14:42:50 +01:00
HugoDaBosss 59d637e0f5 More formatting (stupid eclipse) 2016-03-06 14:42:22 +01:00
HugoDaBosss 923f3088c0 Formatting 2016-03-06 14:40:52 +01:00
HugoDaBosss 4f8aff9c01 Forgot to remove debug message 2016-03-06 14:37:51 +01:00
HugoDaBosss 99ceb9ae79 Fix mob spawners when no EntityId is given 2016-03-06 14:32:57 +01:00
Myles 6e0554f4a4 Fix enchanting tooltips 2016-03-06 13:22:56 +00:00
Myles 36879f8d02 Fix small issue with updater 2016-03-06 13:02:54 +00:00
Myles fe77df1434 Fix brewing #141 2016-03-06 12:25:54 +00:00
Myles 713361f973 Merge pull request #148 from StamBoom/master
Fix commandblock minecarts
2016-03-06 11:20:50 +00:00
Mats a314b86f57 Fix commandblock minecarts 2016-03-06 12:18:18 +01:00
Myles 840c90f871 Don't use GSON >.> 2016-03-06 11:03:41 +00:00
Myles 2a247595c8 Handle invalid version numbers 2016-03-06 10:49:21 +00:00
Myles 4124c3454e Change it so when there is no connection we don't bug them. Also change it to use http instead of https, as https requires certain certificate info by linux. 2016-03-06 10:46:38 +00:00
HugoDaBosss c4185e3056 Merge pull request #147 from fillefilip8/patch-4
Made the config use the default bukkit config methods insteed.
2016-03-06 10:56:07 +01:00
fillefilip8 d6403d495d Opps :) Github likes me :D Removed the new api methods from this branch :D 2016-03-06 10:42:26 +01:00
fillefilip8 d7f54048ff Made the config use the default bukkit config methods insteed. 2016-03-06 10:39:58 +01:00
Myles e487eeb395 Update to 0.5.3, add inventory title tracking so we're working towards some of the inventory bugs with new ones. 2016-03-06 00:25:24 +00:00
Myles 0d0e1c16ea Fix issue with formatting :) (fixes quotes) 2016-03-05 23:24:23 +00:00
Myles f462ff9e8a Fix weird closedchannel bug 2016-03-05 22:16:43 +00:00
Myles 5582556d8a Fix issue with biomes on chunks, #125 2016-03-05 22:05:17 +00:00
Myles ef6214a442 Fix getHandItem across reloads, though half the things will still break on reload :( 2016-03-05 21:23:14 +00:00
Myles 369710333c Change updating so it doesn't tell you on current version up to date but warns if you're on a newer version than expected / older one in console. 2016-03-05 21:15:51 +00:00
Myles 30c4fea044 Add new /viaversion dontbugme, change method if the version looks like it's custom / debug (not compiled by maven) 2016-03-05 20:54:35 +00:00
Myles eccc5091b5 Merge pull request #139 from HugoDaBosss/master
Added proper update message (based on checkplys)
2016-03-05 20:40:48 +00:00
HugoDaBosss 65770d7c5b Added proper update message 2016-03-05 21:37:12 +01:00
Myles 715e873bae Bump version to 0.5.2 2016-03-05 20:21:21 +00:00
Myles eced599818 Merge pull request #138 from StamBoom/master
Fix commandblocks
2016-03-05 20:06:54 +00:00
Mats 6db7755633 Fix commandblocks 2016-03-05 20:36:06 +01:00
Myles 653c3d3984 Merge pull request #131 from StamBoom/patch
Fix book formatting and invalid book tag at empty book
2016-03-05 19:18:39 +00:00
HugoDaBosss 5ca841837d Added BungeeCord to the Issue Template 2016-03-05 20:04:16 +01:00
HugoDaBosss 554e037044 Merge pull request #133 from fillefilip8/patch-2
Fixed some maven warnings.
2016-03-05 19:48:26 +01:00
fillefilip8 457d7e4777 Fixed some maven warnings. 2016-03-05 14:37:01 +01:00
Mats b3dc465498 Remove debug message 2016-03-05 11:35:32 +01:00
Mats c56109a64c Fix book formatting and invalid book tag at empty book 2016-03-05 11:30:17 +01:00
Myles d5e720fe09 Merge pull request #130 from HugoDaBosss/patch-8
Fix spawners showing the correct mob
2016-03-05 00:28:24 +00:00
HugoDaBosss a42526bb88 Small formatting 2016-03-05 01:24:15 +01:00
HugoDaBosss bd5f44b477 Fixed spawners showing the correct mob 2016-03-05 01:21:37 +01:00
Myles d5d8881677 Add debug to show metadata ID on error 2016-03-04 23:30:37 +00:00
Myles ac2178a247 Add debug mode so we can analyse packets 2016-03-04 23:10:07 +00:00
Myles 24fa8aec35 Removed channel closed exception 2016-03-04 23:07:22 +00:00
Myles 2ba92a0d47 Merge pull request #126 from HugoDaBosss/herobrine
Removed Herobrine.
2016-03-04 23:03:45 +00:00
HugoDaBosss ace178834e Removed Herobrine. 2016-03-05 00:00:50 +01:00
HugoDaBosss 9c88d0a37f Merge pull request #10 from MylesIsCool/master
Update from master
2016-03-04 23:54:38 +01:00
Myles bafc1b6799 Merge pull request #122 from HugoDaBosss/patch-7
Fixed double flint and steel sound and added support to ignore sounds in 1.9
2016-03-04 22:29:39 +00:00
HugoDaBosss c9a575f45d Merge pull request #9 from MylesIsCool/master
Update Version I accidentally deployed debug version - 0.5.1
2016-03-04 23:23:44 +01:00
HugoDaBosss c071c895e7 Fixed double flint and steel sound and added support to ignore sounds in
1.9
2016-03-04 22:58:40 +01:00
Myles a8799bd493 Update Version I accidentally deployed debug version - 0.5.1 2016-03-04 21:51:56 +00:00
HugoDaBosss 20d4a94792 Merge pull request #8 from MylesIsCool/master
Update from master
2016-03-04 22:33:12 +01:00
Myles 89e0948f97 Updated version to 0.5.0 :) 2016-03-04 21:21:51 +00:00
Myles 6fe3c15f7d Remove 1.9 chunk unloading, should fix #38 2016-03-04 21:16:12 +00:00
Myles fb5dace6a6 Add armour, based on HugoDaBoss code but modified to work correctly with shift click. Also fix small issue from last commit. 2016-03-04 20:03:46 +00:00
Myles f71e51c85e Add packet sending to API 2016-03-04 19:24:44 +00:00
HugoDaBosss 0dd530a593 Merge pull request #7 from MylesIsCool/master
Update from master
2016-03-04 14:43:10 +01:00
Myles 12df86a142 As per wiki.vg only unload if bitmask = 0 and full chunk (not sure if this fixes chunk issue) 2016-03-04 10:09:06 +00:00
Myles 963f021226 Fix books, also makes ItemSlotRewriter.ItemStack fields public 2016-03-04 10:04:50 +00:00
Myles cb4a8b24d4 Merge pull request #113 from fillefilip8/patch-1
Some README.md fixes.
2016-03-04 09:10:05 +00:00
fillefilip8 76c908b132 Update README.md 2016-03-04 10:05:44 +01:00
Myles 89311af76a Small issue with README 2016-03-04 09:05:05 +00:00
fillefilip8 1ecf515006 Fixed README formatting. 2016-03-04 09:58:31 +01:00
Myles 5c18028577 Bump version to 0.4.9 2016-03-04 08:14:26 +00:00
Myles 678a7de664 Correct README 2016-03-04 01:02:35 +00:00
Myles 0aa190353e Add potions, including splash. 2016-03-04 01:01:04 +00:00
Myles a42b113618 Use new JSONParsers or they all implode. 2016-03-03 23:40:09 +00:00
Myles 2704611977 Cancel sounds properly, fixes block placing issue on bungee. Updated version to 0.4.8 2016-03-03 22:48:17 +00:00
Myles be6245e693 Bump version 0.4.7 2016-03-03 22:46:17 +00:00
Myles d7b7c4916a Read any remaining bytes, not sure if this fixes any errors but we ideally should to prevent issues. 2016-03-03 22:01:49 +00:00
Myles caae4e4cca Merge pull request #108 from gigosaurus/patch-2
Fix some MalformedJsonExceptions
2016-03-03 21:33:57 +00:00
gigosaurus ee58fbedbe Fix some MalformedJsonExceptions
This should fix the last possible cause of issue #70
2016-03-03 21:28:40 +00:00
Myles a84b45f5dd Add new contributor, make format of output match spigot 2016-03-03 21:15:20 +00:00
Myles c2edf45846 Change package for slot rewriter. 2016-03-03 21:06:36 +00:00
Myles 88ff4ee9ca Merge pull request #96 from Mystalion/spawnegg-and-potions
support for rewriting SpawnEggs
2016-03-03 21:03:50 +00:00
Paulomart fd704f6a29 Merge remote-tracking branch 'origin/spawnegg-and-potions'
Conflicts:
	src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java
	src/main/java/us/myles/ViaVersion/util/PacketUtil.java
2016-03-03 21:38:16 +01:00
Paulomart c97b443cf2 I dont even Java. 2016-03-03 21:32:01 +01:00
Paulomart 00df80e6fd Replace nms code with fancy library and own code. 2016-03-03 21:31:56 +01:00
Paulomart 64c2ba243f Basic support for rewriting SpawnEggs and Potions, still needs more work 2016-03-03 21:31:50 +01:00
Myles 0ad2e6478d Merge pull request #103 from StamBoom/master
Fix skin overlay
2016-03-03 19:56:55 +00:00
Myles ab9f786999 Don't send a signed byte for digging. 2016-03-03 19:56:00 +00:00
Mats e826b339f6 Fixed missing Player metadata 2016-03-03 20:49:29 +01:00
Mats f06851f57a Fix skin overlay 2016-03-03 20:37:46 +01:00
Myles 1a90f0eb28 Use new method for finding cause, might need updating with disconnect. Can't replicate disconnect spam on any version on my machine. Also move to JSON for all because older versions don't have GSON :( in main package 2016-03-03 19:24:37 +00:00
Myles fee986d215 Make the injectors work in any 1.8 version. Now looks through fields for suitable in case of different field names also construct slot using known arguments. 2016-03-03 18:12:10 +00:00
fillefilip8 9108e78491 Added more yml info and remove author name from the message in the command. 2016-03-03 18:30:13 +01:00
Myles 1b75526892 Implement changes to entity effect 2016-03-03 18:30:00 +01:00
fillefilip8 5930a83765 Added a command and a new API function "getVersion()" 2016-03-03 18:29:59 +01:00
fillefilip8 ef118a3a64 * One JavaDoc to the api XD
* Added faster way to change version number.
2016-03-03 17:33:47 +01:00
fillefilip8 bb42cda4a8 . 2016-03-03 17:33:28 +01:00
fillefilip8 121bc9de6c * Modifyed that fancy message when 1.9 clients try to enter a Minecart or a Boat :)
* Renamed the listener to something better.
2016-03-03 17:33:27 +01:00
fillefilip8 1e873c123c Added that fancy message when 1.9 clients try to enter a Minecart :) 2016-03-03 17:33:27 +01:00
Myles c704b3709a Implement changes to entity effect 2016-03-03 15:17:31 +00:00
HugoDaBosss 618e09b202 Merge pull request #6 from MylesIsCool/master
Update from master
2016-03-03 14:13:41 +01:00
Myles fd0bd53826 Bump version to 0.4.6 2016-03-03 13:07:57 +00:00
Myles e11c8320f0 Merge pull request #83 from StamBoom/master
Fix unmount
2016-03-03 12:56:54 +00:00
Myles 624595e9f6 Merge pull request #84 from HugoDaBosss/patch-4
Fix animals appearing as babies instead of parents
2016-03-03 12:56:37 +00:00
HugoDaBosss cc813545d8 Formatting 2016-03-03 12:22:54 +01:00
HugoDaBosss e1ba6e07c2 Fix animals appearing as babies instead of parent 2016-03-03 12:20:19 +01:00
Mats 1bf49b1f0b Fix unmount 2016-03-03 12:18:23 +01:00
HugoDaBosss 5e34fda7e4 Merge pull request #4 from MylesIsCool/master
Merge from master
2016-03-03 12:17:06 +01:00
Myles aa70ab8b78 Extra line 2016-03-03 10:37:43 +00:00
Myles 186ba22dc8 Update README with chat, and change issue template 2016-03-03 10:37:10 +00:00
Myles b10aa30d9b Change error correction to use super, should restore default functionality to errors. 2016-03-03 10:24:01 +00:00
Myles 615b9f847c Merge pull request #77 from HugoDaBosss/patch-2
Don't send malformed JSON anymore, preventing kicks.
2016-03-03 10:04:54 +00:00
Myles 8f132fed14 Merge pull request #64 from HugoDaBosss/master
Fixed double placing sound and small packet finding optimization. (I suck at github)
2016-03-03 10:04:33 +00:00
HugoDaBosss 854e24f8fc More formatting 2016-03-03 10:47:22 +01:00
HugoDaBosss ff0544f29a Eclipse is changing my bracket markup x.x 2016-03-03 10:46:38 +01:00
HugoDaBosss 72ae12bc77 Don't send malformed JSON anymore, preventing kicks. 2016-03-03 10:44:57 +01:00
HugoDaBosss 29d2334ef0 Fixed bracket markup ;) 2016-03-03 10:09:38 +01:00
HugoDaBosss afb96c4878 Fixed double break sound 2016-03-03 10:06:24 +01:00
HugoDaBosss e4346611c9 Small optimization 2016-03-03 01:40:24 +01:00
BuildTools f15e11272a Merge branch 'master' of https://github.com/HugoDaBosss/ViaVersion 2016-03-03 01:37:25 +01:00
HugoDaBosss 8764d24a16 Merge pull request #3 from MylesIsCool/master
Update from Fork
2016-03-03 01:37:25 +01:00
Myles 86d543d700 Add new contributor, update version to 0.4.5 :) 2016-03-03 00:13:53 +00:00
Myles 99fd01c359 Merge pull request #63 from gigosaurus/patch-1
Fix player entity meta data
2016-03-03 00:12:03 +00:00
gigosaurus 573dcc10b1 Fix player entity meta data
I'm not 100% confident that what I'm doing here is correct, but looking at http://wiki.vg/Pre-release_protocol#Spawn_Player I think I'm doing it right.

fixes #58
2016-03-03 00:06:13 +00:00
Myles 3e30d989a0 Print out stack traces instead of throwing them move. 2016-03-02 23:20:57 +00:00
Myles fc00dd2b38 Merge pull request #56 from gigosaurus/master
Fix PLAY_USE_BED's old ID
2016-03-02 23:08:57 +00:00
gigosaurus 2e9987373d Fix PLAY_USE_BED's old ID 2016-03-02 22:16:58 +00:00
Myles 27c2f4c076 Bump version 2016-03-02 22:01:16 +00:00
Myles e9b61a8e91 Merge pull request #50 from Mystalion/awesome-metadata
Rewrite Metadata system to read the data from the bytebuf instead of
2016-03-02 20:57:33 +00:00
Paulomart 222dee6fda Rewrite Metadata system to read the data from the bytebuf instead of
using the last sent packet.
2016-03-02 21:39:37 +01:00
Myles e8cc25baad Should fix any ClosedConnection output 2016-03-02 20:19:47 +00:00
Myles 785f0664da Fix wither & add more debug info to missing metaindex 2016-03-02 19:42:14 +00:00
Myles ea6c648e4f Fix spam, update to version 0.4.3 2016-03-02 19:12:38 +00:00
Myles 4cdfd72700 Ensure no bytes are left on the bytebufs and ensure it is cancelled properly. Update Version to 0.4.2 2016-03-02 18:41:47 +00:00
Myles ccd6987f11 Bump to 0.4.1, Fixes bungee issues :) (Some chunk stuff, me being an idiot) 2016-03-02 17:03:32 +00:00
Myles 6c96271925 Bump the version, we now support ProtocolLib (hopefully it works properly) 2016-03-02 15:26:32 +00:00
Myles 318db73f3c This is a huge commit, adds ProtocolLib support. (To the best extent I can):
Channels now work as proxies for the minecraft encoder and decoder, this allows better compatibility when transforming packets.
ConnectionInfo now holds an activate state to deactivate.
Now only 2 handlers
We now use info.getChannel().pipeline().writeAndFlush to ensure we catch it ourselves.
Fix EntityMetadata from last commit so it sends empty metadata instead of cancelling whole packet.
Warn if they reload and don't reinject.
2016-03-02 15:21:07 +00:00
Myles b5b0117fa9 Merge pull request #36 from Mystalion/drop-metadata
Drop MetadataPacket where metadata could not be rewritten
2016-03-02 14:45:50 +00:00
Paulomart 79e5555d42 Drop MetadataPacket where metadata could not be rewritten 2016-03-02 13:31:15 +01:00
HugoDaBosss b6c2a46a86 Merge pull request #2 from MylesIsCool/master
Update From Original #2
2016-03-02 11:44:24 +01:00
Myles 114a7b6bd6 Format some lines properly 2016-03-02 10:19:36 +00:00
Myles 8e6d76296d Update contributors 2016-03-02 10:16:27 +00:00
Myles 153a68bf06 Credits to @SanderGielisse, change how netty information is stored so it's not constant and is now attached to ConnectionInfo 2016-03-02 10:12:43 +00:00
Myles 6199e1d8ce Correct last commit to make it work. 2016-03-02 10:09:04 +00:00
Myles 0db43e612e Merge pull request #25 from HugoDaBosss/master
Fix USE_ITEM using correct item. Fix SPAWN_OBJECT velocity.
2016-03-02 10:07:09 +00:00
Myles 06296ead77 Merge pull request #32 from StamBoom/master
Fix TabList header/footer gives (By non-json Strings) MalformedJsonException
2016-03-02 10:05:26 +00:00
Mats dac9bd58e5 Fix TabList header/footer gives (By non-json Strings) MalformedJsonException 2016-03-02 10:27:17 +01:00
Myles 8e0833ca6b Fix nether & end #30 bump to 0.3.7 2016-03-02 00:23:33 +00:00
Myles 88086e00d0 Bump to 0.3.6 2016-03-02 00:09:12 +00:00
Myles 9368347b56 Fix chat which is not got proper JSON 2016-03-01 23:35:16 +00:00
Myles 6828425d72 Update version to 0.3.5 2016-03-01 23:16:49 +00:00
Myles f9da275358 Fix lightning, track entities sent to the client and use them for mapping MetaIndex instead of previous method. (Allows custom entities and client side packets properly. Echo Pet works!!! + fixes some latency with methods) 2016-03-01 23:16:10 +00:00
Myles 1445bd37c3 Remove unused method from MetaIndex 2016-03-01 23:15:08 +00:00
Myles 2de176e55c Fixed guardian info. 2016-03-01 23:09:55 +00:00
Myles b785fe0515 Add EntityUtil & move utils to util package. 2016-03-01 23:09:29 +00:00
Myles 984176d53b Merge pull request #27 from Mystalion/api
Reflector Main Class and add API framework.
2016-03-01 21:43:44 +00:00
Paulomart bd46c3f5a0 Reflector Main Class and add API framework. 2016-03-01 22:28:18 +01:00
Myles 0209c51d10 Merge pull request #26 from Mystalion/fix-paintings
Fix support for paintings, also add a read and write position method.
2016-03-01 20:56:13 +00:00
Paulomart 3425ed94e0 Fix support for paintings, also add a read and write position method. 2016-03-01 21:38:35 +01:00
Myles 8ceee31299 Fix JSON for title packet, #24. Also implement method for generic JSON fixing woo! 2016-03-01 19:20:54 +00:00
HugoDaBosss db9cd296ee Fix USE_ITEM using correct item. Fix SPAWN_OBJECT velocity. 2016-03-01 19:56:48 +01:00
Myles 6b3fb6424c Update version to 0.3.4, as it should fix JSON data bug. 2016-03-01 18:06:39 +00:00
Myles e43968c142 Merge pull request #18 from StamBoom/master
Fix MalformedJsonException when opening renamed containers
2016-03-01 17:08:47 +00:00
Myles 5c0ba593da Bump version to 0.3.3 2016-03-01 16:58:56 +01:00
Mats 1f51cf8416 Fix MalformedJsonException on opening renamed containers 2016-03-01 16:51:13 +01:00
HugoDaBosss 442d4de74b Merge pull request #1 from MylesIsCool/master
Update From Original
2016-03-01 15:47:15 +01:00
Myles 2a67301642 Bump version to 0.3.3 2016-03-01 14:40:53 +00:00
Myles 46ec24a686 Merge pull request #17 from StamBoom/master
Fixed riding on entities. (To some extent)
2016-03-01 14:35:59 +00:00
Mats 6f25090c01 Fixed riding on entities. 2016-03-01 15:28:17 +01:00
Myles dd36686f1c Merge pull request #14 from HugoDaBosss/master
Fixed: ItemFrame crash, remaining missing sounds and Horse Metadata
2016-03-01 14:24:51 +00:00
Myles 2b980a3cfc Merge pull request #13 from StamBoom/master
Fix MalformedJsonException on Kick / Disconnect
2016-03-01 14:23:50 +00:00
HugoDaBosss 43aaa728b5 Fix Horse Metadata Error 2016-03-01 15:09:21 +01:00
HugoDaBosss 45dfe7261b Added remaining missing sounds 2016-03-01 14:48:00 +01:00
Mats 7831dc0082 Fix MalformedJsonException on Kick / Disconnect 2016-03-01 14:25:26 +01:00
HugoDaBosss ba4e6e5d2f Fixed ItemFrame crash 2016-03-01 14:24:58 +01:00
Myles 68bfaf6d23 Tiny bit of bracket reformatting just for format consistency 2016-03-01 11:00:06 +00:00
54 changed files with 4320 additions and 1827 deletions

No files matched your search

+115 -2
View File
@@ -1,3 +1,116 @@
target/
.idea/
### Java files ###
*.class
# Package Files
#*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
# Ignore project files
*.iml
# Ignore IDEA directory
.idea/*
# Include the project's code style settings file
!.idea/codeStyleSettings.xml
# Include the project's dictionary
!.idea/dictionaries/
!.idea/dictionaries/*
# File-based project format:
*.ipr
*.iws
### Plugin-specific files: ###
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
nb-configuration.xml
.nb-gradle/
### Git ###
# Don't exclude the .gitignore itself
!.gitignore
+12
View File
@@ -0,0 +1,12 @@
sudo: false
language: java
jdk: oraclejdk7
cache:
directories:
- '$HOME/.m2/repository'
script:
- mvn dependency:purge-local-repository -DactTransitively=false -DreResolve=false
- mvn clean install -B -U
+12
View File
@@ -0,0 +1,12 @@
### What version of ViaVersion are you using? Type /ver viaversion
### What version of Spigot are you using? Type /ver
### What plugins are you using? Type /plugins
### Are you using any additional software like BungeeCord? If so, what software and version? (Please list your plugins as well)
### How does this error happen? login? Using an item?
### Is there an error in the console? Use pastebin.com. Is there a kick message?
+3
View File
@@ -0,0 +1,3 @@
License:
--------
You may modify this work, all rights are still owned by myself excluding any files in the spacebase package as they belong to the respected contributors. Please credit the original author (myself) when forking etc. (or if it helped you understand the new protocol or netty!)
+41 -18
View File
@@ -1,37 +1,59 @@
# ViaVersion 0.3.2
**Allows the connection of 1.8 clients to 1.9**
# ViaVersion 0.6.0
[![Build Status](https://travis-ci.org/MylesIsCool/ViaVersion.svg?branch=master)](https://travis-ci.org/MylesIsCool/ViaVersion)
**Allows the connection of 1.9 clients to 1.8**
This plugin modifies netty to allow connection of 1.9 clients to 1.8,
**Don't use late bind nor ProtocolLib**
**As of this point it doesn't have everything, I need to fix:**
Attempt to make boats nicer when they don't work
Remap spawn eggs
If you have a bug with entities, please report the full stack trace
Some items with JSON data cause crashing due to the change in how strict minecraft is.
###*Don't use late bind*
This took hours of work, so if you enjoy this consider looking into contacting me and supporting my projects.
**Contributor Chat:** https://gitter.im/MylesIsCool/ViaVersion
Credits:
Sources:
--------
**wiki.vg** (Protocol info, though I did have to find a lot myself)
**MCProtocolLib** (used for chunk reading & some of writing.)
**OpenNBT** (used for slot rewriting)
Contributors:
--------
**Myself** (harhar)
**Matsv** (Movement Fix / Correcting my stupidity)
**Matsv/StamBoom**
**HugoDaBosss** (Sounds fix)
**HugoDaBosss**
**SanderGielisse**
**Paulomart**
**gigosaurus**
**fillefilip8**
Releases / Dev Builds:
--------
You can find official releases here:
https://www.spigotmc.org/resources/viaversion.19254/history
----------
You can find unofficial dev builds here:
**fillefilip8's Build Server:** http://build.fillecraft.com:8080/job/ViaVersion
License:
--------
@@ -39,4 +61,5 @@ License:
You may modify this work, all rights are still owned by myself excluding any files in the spacebase package as they belong to the respected contributors. Please credit the original author (myself) when forking etc. (or if it helped you understand the new protocol or netty!)
Thanks!
Thanks!
+11
View File
@@ -0,0 +1,11 @@
machine:
java:
version: oraclejdk7
general:
artifacts:
- "target/*.jar"
test:
override:
- mvn clean install -B
post:
- cp ./target/*.jar $CIRCLE_ARTIFACTS
+149 -22
View File
@@ -1,54 +1,181 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>us.myles</groupId>
<artifactId>ViaVersion</artifactId>
<version>1.0-SNAPSHOT</version>
<artifactId>viaversion</artifactId>
<version>0.6.2-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ViaVersion</name>
<description>Allow 1.8 clients to join 1.9 bukkit servers!</description>
<inceptionYear>2016</inceptionYear>
<url>https://www.spigotmc.org/resources/viaversion.19254/</url>
<prerequisites>
<maven>3.3.3</maven>
</prerequisites>
<properties>
<!-- Project Properties -->
<projectEncoding>UTF-8</projectEncoding>
<project.build.sourceEncoding>${projectEncoding}</project.build.sourceEncoding>
<project.build.outputEncoding>${projectEncoding}</project.build.outputEncoding>
<jdkVersion>1.7</jdkVersion>
<!-- <testJreVersion>1.7</testJreVersion> -->
<!-- Change Bukkit Version HERE! -->
<bukkitVersion>1.8.8-R0.1-SNAPSHOT</bukkitVersion>
</properties>
<build>
<finalName>${project.name}-${project.version}</finalName>
<sourceDirectory>src/main/java</sourceDirectory>
<!-- <testSourceDirectory>src/test/java</testSourceDirectory> -->
<resources>
<resource>
<targetPath>.</targetPath>
<filtering>false</filtering>
<directory>.</directory>
<includes>
<include>LICENSE</include>
</includes>
</resource>
<resource>
<targetPath>.</targetPath>
<filtering>true</filtering>
<directory>src/main/resources/</directory>
<includes>
<include>*</include>
</includes>
</resource>
</resources>
<!--
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
</testResources>
-->
<plugins>
<!-- Maven Java Compiler -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<source>${jdkVersion}</source>
<target>${jdkVersion}</target>
<!--
<testSource>${testJreVersion}</testSource>
<testTarget>${testJreVersion}</testTarget>
-->
</configuration>
</plugin>
<!-- Unit Test Plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<argLine>-Dfile.encoding=${projectEncoding} ${argLine}</argLine>
</configuration>
</plugin>
-->
<!-- Libs Shading and Relocation -->
<plugin>
<!--Relocate all lib we use in order to fix class loading errors if we use different versions
than already loaded libs (i.e. by Mojang -> gson)-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>false</minimizeJar>
<relocations>
<relocation>
<pattern>org.spacehq.opennbt</pattern>
<shadedPattern>us.myles.viaversion.libs.opennbt</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<!-- SpigotMC Repo (Bukkit API) -->
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
</repository>
<!-- SpaceHQ Repo-->
<repository>
<id>spacehq-repo</id>
<url>https://repo.spacehq.org/content/repositories/releases/</url>
</repository>
</repositories>
<dependencies>
<!-- Bukkit API, http://www.spigotmc.org/ or http://bukkit.org/ -->
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.8.8-R0.1-SNAPSHOT</version>
<version>${bukkitVersion}</version>
<scope>provided</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<artifactId>junit</artifactId>
<groupId>junit</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>persistence-api</artifactId>
<groupId>javax.persistence</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- NBT Edit Library -->
<dependency>
<groupId>org.spacehq</groupId>
<artifactId>opennbt</artifactId>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<!-- Netty (Network Library) -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.20.Final</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
</project>
@@ -1,7 +1,7 @@
package org.spacehq.mc.protocol.data.game.chunk;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.PacketUtil;
import us.myles.ViaVersion.util.PacketUtil;
import java.io.IOException;
import java.util.ArrayList;
@@ -17,7 +17,7 @@ public class BlockStorage {
public BlockStorage() {
this.bitsPerEntry = 4;
this.states = new ArrayList<Integer>();
this.states = new ArrayList<>();
this.states.add(0);
this.storage = new FlexibleStorage(this.bitsPerEntry, 4096);
@@ -26,7 +26,7 @@ public class BlockStorage {
public BlockStorage(ByteBuf in) throws IOException {
this.bitsPerEntry = in.readUnsignedByte();
this.states = new ArrayList<Integer>();
this.states = new ArrayList<>();
int stateCount = PacketUtil.readVarInt(in);
for (int i = 0; i < stateCount; i++) {
this.states.add(PacketUtil.readVarInt(in));
@@ -35,6 +35,10 @@ public class BlockStorage {
this.storage = new FlexibleStorage(this.bitsPerEntry, PacketUtil.readLongs(PacketUtil.readVarInt(in), in));
}
private static int index(int x, int y, int z) {
return y << 8 | z << 4 | x;
}
public void write(ByteBuf out) throws IOException {
out.writeByte(this.bitsPerEntry);
@@ -78,7 +82,7 @@ public class BlockStorage {
List<Integer> oldStates = this.states;
if (this.bitsPerEntry > 8) {
oldStates = new ArrayList<Integer>(this.states);
oldStates = new ArrayList<>(this.states);
this.states.clear();
this.bitsPerEntry = 13;
}
@@ -107,10 +111,6 @@ public class BlockStorage {
return true;
}
private static int index(int x, int y, int z) {
return y << 8 | z << 4 | x;
}
@Override
public boolean equals(Object o) {
return this == o || (o instanceof BlockStorage && this.bitsPerEntry == ((BlockStorage) o).bitsPerEntry && this.states.equals(((BlockStorage) o).states) && this.storage.equals(((BlockStorage) o).storage));
@@ -1,5 +1,10 @@
package org.spacehq.mc.protocol.data.game.chunk;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Column {
private int x;
private int z;
@@ -23,9 +28,9 @@ public class Column {
this.skylight = false;
boolean noSkylight = false;
for(int index = 0; index < chunks.length; index++) {
if(chunks[index] != null) {
if(chunks[index].getSkyLight() == null) {
for (Chunk chunk : chunks) {
if (chunk != null) {
if (chunk.getSkyLight() == null) {
noSkylight = true;
} else {
this.skylight = true;
@@ -43,26 +48,11 @@ public class Column {
this.biomeData = biomeData;
}
public int getX() {
return this.x;
}
public int getZ() {
return this.z;
}
public Chunk[] getChunks() {
return this.chunks;
}
public boolean hasBiomeData() {
return this.biomeData != null;
}
public byte[] getBiomeData() {
return this.biomeData;
}
public boolean hasSkylight() {
return this.skylight;
}
@@ -18,19 +18,19 @@ public class NetUtil {
public static int writeNewColumn(ByteBuf out, Column column, boolean fullChunk, boolean hasSkylight) throws IOException {
int mask = 0;
Chunk chunks[] = column.getChunks();
for(int index = 0; index < chunks.length; index++) {
for (int index = 0; index < chunks.length; index++) {
Chunk chunk = chunks[index];
if(chunk != null && (!fullChunk || !chunk.isEmpty())) {
if (chunk != null && (!fullChunk || !chunk.isEmpty())) {
mask |= 1 << index;
chunk.getBlocks().write(out);
chunk.getBlockLight().write(out);
if(hasSkylight || column.hasSkylight()) {
if (hasSkylight || column.hasSkylight()) {
chunk.getSkyLight().write(out); // TODO: Make a PR to original lib to correct this
}
}
}
if(fullChunk) {
if (fullChunk && column.getBiomeData() != null) {
out.writeBytes(column.getBiomeData());
}
@@ -39,7 +39,7 @@ public class NetUtil {
public static Column readOldChunkData(int x, int z, boolean isFullChunk, int bitmask, byte[] input, boolean checkForSky, boolean hasSkyLight) {
int pos = 0;
int expected = 0;
int expected = isFullChunk ? 256 : 0;
boolean sky = false;
ShortBuffer buf = ByteBuffer.wrap(input).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
// 0 = Calculate expected length and determine if the packet has skylight.
@@ -47,45 +47,47 @@ public class NetUtil {
// 2 = Get block light.
// 3 = Get sky light.
Chunk[] chunks = new Chunk[16];
for(int pass = 0; pass < 4; pass++) {
for(int ind = 0; ind < 16; ind++) {
if((bitmask & 1 << ind) != 0) {
if(pass == 0) {
int chunkCount = 0;
for (int pass = 0; pass < 4; pass++) {
if(pass == 1){
if(chunkCount == 0) return null;
}
for (int ind = 0; ind < 16; ind++) {
if ((bitmask & 1 << ind) != 0) {
if (pass == 0) {
chunkCount++;
// Block length + Blocklight length
expected += (4096 * 2) + 2048;
}
if(pass == 1) {
if (pass == 1) {
chunks[ind] = new Chunk(sky || hasSkyLight);
buf.position(pos / 2);
short[] tempData = new short[4096];
buf.get(tempData, 0, tempData.length);
int buffPos = buf.position();
// convert short array to new one
int index = 0;
for(short ss:tempData){
for (int index = 0; index < 4096; index++) {
short ss = buf.get(buffPos + index);
// s is 16 bits, 12 bits id and 4 bits data
int data = ss & 0xF;
int id = (ss >> 4) << 4 | data;
int newCombined = id ; // test
int newCombined = id; // test
chunks[ind].getBlocks().set(index, newCombined);
index++;
}
pos += tempData.length * 2;
pos += 4096 * 2;
}
if(pass == 2) {
if (pass == 2) {
NibbleArray3d blocklight = chunks[ind].getBlockLight();
System.arraycopy(input, pos, blocklight.getData(), 0, blocklight.getData().length);
pos += blocklight.getData().length;
}
if(pass == 3) {
if(chunks[ind].getSkyLight() != null) {
if (pass == 3) {
if (sky) {
NibbleArray3d skylight = chunks[ind].getSkyLight();
System.arraycopy(input, pos, skylight.getData(), 0, skylight.getData().length);
pos += skylight.getData().length;
@@ -94,16 +96,17 @@ public class NetUtil {
}
}
if(pass == 0) {
if (pass == 0) {
// If we have more data than blocks and blocklight combined, there must be skylight data as well.
if(input.length > expected) {
if (input.length > expected) {
sky = checkForSky;
}
}
}
byte biomeData[] = null;
if(isFullChunk) {
if (isFullChunk && (pos + 256 <= input.length)) {
biomeData = new byte[256];
System.arraycopy(input, pos, biomeData, 0, biomeData.length);
}
@@ -1,4 +1,4 @@
package us.myles.ViaVersion;
public class CancelException extends Exception{
public class CancelException extends Exception {
}
@@ -1,59 +1,59 @@
package us.myles.ViaVersion;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.socket.SocketChannel;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.packets.State;
import java.util.UUID;
@Getter
@Setter
public class ConnectionInfo {
private int protocol = 0;
private State state = State.HANDSHAKE;
private int compression = 0;
private final SocketChannel channel;
private Object lastPacket;
private java.util.UUID UUID;
private State state = State.HANDSHAKE;
private String openWindow;
private int protocol = 0;
private int compression = 0;
private int entityID;
private boolean active = true;
private String username;
public int getProtocol() {
return protocol;
}
public void setProtocol(int protocol) {
this.protocol = protocol;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void setCompression(int compression) {
this.compression = compression;
}
public int getCompression() {
return compression;
}
public void setLastPacket(Object lastPacket) {
this.lastPacket = lastPacket;
}
public Object getLastPacket() {
return lastPacket;
}
public void setUUID(UUID UUID) {
this.UUID = UUID;
}
public java.util.UUID getUUID() {
return UUID;
public ConnectionInfo(SocketChannel socketChannel) {
this.channel = socketChannel;
}
public Player getPlayer() {
return UUID == null ? null : Bukkit.getPlayer(UUID);
}
public void setActive(boolean active) {
this.active = active;
}
public void sendRawPacket(final ByteBuf packet, boolean currentThread) {
final ChannelHandler handler = channel.pipeline().get("encoder");
if (currentThread) {
channel.pipeline().context(handler).writeAndFlush(packet);
} else {
channel.eventLoop().submit(new Runnable() {
@Override
public void run() {
channel.pipeline().context(handler).writeAndFlush(packet);
}
});
}
}
public void sendRawPacket(final ByteBuf packet) {
sendRawPacket(packet, false);
}
public void closeWindow() {
this.openWindow = null;
}
}
@@ -1,94 +0,0 @@
package us.myles.ViaVersion;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
public class Core extends JavaPlugin {
@Override
public void onEnable() {
System.out.println("ViaVersion enabled, injecting. (Allows 1.8 to be accessed via 1.9)");
try {
injectPacketHandler();
} catch (Exception e) {
if(Bukkit.getPluginManager().getPlugin("ProtocolLib") != null){
System.out.println("This plugin is not compatible with protocol lib.");
}
System.out.println("Unable to inject handlers, are you on 1.8? ");
e.printStackTrace();
}
}
public void injectPacketHandler() throws Exception {
Class<?> serverClazz = ReflectionUtil.nms("MinecraftServer");
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
Object connection = serverClazz.getDeclaredMethod("getServerConnection").invoke(server);
List<ChannelFuture> futures = ReflectionUtil.get(connection, "g", List.class);
if (futures.size() == 0) {
throw new Exception("Could not find server to inject (late bind?)");
}
for (ChannelFuture future : futures) {
ChannelPipeline pipeline = future.channel().pipeline();
ChannelHandler bootstrapAcceptor = pipeline.first();
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
ChannelInitializer newInit = new ViaVersionInitializer(oldInit);
ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit);
}
}
public static Entity getEntity(final UUID player, final int id) {
try {
return Bukkit.getScheduler().callSyncMethod(getPlugin(Core.class), new Callable<Entity>() {
@Override
public Entity call() throws Exception {
Player p = Bukkit.getPlayer(player);
if (p == null) return null;
for (Entity e : p.getWorld().getEntities()) {
if (e.getEntityId() == id) {
return e;
}
}
return null;
}
}).get(10, TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println("Error fetching entity ");
e.printStackTrace();
return null;
}
}
public static ItemStack getHandItem(final ConnectionInfo info) {
try {
return Bukkit.getScheduler().callSyncMethod(getPlugin(Core.class), new Callable<ItemStack>() {
@Override
public ItemStack call() throws Exception {
if (info.getPlayer() != null) {
return info.getPlayer().getItemInHand();
}
return null;
}
}).get(10, TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println("Error fetching hand item ");
e.printStackTrace();
return null;
}
}
}
@@ -0,0 +1,265 @@
package us.myles.ViaVersion;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.ViaVersionAPI;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossStyle;
import us.myles.ViaVersion.armor.ArmorListener;
import us.myles.ViaVersion.boss.ViaBossBar;
import us.myles.ViaVersion.commands.ViaVersionCommand;
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
import us.myles.ViaVersion.listeners.CommandBlockListener;
import us.myles.ViaVersion.update.UpdateListener;
import us.myles.ViaVersion.update.UpdateUtil;
import us.myles.ViaVersion.util.ListWrapper;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
private final Map<UUID, ConnectionInfo> portedPlayers = new ConcurrentHashMap<>();
private boolean debug = false;
public static ItemStack getHandItem(final ConnectionInfo info) {
try {
return Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Callable<ItemStack>() {
@Override
public ItemStack call() throws Exception {
if (info.getPlayer() != null) {
return info.getPlayer().getItemInHand();
}
return null;
}
}).get(10, TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println("Error fetching hand item: " + e.getClass().getName());
if (ViaVersion.getInstance().isDebug())
e.printStackTrace();
return null;
}
}
@Override
public void onEnable() {
ViaVersion.setInstance(this);
saveDefaultConfig();
if (System.getProperty("ViaVersion") != null) {
getLogger().severe("ViaVersion is already loaded, we don't support reloads. Please reboot if you wish to update.");
getLogger().severe("Some features may not work.");
return;
}
getLogger().info("ViaVersion " + getDescription().getVersion() + " is now enabled, injecting. (Allows 1.8 to be accessed via 1.9)");
injectPacketHandler();
if (getConfig().getBoolean("checkforupdates"))
UpdateUtil.sendUpdateMessage(this);
Bukkit.getPluginManager().registerEvents(new Listener() {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
removePortedClient(e.getPlayer().getUniqueId());
}
}, this);
Bukkit.getPluginManager().registerEvents(new ArmorListener(this), this);
Bukkit.getPluginManager().registerEvents(new CommandBlockListener(this), this);
Bukkit.getPluginManager().registerEvents(new UpdateListener(this), this);
getCommand("viaversion").setExecutor(new ViaVersionCommand(this));
}
public void injectPacketHandler() {
try {
Class<?> serverClazz = ReflectionUtil.nms("MinecraftServer");
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
Object connection = serverClazz.getDeclaredMethod("getServerConnection").invoke(server);
if (connection == null) {
System.out.println("connection is null!!");
//try others
for (Method m : serverClazz.getDeclaredMethods()) {
if (m.getReturnType() != null && !m.getName().equals("getServerConnection")) {
if (m.getReturnType().getSimpleName().equals("ServerConnection")) {
if (m.getParameterTypes().length == 0) {
connection = m.invoke(server);
}
}
}
}
if (connection == null) {
getLogger().warning("We failed to find the ServerConnection? :(");
return;
}
}
if (connection != null) {
for (Field field : connection.getClass().getDeclaredFields()) {
field.setAccessible(true);
final Object value = field.get(connection);
if (value instanceof List) {
// Inject the list
List wrapper = new ListWrapper((List) value) {
@Override
public synchronized void handleAdd(Object o) {
synchronized (this) {
if (o instanceof ChannelFuture) {
inject((ChannelFuture) o);
}
}
}
};
field.set(connection, wrapper);
// Iterate through current list
synchronized (wrapper) {
for (Object o : (List) value) {
if (o instanceof ChannelFuture) {
inject((ChannelFuture) o);
} else {
break; // not the right list.
}
}
}
}
}
}
System.setProperty("ViaVersion", getDescription().getVersion());
} catch (Exception e) {
getLogger().severe("Unable to inject handlers, are you on 1.8? ");
e.printStackTrace();
}
}
private void inject(ChannelFuture future) {
try {
ChannelHandler bootstrapAcceptor = future.channel().pipeline().first();
try {
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
ChannelInitializer newInit = new ViaVersionInitializer(oldInit);
ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit);
} catch (NoSuchFieldException e) {
// field not found
throw new Exception("Unable to find childHandler, blame " + bootstrapAcceptor.getClass().getName());
}
} catch (Exception e) {
getLogger().severe("Have you got late-bind enabled with something else? (ProtocolLib?)");
e.printStackTrace();
}
}
@Override
public boolean isPorted(Player player) {
return isPorted(player.getUniqueId());
}
@Override
public boolean isPorted(UUID playerUUID) {
return portedPlayers.containsKey(playerUUID);
}
@Override
public String getVersion() {
return getDescription().getVersion();
}
public void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException {
sendRawPacket(player.getUniqueId(), packet);
}
@Override
public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException {
if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not on 1.9");
ConnectionInfo ci = portedPlayers.get(uuid);
ci.sendRawPacket(packet);
}
@Override
public BossBar createBossBar(String title, BossColor color, BossStyle style) {
return new ViaBossBar(title, 1F, color, style);
}
@Override
public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) {
return new ViaBossBar(title, health, color, style);
}
@Override
public boolean isDebug() {
return this.debug;
}
public void setDebug(boolean value) {
this.debug = value;
}
@Override
public boolean isSyncedChunks() {
return getConfig().getBoolean("sync-chunks", true);
}
public boolean isPreventCollision() {
return getConfig().getBoolean("prevent-collision", true);
}
public boolean isSuppressMetadataErrors() {
return getConfig().getBoolean("suppress-metadata-errors", false);
}
public boolean isShieldBlocking() {
return getConfig().getBoolean("shield-blocking", true);
}
public boolean isAutoTeam() {
// Collision has to be enabled first
if (!isPreventCollision()) return false;
return getConfig().getBoolean("auto-team", true);
}
public void addPortedClient(ConnectionInfo info) {
portedPlayers.put(info.getUUID(), info);
}
public void removePortedClient(UUID clientID) {
portedPlayers.remove(clientID);
}
public void run(final Runnable runnable, boolean wait) {
try {
Future f = Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
runnable.run();
return true;
}
});
if (wait) {
f.get(10, TimeUnit.SECONDS);
}
} catch (Exception e) {
System.out.println("Failed to run task: " + e.getClass().getName());
if (ViaVersion.getInstance().isDebug())
e.printStackTrace();
}
}
}
@@ -0,0 +1,11 @@
package us.myles.ViaVersion.api;
import lombok.Getter;
import lombok.Setter;
public class ViaVersion {
@Getter
@Setter
private static ViaVersionAPI instance;
}
@@ -0,0 +1,87 @@
package us.myles.ViaVersion.api;
import io.netty.buffer.ByteBuf;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossStyle;
import java.util.UUID;
public interface ViaVersionAPI {
/**
* Is player using 1.9?
*
* @param player
* @return True if the client is on 1.9
*/
boolean isPorted(Player player);
/**
* Is player using 1.9?
*
* @param playerUUID
* @return True if the client is on 1.9
*/
boolean isPorted(UUID playerUUID);
/**
* Get the version of the plugin
*
* @return Plugin version
*/
String getVersion();
/**
* Send a raw packet to the player (Use new IDs)
*
* @param player The player to send packet
* @param packet The packet, you need a VarInt ID then the packet contents.
* @throws IllegalArgumentException If not on 1.9 throws IllegalArg
*/
void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException;
/**
* Send a raw packet to the player (Use new IDs)
*
* @param uuid The uuid from the player to send packet
* @param packet The packet, you need a VarInt ID then the packet contents.
* @throws IllegalArgumentException If not on 1.9 throws IllegalArg
*/
void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException;
/**
* Create a new bossbar instance
*
* @param title The title
* @param color The color
* @param style The style
* @return Bossbar instance
*/
BossBar createBossBar(String title, BossColor color, BossStyle style);
/**
* Create a new bossbar instance
*
* @param title The title
* @param health Number between 0 and 1
* @param color The color
* @param style The style
* @return Bossbar instance
*/
BossBar createBossBar(String title, float health, BossColor color, BossStyle style);
/**
* Obtain if global debug is enabled
*
* @return true if debug is enabled
*/
boolean isDebug();
/**
* Obtains if syncing chunks is on
*
* @return true if it is
*/
boolean isSyncedChunks();
}
@@ -0,0 +1,122 @@
package us.myles.ViaVersion.api.boss;
import org.bukkit.entity.Player;
import java.util.Set;
import java.util.UUID;
public interface BossBar {
/**
* Change the title
*
* @param title Title can be in either JSON or just text
*/
void setTitle(String title);
/**
* Get the current title
*
* @return the title
*/
String getTitle();
/**
* Change the health
*
* @param health this float has to be between 0F - 1F
*/
void setHealth(float health);
/**
* Get the health
*
* @return float between 0F - 1F
*/
float getHealth();
/**
* Yay colors!
*
* @param color Whatever color you want!
*/
void setColor(BossColor color);
/**
* Get the bossbar color
*
* @return
*/
BossColor getColor();
/**
* Change the bosbar style
*
* @param style BossStyle
*/
void setStyle(BossStyle style);
/**
* Get the bosbar style
*
* @return BossStyle
*/
BossStyle getStyle();
/**
* Show the bossbar to a player.
*
* @param player
*/
void addPlayer(Player player);
/**
* Remove the bossbar from a player
*
* @param player
*/
void removePlayer(Player player);
/**
* Add flags
*
* @param flag
*/
void addFlag(BossFlag flag);
/**
* Remove flags.
*
* @param flag
*/
void removeFlag(BossFlag flag);
/**
* @param flag
* @return
*/
boolean hasFlag(BossFlag flag);
/**
* Get players
*
* @return UUIDS from players (sorry I lied)
*/
Set<UUID> getPlayers();
/**
* Show the bossbar to everyone (In the getPlayer set)
*/
void show();
/**
* Hide the bossbar from everyone (In the getPlayer set)
*/
void hide();
/**
* Is it visible?
*
* @return visibility changable with show() and hide()
*/
boolean isVisible();
}
@@ -0,0 +1,18 @@
package us.myles.ViaVersion.api.boss;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public enum BossColor {
PINK(0),
BLUE(1),
RED(2),
GREEN(3),
YELLOW(4),
PURPLE(5),
WHITE(6);
private final int id;
}
@@ -0,0 +1,13 @@
package us.myles.ViaVersion.api.boss;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public enum BossFlag {
DARKEN_SKY(1),
PLAY_BOSS_MUSIC(2);
private final int id;
}
@@ -0,0 +1,16 @@
package us.myles.ViaVersion.api.boss;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public enum BossStyle {
SOLID(0),
SEGMENTED_6(1),
SEGMENTED_10(2),
SEGMENTED_12(3),
SEGMENTED_20(4);
private final int id;
}
@@ -0,0 +1,102 @@
package us.myles.ViaVersion.armor;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.RequiredArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.CraftingInventory;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.packets.PacketType;
import java.util.UUID;
import static us.myles.ViaVersion.util.PacketUtil.*;
@RequiredArgsConstructor
public class ArmorListener implements Listener {
private static final UUID ARMOR_ATTRIBUTE = UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150");
private final ViaVersionPlugin plugin;
public static void sendArmorUpdate(Player player) {
int armor = ArmorType.calculateArmorPoints(player.getInventory().getArmorContents());
ByteBuf buf = Unpooled.buffer();
writeVarInt(PacketType.PLAY_ENTITY_PROPERTIES.getNewPacketID(), buf);
writeVarInt(player.getEntityId(), buf);
buf.writeInt(1); // only 1 property
writeString("generic.armor", buf);
buf.writeDouble(0); //default 0 armor
writeVarInt(1, buf); // 1 modifier
writeUUID(ARMOR_ATTRIBUTE, buf); // armor modifier uuid
buf.writeDouble((double) armor); // the modifier value
buf.writeByte(0); // the modifier operation, 0 is add number
ViaVersion.getInstance().sendRawPacket(player, buf);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onInventoryClick(InventoryClickEvent e) {
HumanEntity human = e.getWhoClicked();
if (human instanceof Player && e.getInventory() instanceof CraftingInventory) {
final Player player = (Player) human;
if (ViaVersion.getInstance().isPorted(player)) {
if (e.getCurrentItem() != null) {
if (ArmorType.isArmor(e.getCurrentItem().getType())) {
sendDelayedArmorUpdate(player);
return;
}
}
if (e.getRawSlot() >= 5 && e.getRawSlot() <= 8) {
sendDelayedArmorUpdate(player);
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onInteract(PlayerInteractEvent e) {
if (e.getItem() != null) {
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (ArmorType.isArmor(e.getMaterial())) {
final Player player = e.getPlayer();
// Due to odd bugs it's 3 ticks later
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
if (ViaVersion.getInstance().isPorted(player)) {
sendArmorUpdate(player);
}
}
}, 3L);
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onJoin(PlayerJoinEvent e) {
sendDelayedArmorUpdate(e.getPlayer());
}
public void sendDelayedArmorUpdate(final Player player) {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
if (ViaVersion.getInstance().isPorted(player)) {
sendArmorUpdate(player);
}
}
});
}
}
@@ -0,0 +1,81 @@
package us.myles.ViaVersion.armor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@RequiredArgsConstructor
@Getter
public enum ArmorType {
LEATHER_HELMET(1, 298, Material.LEATHER_HELMET),
LEATHER_CHESTPLATE(3, 299, Material.LEATHER_CHESTPLATE),
LEATHER_LEGGINGS(2, 300, Material.LEATHER_LEGGINGS),
LEATHER_BOOTS(1, 301, Material.LEATHER_BOOTS),
CHAINMAIL_HELMET(2, 302, Material.CHAINMAIL_HELMET),
CHAINMAIL_CHESTPLATE(5, 303, Material.CHAINMAIL_CHESTPLATE),
CHAINMAIL_LEGGINGS(4, 304, Material.CHAINMAIL_LEGGINGS),
CHAINMAIL_BOOTS(1, 305, Material.CHAINMAIL_BOOTS),
IRON_HELMET(2, 306, Material.IRON_HELMET),
IRON_CHESTPLATE(6, 307, Material.IRON_CHESTPLATE),
IRON_LEGGINGS(5, 308, Material.IRON_LEGGINGS),
IRON_BOOTS(2, 309, Material.IRON_BOOTS),
DIAMOND_HELMET(3, 310, Material.DIAMOND_HELMET),
DIAMOND_CHESTPLATE(8, 311, Material.DIAMOND_CHESTPLATE),
DIAMOND_LEGGINGS(6, 312, Material.DIAMOND_LEGGINGS),
DIAMOND_BOOTS(3, 313, Material.DIAMOND_BOOTS),
GOLD_HELMET(2, 314, Material.GOLD_HELMET),
GOLD_CHESTPLATE(5, 315, Material.GOLD_CHESTPLATE),
GOLD_LEGGINGS(3, 316, Material.GOLD_LEGGINGS),
GOLD_BOOTS(1, 317, Material.GOLD_BOOTS),
NONE(0, 0, Material.AIR);
private final int armorPoints;
private final int id;
private final Material type;
public static ArmorType findByType(Material type) {
for(ArmorType a : ArmorType.values())
if(a.getType() == type)
return a;
return ArmorType.NONE;
}
public static int calculateArmorPoints(ItemStack[] armor) {
int total = 0;
for (ItemStack anArmor : armor) {
if (anArmor != null)
total += findByType(anArmor.getType()).getArmorPoints();
}
return total;
}
public static ArmorType findById(int id) {
for(ArmorType a : ArmorType.values())
if(a.getId() == id)
return a;
return ArmorType.NONE;
}
public static boolean isArmor(Material material){
for(ArmorType a : ArmorType.values())
if(a.getType() == material)
return true;
return false;
}
public static int calculateArmorPoints(int[] armor) {
int total = 0;
for (int anArmor : armor) {
if (anArmor != -1)
total += findById(anArmor).getArmorPoints();
}
return total;
}
public Material getType() {
return this.type;
}
}
@@ -0,0 +1,213 @@
package us.myles.ViaVersion.boss;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossFlag;
import us.myles.ViaVersion.api.boss.BossStyle;
import us.myles.ViaVersion.packets.PacketType;
import us.myles.ViaVersion.transformers.OutgoingTransformer;
import us.myles.ViaVersion.util.PacketUtil;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@Getter
public class ViaBossBar implements BossBar {
private UUID uuid;
private String title;
private float health;
private BossColor color;
private BossStyle style;
private Set<UUID> players;
private boolean visible;
private Set<BossFlag> flags;
public ViaBossBar(String title, float health, BossColor color, BossStyle style) {
Validate.notNull(title, "Title cannot be null");
Validate.isTrue((health >= 0 && health <= 1), "Health must be between 0 and 1");
this.uuid = UUID.randomUUID();
this.title = title;
this.health = health;
this.color = color == null ? BossColor.PURPLE : color;
this.style = style == null ? BossStyle.SOLID : style;
this.players = new HashSet<>();
this.flags = new HashSet<>();
visible = true;
}
@Override
public void setTitle(String title) {
Validate.notNull(title, "Title cannot be null");
this.title = title;
sendPacket(UpdateAction.UPDATE_TITLE);
}
@Override
public void setHealth(float health) {
Validate.isTrue((health >= 0 && health <= 1), "Health must be between 0 and 1");
this.health = health;
sendPacket(UpdateAction.UPDATE_HEALTH);
}
@Override
public BossColor getColor() {
return color;
}
@Override
public void setColor(BossColor color) {
Validate.notNull(color, "Color cannot be null");
this.color = color;
sendPacket(UpdateAction.UPDATE_STYLE);
}
@Override
public void setStyle(BossStyle style) {
Validate.notNull(style, "Style cannot be null");
this.style = style;
sendPacket(UpdateAction.UPDATE_STYLE);
}
@Override
public void addPlayer(Player player) {
if (player != null && !players.contains(player.getUniqueId())) {
players.add(player.getUniqueId());
if (visible)
sendPacket(player.getUniqueId(), getPacket(UpdateAction.ADD));
}
}
@Override
public void removePlayer(Player player) {
if (player != null && players.contains(player.getUniqueId())) {
players.remove(player.getUniqueId());
sendPacket(player.getUniqueId(), getPacket(UpdateAction.REMOVE));
}
}
@Override
public void addFlag(BossFlag flag) {
if (!hasFlag(flag))
flags.add(flag);
sendPacket(UpdateAction.UPDATE_FLAGS);
}
@Override
public void removeFlag(BossFlag flag) {
if (hasFlag(flag))
flags.remove(flag);
sendPacket(UpdateAction.UPDATE_FLAGS);
}
@Override
public boolean hasFlag(BossFlag flag) {
return flags.contains(flag);
}
@Override
public Set<UUID> getPlayers() {
return Collections.unmodifiableSet(players);
}
@Override
public void show() {
setVisible(true);
}
@Override
public void hide() {
setVisible(false);
}
@Override
public boolean isVisible() {
return visible;
}
private void setVisible(boolean value) {
if (visible != value) {
visible = value;
sendPacket(value ? UpdateAction.ADD : UpdateAction.REMOVE);
}
}
private void sendPacket(UpdateAction action) {
ByteBuf buf = getPacket(action);
for (UUID uuid : players)
sendPacket(uuid, buf);
}
private void sendPacket(UUID uuid, ByteBuf buf) {
if (!ViaVersion.getInstance().isPorted(uuid)) {
players.remove(uuid);
return;
}
ViaVersion.getInstance().sendRawPacket(uuid, buf);
}
private ByteBuf getPacket(UpdateAction action) {
ByteBuf buf = Unpooled.buffer();
PacketUtil.writeVarInt(PacketType.PLAY_BOSS_BAR.getNewPacketID(), buf);
PacketUtil.writeUUID(uuid, buf);
PacketUtil.writeVarInt(action.getId(), buf);
switch (action) {
case ADD:
PacketUtil.writeString(fixJson(title), buf);
buf.writeFloat(health);
PacketUtil.writeVarInt(color.getId(), buf);
PacketUtil.writeVarInt(style.getId(), buf);
buf.writeByte(flagToBytes());
break;
case REMOVE:
break;
case UPDATE_HEALTH:
buf.writeFloat(health);
break;
case UPDATE_TITLE:
PacketUtil.writeString(fixJson(title), buf);
break;
case UPDATE_STYLE:
PacketUtil.writeVarInt(color.getId(), buf);
PacketUtil.writeVarInt(style.getId(), buf);
break;
case UPDATE_FLAGS:
buf.writeByte(flagToBytes());
break;
}
return buf;
}
private int flagToBytes() {
int bitmask = 0;
for (BossFlag flag : flags)
bitmask |= flag.getId();
return bitmask;
}
private String fixJson(String text) {
return OutgoingTransformer.fixJson(text);
}
@RequiredArgsConstructor
@Getter
private enum UpdateAction {
ADD(0),
REMOVE(1),
UPDATE_HEALTH(2),
UPDATE_TITLE(3),
UPDATE_STYLE(4),
UPDATE_FLAGS(5);
private final int id;
}
}
@@ -1,52 +0,0 @@
package us.myles.ViaVersion.chunks;
public class ByteWriter {
private final byte[] bytes;
private int byteIndex;
private int bitIndex;
public ByteWriter(int size) {
this.bytes = new byte[size];
this.byteIndex = 0;
this.bitIndex = 0;
}
public byte[] getOutput() {
return this.bytes;
}
public void writeFullByte(int b){
writeByte(b, 8);
}
public void writeByte(int b, int length) {
byte current = getCurrentByte();
byte byteB = (byte)(int)((b) & 0xff);
System.out.println("Input: " + byteB);
System.out.println(Integer.toBinaryString(byteB));
int space = (8 - bitIndex);
int written = space > length ? length : space;
System.out.println("Written is " + written);
bytes[byteIndex] = (byte) (current | (extractRange(byteB, 0, written) >> (bitIndex - 1)));
System.out.println("output value: " + bytes[byteIndex]);
this.bitIndex += length;
if(this.bitIndex >= 8) {
this.byteIndex += 1;
this.bitIndex = bitIndex - 8;
// write remaining into this
System.out.println("Writing from " + written + " to " + (written + bitIndex));
System.out.println("Value: " + extractRange(byteB, written, written + bitIndex));
bytes[byteIndex] = (byte) (extractRange(byteB, written, written + bitIndex) << written);
}
}
private byte extractRange(int in, int begin, int end){
return (byte) ((in >> begin) & ((1 << (end - begin)) - 1));
}
public byte getCurrentByte() {
if(byteIndex == bytes.length) throw new RuntimeException("ByteWriter overflow!");
return bytes[byteIndex];
}
}
@@ -1,16 +0,0 @@
package us.myles.ViaVersion.chunks;
import java.util.BitSet;
public class MagicBitSet extends BitSet{
private final int initLength;
public MagicBitSet(int nbits) {
super(nbits);
this.initLength = nbits;
}
public int getTrueLength() {
return length() == 0 ? initLength : length();
}
}
@@ -1,19 +0,0 @@
package us.myles.ViaVersion.chunks;
public class PacketChunk {
private PacketChunkData[] chunkData;
private byte[] biomeData;
public PacketChunk(PacketChunkData[] chunkData, byte[] biomeData) {
this.chunkData = chunkData;
this.biomeData = biomeData;
}
public PacketChunkData[] getChunkData() {
return chunkData;
}
public byte[] getBiomeData() {
return biomeData;
}
}
@@ -1,25 +0,0 @@
package us.myles.ViaVersion.chunks;
public class PacketChunkData {
private short[] blocks = new short[4096];
private byte[] blockLight = new byte[2048];
private byte[] skyLight;
public PacketChunkData(boolean isSkyLightData) {
if(isSkyLightData){
skyLight = new byte[2048];
}
}
public short[] getBlocks() {
return this.blocks;
}
public byte[] getBlockLight() {
return this.blockLight;
}
public byte[] getSkyLight() {
return this.skyLight;
}
}
@@ -0,0 +1,77 @@
package us.myles.ViaVersion.commands;
import lombok.RequiredArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import java.util.ArrayList;
import java.util.List;
/**
* Created by fillefilip8 on 2016-03-03.
*/
@RequiredArgsConstructor
public class ViaVersionCommand implements CommandExecutor {
private final ViaVersionPlugin plugin;
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (sender.hasPermission("viaversion.admin")) {
if (args.length == 0) {
sendHelp(sender);
} else if (args.length == 1) {
if (args[0].equalsIgnoreCase("list")) {
List<String> portedPlayers = new ArrayList<>();
List<String> normalPlayers = new ArrayList<>();
for (Player p : Bukkit.getOnlinePlayers()) {
if (ViaVersion.getInstance().isPorted(p)) {
portedPlayers.add(p.getName());
} else {
normalPlayers.add(p.getName());
}
}
sender.sendMessage(color("&8[&61.9&8]: &b" + portedPlayers.toString()));
sender.sendMessage(color("&8[&61.8&8]: &b" + normalPlayers.toString()));
} else if (args[0].equalsIgnoreCase("debug")) {
plugin.setDebug(!plugin.isDebug());
sender.sendMessage(color("&6Debug mode is now " + (plugin.isDebug() ? "&aenabled" : "&cdisabled")));
} else if (args[0].equalsIgnoreCase("dontbugme")) {
boolean newValue = !plugin.getConfig().getBoolean("checkforupdates", true);
plugin.getConfig().set("checkforupdates", newValue);
plugin.saveConfig();
sender.sendMessage(color("&6We will " + (newValue ? "&anotify you about updates." : "&cnot tell you about updates.")));
} else if (args[0].equalsIgnoreCase("autoteam")) {
boolean newValue = !plugin.getConfig().getBoolean("auto-team", true);
plugin.getConfig().set("auto-team", newValue);
plugin.saveConfig();
sender.sendMessage(color("&6We will " + (newValue ? "&aautomatically team players" : "&cno longer auto team players")));
sender.sendMessage(color("&6All players will need to re-login for the change to take place."));
} else {
sendHelp(sender);
}
}
}
return false;
}
public void sendHelp(CommandSender sender){
sender.sendMessage(color("&aViaVersion &c" + ViaVersion.getInstance().getVersion()));
sender.sendMessage(color("&6Commands:"));
sender.sendMessage(color("&2/viaversion list &7- &6Shows lists of all 1.9 clients and 1.8 clients."));
sender.sendMessage(color("&2/viaversion debug &7- &6Toggle debug mode"));
sender.sendMessage(color("&2/viaversion autoteam &7- &6Toggle automatically teaming to prevent colliding."));
sender.sendMessage(color("&2/viaversion dontbugme &7- &6Toggle checking for updates."));
}
public String color(String string) {
return string.replace("&", "§");
}
}
@@ -0,0 +1,52 @@
package us.myles.ViaVersion.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.transformers.IncomingTransformer;
import us.myles.ViaVersion.util.PacketUtil;
import java.util.List;
public class ViaDecodeHandler extends ByteToMessageDecoder {
private final IncomingTransformer incomingTransformer;
private final ByteToMessageDecoder minecraftDecoder;
private final ConnectionInfo info;
public ViaDecodeHandler(ConnectionInfo info, ByteToMessageDecoder minecraftDecoder) {
this.info = info;
this.minecraftDecoder = minecraftDecoder;
this.incomingTransformer = new IncomingTransformer(info);
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> list) throws Exception {
// use transformers
if (bytebuf.readableBytes() > 0) {
if (info.isActive()) {
int id = PacketUtil.readVarInt(bytebuf);
// Transform
ByteBuf newPacket = ctx.alloc().buffer();
try {
incomingTransformer.transform(id, bytebuf, newPacket);
bytebuf.clear();
bytebuf = newPacket;
} catch (Exception e) {
bytebuf.clear();
throw e;
}
}
// call minecraft decoder
list.addAll(PacketUtil.callDecode(this.minecraftDecoder, ctx, bytebuf));
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (PacketUtil.containsCause(cause, CancelException.class)) return;
super.exceptionCaught(ctx, cause);
}
}
@@ -0,0 +1,90 @@
package us.myles.ViaVersion.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.transformers.OutgoingTransformer;
import us.myles.ViaVersion.util.PacketUtil;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ViaEncodeHandler extends MessageToByteEncoder {
private final ConnectionInfo info;
private final MessageToByteEncoder minecraftEncoder;
private final OutgoingTransformer outgoingTransformer;
public ViaEncodeHandler(ConnectionInfo info, MessageToByteEncoder minecraftEncoder) {
this.info = info;
this.minecraftEncoder = minecraftEncoder;
this.outgoingTransformer = new OutgoingTransformer(info);
}
@Override
protected void encode(final ChannelHandlerContext ctx, Object o, final ByteBuf bytebuf) throws Exception {
// handle the packet type
if (!(o instanceof ByteBuf)) {
info.setLastPacket(o);
/* This transformer is more for fixing issues which we find hard at packet level :) */
if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk") && info.isActive()) {
final int[] locX = ReflectionUtil.get(o, "a", int[].class);
final int[] locZ = ReflectionUtil.get(o, "b", int[].class);
final Object world = ReflectionUtil.get(o, "world", ReflectionUtil.nms("World"));
Class<?> mapChunk = ReflectionUtil.nms("PacketPlayOutMapChunk");
final Constructor constructor = mapChunk.getDeclaredConstructor(ReflectionUtil.nms("Chunk"), boolean.class, int.class);
Runnable chunks = new Runnable() {
@Override
public void run() {
for (int i = 0; i < locX.length; i++) {
int x = locX[i];
int z = locZ[i];
// world invoke function
try {
Object chunk = ReflectionUtil.nms("World").getDeclaredMethod("getChunkAt", int.class, int.class).invoke(world, x, z);
Object packet = constructor.newInstance(chunk, true, 65535);
ctx.pipeline().writeAndFlush(packet);
} catch (InstantiationException | InvocationTargetException | ClassNotFoundException | IllegalAccessException | NoSuchMethodException e) {
e.printStackTrace();
}
}
}
};
chunks.run();
bytebuf.clear();
throw new CancelException();
}
// call minecraft encoder
PacketUtil.callEncode(this.minecraftEncoder, ctx, o, bytebuf);
}
if (bytebuf.readableBytes() == 0) {
throw new CancelException();
}
if (info.isActive()) {
int id = PacketUtil.readVarInt(bytebuf);
// Transform
ByteBuf oldPacket = bytebuf.copy();
bytebuf.clear();
try {
outgoingTransformer.transform(id, oldPacket, bytebuf);
} catch (Exception e) {
bytebuf.clear();
throw e;
} finally {
oldPacket.release();
}
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (PacketUtil.containsCause(cause, CancelException.class)) return;
super.exceptionCaught(ctx, cause);
}
}
@@ -1,53 +0,0 @@
package us.myles.ViaVersion.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.PacketUtil;
import us.myles.ViaVersion.transformers.IncomingTransformer;
@ChannelHandler.Sharable
public class ViaInboundHandler extends ChannelInboundHandlerAdapter {
private final IncomingTransformer incomingTransformer;
private final ViaVersionInitializer init;
public ViaInboundHandler(Channel c, ConnectionInfo info, ViaVersionInitializer init) {
this.init = init;
this.incomingTransformer = new IncomingTransformer(c, info, init);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
boolean compression = ctx.pipeline().get("compress") != null;
if (msg instanceof ByteBuf) {
ByteBuf bytebuf = (ByteBuf) msg;
if (compression) {
// decompress :)
bytebuf = PacketUtil.decompress(ctx, bytebuf);
}
int id = PacketUtil.readVarInt(bytebuf);
// Transform
ByteBuf newPacket = ctx.alloc().buffer();
try {
incomingTransformer.transform(id, bytebuf, newPacket);
} catch (CancelException e) {
return;
} finally {
bytebuf.release();
}
if (compression) {
// recompress :)
newPacket = PacketUtil.compress(ctx, newPacket);
}
msg = newPacket;
}
super.channelRead(ctx, msg);
}
}
@@ -1,53 +0,0 @@
package us.myles.ViaVersion.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.PacketUtil;
import us.myles.ViaVersion.transformers.OutgoingTransformer;
@ChannelHandler.Sharable
public class ViaOutboundHandler extends ChannelOutboundHandlerAdapter {
private final OutgoingTransformer outgoingTransformer;
private final ViaVersionInitializer init;
public ViaOutboundHandler(Channel c, ConnectionInfo info, ViaVersionInitializer init) {
this.init = init;
this.outgoingTransformer = new OutgoingTransformer(c, info, init);
}
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise channelPromise) throws Exception {
try {
if (channelPromise.isDone()) return; // don't break any <3s
boolean compression = ctx.pipeline().get("compress") != null;
if (msg instanceof ByteBuf) {
ByteBuf bytebuf = (ByteBuf) msg;
if (compression) {
// decompress :)
bytebuf = PacketUtil.decompress(ctx, bytebuf);
}
int id = PacketUtil.readVarInt(bytebuf);
// Transform
ByteBuf newPacket = ctx.alloc().buffer();
try {
outgoingTransformer.transform(id, bytebuf, newPacket);
} catch (CancelException e) {
return;
} finally {
bytebuf.release();
}
if (compression) {
// recompress :)
newPacket = PacketUtil.compress(ctx, newPacket);
}
msg = newPacket;
}
super.write(ctx, msg, channelPromise);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,43 +0,0 @@
package us.myles.ViaVersion.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.ReflectionUtil;
import java.lang.reflect.Constructor;
@ChannelHandler.Sharable
public class ViaOutboundPacketHandler extends ChannelOutboundHandlerAdapter {
private final ConnectionInfo info;
public ViaOutboundPacketHandler(Channel c, ConnectionInfo info) {
this.info = info;
}
@Override
public void write(ChannelHandlerContext channelHandlerContext, Object o, ChannelPromise channelPromise) throws Exception {
if (!(o instanceof ByteBuf)) {
info.setLastPacket(o);
/* This transformer is more for fixing issues which we find hard at byte level :) */
if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk")) {
int[] locX = ReflectionUtil.get(o, "a", int[].class);
int[] locZ = ReflectionUtil.get(o, "b", int[].class);
Object world = ReflectionUtil.get(o, "world", ReflectionUtil.nms("World"));
Class<?> mapChunk = ReflectionUtil.nms("PacketPlayOutMapChunk");
Constructor constructor = mapChunk.getDeclaredConstructor(ReflectionUtil.nms("Chunk"), boolean.class, int.class);
for (int i = 0; i < locX.length; i++) {
int x = locX[i];
int z = locZ[i];
// world invoke function
Object chunk = ReflectionUtil.nms("World").getDeclaredMethod("getChunkAt", int.class, int.class).invoke(world, x, z);
Object packet = constructor.newInstance(chunk, true, 65535);
channelHandlerContext.write(packet);
}
return;
}
}
super.write(channelHandlerContext, o, channelPromise);
}
}
@@ -3,18 +3,16 @@ package us.myles.ViaVersion.handlers;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import us.myles.ViaVersion.ConnectionInfo;
import java.lang.reflect.Method;
public class ViaVersionInitializer extends ChannelInitializer<SocketChannel> {
private final ChannelInitializer<SocketChannel> oldInit;
private Method method;
private ConnectionInfo info;
private ViaInboundHandler inbound;
private ViaOutboundHandler outbound;
private SocketChannel socketChannel;
private ViaOutboundPacketHandler outbound2;
public ViaVersionInitializer(ChannelInitializer<SocketChannel> oldInit) {
this.oldInit = oldInit;
@@ -28,24 +26,14 @@ public class ViaVersionInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
info = new ConnectionInfo();
ConnectionInfo info = new ConnectionInfo(socketChannel);
// Add originals
this.method.invoke(this.oldInit, socketChannel);
// Add our transformers
this.socketChannel = socketChannel;
this.inbound = new ViaInboundHandler(socketChannel, info, this);
this.outbound = new ViaOutboundHandler(socketChannel, info, this);
this.outbound2 = new ViaOutboundPacketHandler(socketChannel, info);
socketChannel.pipeline().addBefore("decoder", "via_incoming", this.inbound);
socketChannel.pipeline().addBefore("packet_handler", "via_outgoing2", this.outbound2);
socketChannel.pipeline().addBefore("encoder", "via_outgoing", this.outbound);
ViaEncodeHandler encoder = new ViaEncodeHandler(info, (MessageToByteEncoder) socketChannel.pipeline().get("encoder"));
ViaDecodeHandler decoder = new ViaDecodeHandler(info, (ByteToMessageDecoder) socketChannel.pipeline().get("decoder"));
socketChannel.pipeline().replace("encoder", "encoder", encoder);
socketChannel.pipeline().replace("decoder", "decoder", decoder);
}
public void remove(){
socketChannel.pipeline().remove("via_incoming");
socketChannel.pipeline().remove("via_outgoing");
socketChannel.pipeline().remove("via_outgoing2");
}
}
@@ -0,0 +1,62 @@
package us.myles.ViaVersion.listeners;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.RequiredArgsConstructor;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.packets.PacketType;
import us.myles.ViaVersion.util.PacketUtil;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@RequiredArgsConstructor
public class CommandBlockListener implements Listener {
private final ViaVersionPlugin plugin;
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onJoin(final PlayerJoinEvent e) {
if (e.getPlayer().isOp() && plugin.isPorted(e.getPlayer())) {
ByteBuf buf = Unpooled.buffer();
PacketUtil.writeVarInt(PacketType.PLAY_ENTITY_STATUS.getNewPacketID(), buf);
buf.writeInt(e.getPlayer().getEntityId());
buf.writeByte(26);
plugin.sendRawPacket(e.getPlayer(), buf);
}
}
@EventHandler(ignoreCancelled = true)
public void onInteract(PlayerInteractEvent e) {
if (e.getAction() == Action.RIGHT_CLICK_BLOCK && plugin.isPorted(e.getPlayer()) && e.getPlayer().isOp()) {
try {
sendCommandBlockPacket(e.getClickedBlock(), e.getPlayer());
} catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e1) {
e1.printStackTrace();
}
}
}
private void sendCommandBlockPacket(Block b, Player player) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException {
if (!(b.getState() instanceof CommandBlock))
return;
CommandBlock cmd = (CommandBlock) b.getState();
Object tileEntityCommand = ReflectionUtil.get(cmd, "commandBlock", ReflectionUtil.nms("TileEntityCommand"));
Object updatePacket = ReflectionUtil.invoke(tileEntityCommand, "getUpdatePacket");
Object nmsPlayer = ReflectionUtil.invoke(player, "getHandle");
Object playerConnection = ReflectionUtil.get(nmsPlayer, "playerConnection", ReflectionUtil.nms("PlayerConnection"));
Method sendPacket = playerConnection.getClass().getMethod("sendPacket", ReflectionUtil.nms("Packet"));
sendPacket.invoke(playerConnection, updatePacket); //Let the transformer do the work
}
}
@@ -1,201 +1,183 @@
package us.myles.ViaVersion.metadata;
import org.bukkit.entity.*;
public enum MetaIndex {
// entity
ENTITY_STATUS(org.bukkit.entity.Entity.class, 0, Type.Byte, NewType.Byte),
ENTITY_AIR(org.bukkit.entity.Entity.class, 1, Type.Short, NewType.VarInt),
ENTITY_SILENT(org.bukkit.entity.Entity.class, 4, Type.Byte, NewType.Boolean),
// living entity
LIVINGENTITY_NAMETAG(LivingEntity.class, 2, Type.String, NewType.String),
LIVINGENTITY_ALWAYS_SHOW_NAMETAG(LivingEntity.class, 3, Type.Byte, NewType.Boolean),
LIVINGENTITY_HEALTH(LivingEntity.class, 6, Type.Float, NewType.Float),
LIVINGENTITY_POTION_EFFECT_COLOR(LivingEntity.class, 7, Type.Int, NewType.VarInt),
LIVINGENTITY_IS_POTION_AMBIENT(LivingEntity.class, 8, Type.Byte, NewType.Boolean),
LIVINGENTITY_NUMBER_OF_ARROWS_IN(LivingEntity.class, 9, Type.Byte, NewType.VarInt),
LIVINGENTITY_NO_AI(LivingEntity.class, 15, Type.Byte, 10, NewType.Byte), // in 1.9 this is combined with Left handed, oh.
// ageable
AGEABLE_AGE(Ageable.class, 12, Type.Byte, 11, NewType.Boolean),
// armour stand
STAND_INFO(ArmorStand.class, 10, Type.Byte, NewType.Byte),
STAND_HEAD_POS(ArmorStand.class, 11, Type.Rotation, NewType.Vector3F),
STAND_BODY_POS(ArmorStand.class, 12, Type.Rotation, NewType.Vector3F),
STAND_LA_POS(ArmorStand.class, 13, Type.Rotation, NewType.Vector3F),
STAND_RA_POS(ArmorStand.class, 14, Type.Rotation, NewType.Vector3F),
STAND_LL_POS(ArmorStand.class, 15, Type.Rotation, NewType.Vector3F),
STAND_RL_POS(ArmorStand.class, 16, Type.Rotation, NewType.Vector3F),
// human, discountined?
PLAYER_SKIN_FLAGS(HumanEntity.class, 10, Type.Byte, NewType.Discontinued), // unsigned on 1.8
PLAYER_HUMAN_BYTE(HumanEntity.class, 16, Type.Byte, NewType.Discontinued), // unused on 1.8
PLAYER_ADDITIONAL_HEARTS(HumanEntity.class, 17, Type.Float, NewType.Discontinued),
PLAYER_SCORE(HumanEntity.class, 18, Type.Int, NewType.Discontinued),
// horse
HORSE_INFO(Horse.class, 16, Type.Int, 12, NewType.Byte),
HORSE_TYPE(Horse.class, 19, Type.Byte, 13, NewType.VarInt),
HORSE_SUBTYPE(Horse.class, 20, Type.Int, 14, NewType.VarInt),
HORSE_OWNER(Horse.class, 21, Type.String, 15, NewType.OptUUID),
HORSE_ARMOR(Horse.class, 22, Type.Int, 16, NewType.VarInt),
// bat
BAT_ISHANGING(Bat.class, 16, Type.Byte, 11, NewType.Byte),
// tameable
TAMING_INFO(Tameable.class, 16, Type.Byte, 12, NewType.Byte),
TAMING_OWNER(Tameable.class, 17, Type.String, 13, NewType.OptUUID),
// ocelot
OCELOT_TYPE(Ocelot.class, 18, Type.Byte, 14, NewType.VarInt),
// wolf
WOLF_HEALTH(Wolf.class, 18, Type.Float, 14, NewType.Float),
WOLF_BEGGING(Wolf.class, 19, Type.Byte, 15, NewType.Boolean),
WOLF_COLLAR(Wolf.class, 20, Type.Byte, 16, NewType.VarInt),
// pig
PIG_SADDLE(Pig.class, 16, Type.Byte, 12, NewType.Boolean),
// rabbit
RABBIT_TYPE(Rabbit.class, 18, Type.Byte, 12, NewType.VarInt),
// sheep
SHEEP_COLOR(Sheep.class, 16, Type.Byte, 12, NewType.Byte),
// villager
VILLAGER_PROFESSION(Villager.class, 16, Type.Int, 12, NewType.VarInt), // TODO write this to wiki.vg
// enderman
ENDERMAN_BLOCK(Enderman.class, 16, Type.Short, 11, NewType.BlockID), // special case
ENDERMAN_BLOCKDATA(Enderman.class, 17, Type.Byte, 11, NewType.BlockID), // special case
ENDERMAN_ISSCREAMING(Enderman.class, 18, Type.Byte, 12, NewType.Boolean),
// zombie
ZOMBIE_ISCHILD(Zombie.class, 12, Type.Byte, 11, NewType.Boolean),
ZOMBIE_ISVILLAGER(Zombie.class, 13, Type.Byte, 12, NewType.VarInt),
ZOMBIE_ISCONVERTING(Zombie.class, 14, Type.Byte, 13, NewType.Boolean),
// ZOMBIE_RISINGHANDS added in 1.9
// blaze
BLAZE_ONFIRE(Blaze.class, 16, Type.Byte, 11, NewType.Byte),
// spider
SPIDER_CIMBING(Spider.class, 16, Type.Byte, 11, NewType.Byte),
// creeper
CREEPER_FUSE(Creeper.class, 16, Type.Byte, 11, NewType.VarInt), // -1 idle, 1 is fuse
CREEPER_ISPOWERED(Creeper.class, 17, Type.Byte, 12, NewType.Boolean),
CREEPER_ISIGNITED(Creeper.class, 18, Type.Byte, 13, NewType.Boolean), // TODO: Write on wiki.vg for current prot
// ghast
GHAST_ISATTACKING(Ghast.class, 16, Type.Byte, 11, NewType.Boolean),
// slime
SLIME_SIZE(Slime.class, 16, Type.Byte, 11, NewType.VarInt),
// skeleton
SKELETON_TYPE(Skeleton.class, 13, Type.Byte, 11, NewType.VarInt),
// witch
WITCH_AGGRO(Witch.class, 21, Type.Byte, 11, NewType.Boolean),
// iron golem
IRON_PLAYERMADE(IronGolem.class, 16, Type.Byte, 11, NewType.Byte),
// wither
WITHER_TARGET1(Wither.class, 17, Type.Int, 11, NewType.VarInt),
WITHER_TARGET2(Wither.class, 18, Type.Int, 12, NewType.VarInt),
WITHER_TARGET3(Wither.class, 19, Type.Int, 13, NewType.VarInt),
WITHER_INVULN_TIME(Wither.class, 20, Type.Int, 14, NewType.VarInt),
// guardian
GUARDIAN_INFO(Guardian.class, 16, Type.Byte, 11, NewType.Byte),
GUARDIAN_TARGET(Guardian.class, 17, Type.Int, 12, NewType.VarInt),
// boat
BOAT_SINCEHIT(Boat.class, 17, Type.Int, 5, NewType.VarInt),
BOAT_FORWARDDIR(Boat.class, 18, Type.Int, 6, NewType.VarInt),
BOAT_DMGTAKEN(Boat.class, 19, Type.Float, 7, NewType.Float),
// BOAT_TYPE in 1.9
// minecart
MINECART_SHAKINGPOWER(Minecart.class, 17, Type.Int, 5, NewType.VarInt),
MINECART_SHAKINGDIRECTION(Minecart.class, 18, Type.Int, 6, NewType.VarInt),
MINECART_DAMAGETAKEN(Minecart.class, 19, Type.Float, 7, NewType.Float), // also shaking modifier :P
MINECART_BLOCK(Minecart.class, 20, Type.Int, 8, NewType.VarInt),
MINECART_BLOCK_Y(Minecart.class, 21, Type.Int, 9, NewType.VarInt),
MINECART_SHOWBLOCK(Minecart.class, 22, Type.Byte, 10, NewType.Boolean),
// furnace cart
FURNACECART_ISPOWERED(org.bukkit.entity.minecart.PoweredMinecart.class, 16, Type.Byte, 11, NewType.Boolean),
// item drop
ITEM_ITEM(Item.class, 10, Type.Slot, 5, NewType.Slot),
// arrow
ARROW_ISCRIT(Arrow.class, 16, Type.Byte, 5, NewType.Byte),
// firework
FIREWORK_INFO(Firework.class, 8, Type.Slot, 5, NewType.Slot),
// item frame
ITEMFRAME_ITEM(ItemFrame.class, 8, Type.Slot, 5, NewType.Slot),
ITEMFRAME_ROTATION(ItemFrame.class, 9, Type.Byte, 5, NewType.VarInt),
// ender crystal
ENDERCRYSTAL_HEALTH(EnderCrystal.class, 8, Type.Int, NewType.Discontinued),;
private Class<?> clazz;
private int newIndex;
private NewType newType;
private Type oldType;
private int index;
MetaIndex(Class<?> type, int index, Type oldType, NewType newType) {
this.clazz = type;
this.index = index;
this.newIndex = index;
this.oldType = oldType;
this.newType = newType;
}
MetaIndex(Class<?> type, int index, Type oldType, int newIndex, NewType newType) {
this.clazz = type;
this.index = index;
this.oldType = oldType;
this.newIndex = newIndex;
this.newType = newType;
}
public int getNewIndex() {
return newIndex;
}
public NewType getNewType() {
return newType;
}
public Type getOldType() {
return oldType;
}
public int getIndex() {
return index;
}
public Class<?> getApplicableClass() {
return this.clazz;
}
public static MetaIndex getIndex(Entity entity, int index) {
EntityType type;
if (entity instanceof Player) {
type = EntityType.PLAYER;
} else {
type = entity.getType();
}
return getIndex(type, index);
}
public static MetaIndex getIndex(EntityType type, int index) {
Class<? extends org.bukkit.entity.Entity> entityClass = type.getEntityClass();
if(entityClass == null){
System.out.println("Could not get entity class for " + type);
return null;
}
for (MetaIndex mi : MetaIndex.values()) {
if (mi.getIndex() == index) {
// To fix issue with armour stands colliding with new values
if(mi.getApplicableClass().equals(LivingEntity.class)) continue;
if ((mi.getApplicableClass().isAssignableFrom(entityClass) ||
mi.getApplicableClass().equals(entityClass))) {
return mi;
}
}
}
// fall back to living entity
for (MetaIndex mi : MetaIndex.values()) {
if (mi.getIndex() == index) {
if (mi.getApplicableClass().isAssignableFrom(LivingEntity.class) ||
mi.getApplicableClass().equals(LivingEntity.class)) {
return mi;
}
}
}
return null;
}
}
package us.myles.ViaVersion.metadata;
import lombok.Getter;
import org.bukkit.entity.*;
@Getter
public enum MetaIndex {
// entity
ENTITY_STATUS(org.bukkit.entity.Entity.class, 0, Type.Byte, NewType.Byte),
ENTITY_AIR(org.bukkit.entity.Entity.class, 1, Type.Short, NewType.VarInt),
ENTITY_SILENT(org.bukkit.entity.Entity.class, 4, Type.Byte, NewType.Boolean),
// living entity
LIVINGENTITY_NAMETAG(LivingEntity.class, 2, Type.String, NewType.String),
LIVINGENTITY_ALWAYS_SHOW_NAMETAG(LivingEntity.class, 3, Type.Byte, NewType.Boolean),
LIVINGENTITY_HEALTH(LivingEntity.class, 6, Type.Float, NewType.Float),
LIVINGENTITY_POTION_EFFECT_COLOR(LivingEntity.class, 7, Type.Int, NewType.VarInt),
LIVINGENTITY_IS_POTION_AMBIENT(LivingEntity.class, 8, Type.Byte, NewType.Boolean),
LIVINGENTITY_NUMBER_OF_ARROWS_IN(LivingEntity.class, 9, Type.Byte, NewType.VarInt),
LIVINGENTITY_NO_AI(LivingEntity.class, 15, Type.Byte, 10, NewType.Byte), // in 1.9 this is combined with Left handed, oh.
// ageable
AGEABLE_AGE(Ageable.class, 12, Type.Byte, 11, NewType.Boolean),
// armour stand
STAND_INFO(ArmorStand.class, 10, Type.Byte, NewType.Byte),
STAND_HEAD_POS(ArmorStand.class, 11, Type.Rotation, NewType.Vector3F),
STAND_BODY_POS(ArmorStand.class, 12, Type.Rotation, NewType.Vector3F),
STAND_LA_POS(ArmorStand.class, 13, Type.Rotation, NewType.Vector3F),
STAND_RA_POS(ArmorStand.class, 14, Type.Rotation, NewType.Vector3F),
STAND_LL_POS(ArmorStand.class, 15, Type.Rotation, NewType.Vector3F),
STAND_RL_POS(ArmorStand.class, 16, Type.Rotation, NewType.Vector3F),
// human, discountined?
PLAYER_SKIN_FLAGS(HumanEntity.class, 10, Type.Byte, 12, NewType.Byte), // unsigned on 1.8
PLAYER_HUMAN_BYTE(HumanEntity.class, 16, Type.Byte, NewType.Discontinued), // unused on 1.8
PLAYER_ADDITIONAL_HEARTS(HumanEntity.class, 17, Type.Float, 10, NewType.Float),
PLAYER_SCORE(HumanEntity.class, 18, Type.Int, 11, NewType.VarInt),
PLAYER_HAND(HumanEntity.class, -1, Type.NonExistent, 5, NewType.Byte), // new in 1.9
// horse
HORSE_INFO(Horse.class, 16, Type.Int, 12, NewType.Byte),
HORSE_TYPE(Horse.class, 19, Type.Byte, 13, NewType.VarInt),
HORSE_SUBTYPE(Horse.class, 20, Type.Int, 14, NewType.VarInt),
HORSE_OWNER(Horse.class, 21, Type.String, 15, NewType.OptUUID),
HORSE_ARMOR(Horse.class, 22, Type.Int, 16, NewType.VarInt),
// bat
BAT_ISHANGING(Bat.class, 16, Type.Byte, 11, NewType.Byte),
// tameable
TAMING_INFO(Tameable.class, 16, Type.Byte, 12, NewType.Byte),
TAMING_OWNER(Tameable.class, 17, Type.String, 13, NewType.OptUUID),
// ocelot
OCELOT_TYPE(Ocelot.class, 18, Type.Byte, 14, NewType.VarInt),
// wolf
WOLF_HEALTH(Wolf.class, 18, Type.Float, 14, NewType.Float),
WOLF_BEGGING(Wolf.class, 19, Type.Byte, 15, NewType.Boolean),
WOLF_COLLAR(Wolf.class, 20, Type.Byte, 16, NewType.VarInt),
// pig
PIG_SADDLE(Pig.class, 16, Type.Byte, 12, NewType.Boolean),
// rabbit
RABBIT_TYPE(Rabbit.class, 18, Type.Byte, 12, NewType.VarInt),
// sheep
SHEEP_COLOR(Sheep.class, 16, Type.Byte, 12, NewType.Byte),
// villager
VILLAGER_PROFESSION(Villager.class, 16, Type.Int, 12, NewType.VarInt), // TODO write this to wiki.vg
// enderman
ENDERMAN_BLOCK(Enderman.class, 16, Type.Short, 11, NewType.BlockID), // special case
ENDERMAN_BLOCKDATA(Enderman.class, 17, Type.Byte, 11, NewType.BlockID), // special case
ENDERMAN_ISSCREAMING(Enderman.class, 18, Type.Byte, 12, NewType.Boolean),
// zombie
ZOMBIE_ISCHILD(Zombie.class, 12, Type.Byte, 11, NewType.Boolean),
ZOMBIE_ISVILLAGER(Zombie.class, 13, Type.Byte, 12, NewType.VarInt),
ZOMBIE_ISCONVERTING(Zombie.class, 14, Type.Byte, 13, NewType.Boolean),
// ZOMBIE_RISINGHANDS added in 1.9
// blaze
BLAZE_ONFIRE(Blaze.class, 16, Type.Byte, 11, NewType.Byte),
// spider
SPIDER_CIMBING(Spider.class, 16, Type.Byte, 11, NewType.Byte),
// creeper
CREEPER_FUSE(Creeper.class, 16, Type.Byte, 11, NewType.VarInt), // -1 idle, 1 is fuse
CREEPER_ISPOWERED(Creeper.class, 17, Type.Byte, 12, NewType.Boolean),
CREEPER_ISIGNITED(Creeper.class, 18, Type.Byte, 13, NewType.Boolean),
// ghast
GHAST_ISATTACKING(Ghast.class, 16, Type.Byte, 11, NewType.Boolean),
// slime
SLIME_SIZE(Slime.class, 16, Type.Byte, 11, NewType.VarInt),
// skeleton
SKELETON_TYPE(Skeleton.class, 13, Type.Byte, 11, NewType.VarInt),
// witch
WITCH_AGGRO(Witch.class, 21, Type.Byte, 11, NewType.Boolean),
// iron golem
IRON_PLAYERMADE(IronGolem.class, 16, Type.Byte, 11, NewType.Byte),
// wither
WITHER_TARGET1(Wither.class, 17, Type.Int, 11, NewType.VarInt),
WITHER_TARGET2(Wither.class, 18, Type.Int, 12, NewType.VarInt),
WITHER_TARGET3(Wither.class, 19, Type.Int, 13, NewType.VarInt),
WITHER_INVULN_TIME(Wither.class, 20, Type.Int, 14, NewType.VarInt),
// wither skull
WITHERSKULL_INVULN(WitherSkull.class, 10, Type.Byte, 5, NewType.Boolean),
// guardian
GUARDIAN_INFO(Guardian.class, 16, Type.Int, 11, NewType.Byte),
GUARDIAN_TARGET(Guardian.class, 17, Type.Int, 12, NewType.VarInt),
// boat
BOAT_SINCEHIT(Boat.class, 17, Type.Int, 5, NewType.VarInt),
BOAT_FORWARDDIR(Boat.class, 18, Type.Int, 6, NewType.VarInt),
BOAT_DMGTAKEN(Boat.class, 19, Type.Float, 7, NewType.Float),
// BOAT_TYPE in 1.9
// minecart
MINECART_SHAKINGPOWER(Minecart.class, 17, Type.Int, 5, NewType.VarInt),
MINECART_SHAKINGDIRECTION(Minecart.class, 18, Type.Int, 6, NewType.VarInt),
MINECART_DAMAGETAKEN(Minecart.class, 19, Type.Float, 7, NewType.Float), // also shaking modifier :P
MINECART_BLOCK(Minecart.class, 20, Type.Int, 8, NewType.VarInt),
MINECART_BLOCK_Y(Minecart.class, 21, Type.Int, 9, NewType.VarInt),
MINECART_SHOWBLOCK(Minecart.class, 22, Type.Byte, 10, NewType.Boolean),
// Command minecart (they are still broken)
MINECART_COMMANDBLOCK_COMMAND(Minecart.class, 23, Type.String, 11, NewType.String),
MINECART_COMMANDBLOCK_OUTPUT(Minecart.class, 24, Type.String, 12, NewType.Chat),
// furnace cart
FURNACECART_ISPOWERED(Minecart.class, 16, Type.Byte, 11, NewType.Boolean),
// item drop
ITEM_ITEM(Item.class, 10, Type.Slot, 5, NewType.Slot),
// arrow
ARROW_ISCRIT(Arrow.class, 16, Type.Byte, 5, NewType.Byte),
// firework
FIREWORK_INFO(Firework.class, 8, Type.Slot, 5, NewType.Slot),
// item frame
ITEMFRAME_ITEM(ItemFrame.class, 8, Type.Slot, 5, NewType.Slot),
ITEMFRAME_ROTATION(ItemFrame.class, 9, Type.Byte, 6, NewType.VarInt),
// ender crystal
ENDERCRYSTAL_HEALTH(EnderCrystal.class, 8, Type.Int, NewType.Discontinued),;
private Class<?> clazz;
private int newIndex;
private NewType newType;
private Type oldType;
private int index;
MetaIndex(Class<?> type, int index, Type oldType, NewType newType) {
this.clazz = type;
this.index = index;
this.newIndex = index;
this.oldType = oldType;
this.newType = newType;
}
MetaIndex(Class<?> type, int index, Type oldType, int newIndex, NewType newType) {
this.clazz = type;
this.index = index;
this.oldType = oldType;
this.newIndex = newIndex;
this.newType = newType;
}
public static MetaIndex getIndex(EntityType type, int index) {
Class<? extends org.bukkit.entity.Entity> entityClass = type.getEntityClass();
if (entityClass == null) {
System.out.println("Could not get entity class for " + type);
return null;
}
for (MetaIndex mi : MetaIndex.values()) {
if (mi.getIndex() == index) {
// To fix issue with armour stands colliding with new values
if (mi.getApplicableClass().equals(LivingEntity.class)) continue;
if ((mi.getApplicableClass().isAssignableFrom(entityClass) ||
mi.getApplicableClass().equals(entityClass))) {
return mi;
}
}
}
// fall back to living entity
for (MetaIndex mi : MetaIndex.values()) {
if (mi.getIndex() == index) {
if (mi.getApplicableClass().isAssignableFrom(LivingEntity.class) ||
mi.getApplicableClass().equals(LivingEntity.class)) {
return mi;
}
}
}
return null;
}
public Class<?> getApplicableClass() {
return this.clazz;
}
}
@@ -0,0 +1,216 @@
package us.myles.ViaVersion.metadata;
import io.netty.buffer.ByteBuf;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.entity.EntityType;
import org.bukkit.util.EulerAngle;
import org.bukkit.util.Vector;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.slot.ItemSlotRewriter;
import us.myles.ViaVersion.slot.ItemSlotRewriter.ItemStack;
import us.myles.ViaVersion.transformers.OutgoingTransformer;
import us.myles.ViaVersion.util.PacketUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MetadataRewriter {
public static void writeMetadata1_9(EntityType type, List<Entry> list, ByteBuf output) {
short id = -1;
int data = -1;
for (Entry entry : list) {
MetaIndex metaIndex = entry.index;
try {
if (metaIndex.getNewType() != NewType.Discontinued) {
if (metaIndex.getNewType() != NewType.BlockID || id != -1 && data == -1 || id == -1 && data != -1) { // block ID is only written if we have both parts
output.writeByte(metaIndex.getNewIndex());
output.writeByte(metaIndex.getNewType().getTypeID());
}
Object value = entry.value;
switch (metaIndex.getNewType()) {
case Byte:
// convert from int, byte
if (metaIndex.getOldType() == Type.Byte) {
output.writeByte((Byte) value);
}
if (metaIndex.getOldType() == Type.Int) {
output.writeByte(((Integer) value).byteValue());
}
// After writing the last one
if (metaIndex == MetaIndex.ENTITY_STATUS && type == EntityType.PLAYER) {
output.writeByte(MetaIndex.PLAYER_HAND.getNewIndex());
output.writeByte(MetaIndex.PLAYER_HAND.getNewType().getTypeID());
if ((((Byte) value) & 0x10) == 0x10) { // Player eating/aiming/drinking
output.writeByte(1); // Using main hand
} else {
output.writeByte(0); // Not using any hand to stop animation
}
}
break;
case OptUUID:
String owner = (String) value;
UUID toWrite = null;
if (owner.length() != 0) {
try {
toWrite = UUID.fromString(owner);
} catch (Exception ignored) {
}
}
output.writeBoolean(toWrite != null);
if (toWrite != null)
PacketUtil.writeUUID(toWrite, output);
break;
case BlockID:
// if we have both sources :))
if (metaIndex.getOldType() == Type.Byte) {
data = (Byte) value;
}
if (metaIndex.getOldType() == Type.Short) {
id = (Short) value;
}
if (id != -1 && data != -1) {
int combined = id << 4 | data;
data = -1;
id = -1;
PacketUtil.writeVarInt(combined, output);
}
break;
case VarInt:
// convert from int, short, byte
if (metaIndex.getOldType() == Type.Byte) {
PacketUtil.writeVarInt(((Byte) value).intValue(), output);
}
if (metaIndex.getOldType() == Type.Short) {
PacketUtil.writeVarInt(((Short) value).intValue(), output);
}
if (metaIndex.getOldType() == Type.Int) {
PacketUtil.writeVarInt((Integer) value, output);
}
break;
case Float:
output.writeFloat((Float) value);
break;
case String:
PacketUtil.writeString((String) value, output);
break;
case Boolean:
if (metaIndex == MetaIndex.AGEABLE_AGE)
output.writeBoolean((Byte) value < 0);
else
output.writeBoolean((Byte) value != 0);
break;
case Slot:
ItemStack item = (ItemStack) value;
ItemSlotRewriter.fixIdsFrom1_8To1_9(item);
ItemSlotRewriter.writeItemStack(item, output);
break;
case Position:
Vector vector = (Vector) value;
output.writeInt((int) vector.getX());
output.writeInt((int) vector.getY());
output.writeInt((int) vector.getZ());
break;
case Vector3F:
EulerAngle angle = (EulerAngle) value;
output.writeFloat((float) angle.getX());
output.writeFloat((float) angle.getY());
output.writeFloat((float) angle.getZ());
break;
case Chat:
PacketUtil.writeString(OutgoingTransformer.fixJson((String) value), output);
break;
default:
System.out.println("[Out] Unhandled MetaDataType: " + metaIndex.getNewType());
break;
}
}
} catch (Exception e) {
if (!((ViaVersionPlugin) ViaVersion.getInstance()).isSuppressMetadataErrors()) {
System.out.println("INCLUDE THIS IN YOUR ERROR LOG!");
if (type != null)
System.out.println("An error occurred with entity meta data for " + type + " OldID: " + entry.oldID);
else
System.out.println("An error occurred with entity meta data for UNKNOWN_ENTITY OldID: " + entry.oldID);
if (metaIndex != null) {
System.out.println("Old ID: " + metaIndex.getIndex() + " New ID: " + metaIndex.getNewIndex());
System.out.println("Old Type: " + metaIndex.getOldType() + " New Type: " + metaIndex.getNewType());
}
e.printStackTrace();
}
}
}
output.writeByte(255);
}
public static List<Entry> readMetadata1_8(EntityType entityType, ByteBuf buf) {
List<Entry> entries = new ArrayList<>();
byte item;
while ((item = buf.readByte()) != 127) {
Type type = Type.byId((item & 0xE0) >> 5);
int id = item & 0x1F;
MetaIndex index = MetaIndex.getIndex(entityType, id);
switch (type) {
case Byte:
entries.add(new Entry(index, buf.readByte(), id));
break;
case Short:
entries.add(new Entry(index, buf.readShort(), id));
break;
case Int:
entries.add(new Entry(index, buf.readInt(), id));
break;
case Float:
entries.add(new Entry(index, buf.readFloat(), id));
break;
case String:
entries.add(new Entry(index, PacketUtil.readString(buf), id));
break;
case Slot: {
try {
entries.add(new Entry(index, ItemSlotRewriter.readItemStack(buf), id));
} catch (Exception e) {
e.printStackTrace();
}
}
break;
case Position: {
int x = buf.readInt();
int y = buf.readInt();
int z = buf.readInt();
entries.add(new Entry(index, new Vector(x, y, z), id));
break;
}
case Rotation: {
float x = buf.readFloat();
float y = buf.readFloat();
float z = buf.readFloat();
entries.add(new Entry(index, new EulerAngle(x, y, z), id));
break;
}
default:
System.out.println("[Out] Unhandled MetaDataType: " + type);
break;
}
}
return entries;
}
@Getter
@Setter
public static final class Entry {
private final int oldID;
private MetaIndex index;
private Object value;
private Entry(MetaIndex index, Object value, int id) {
this.index = index;
this.value = value;
this.oldID = id;
}
}
}
@@ -1,5 +1,10 @@
package us.myles.ViaVersion.metadata;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public enum NewType {
Byte(0),
VarInt(1),
@@ -15,13 +20,7 @@ public enum NewType {
OptUUID(11),
BlockID(12),
Discontinued(99);
private final int typeID;
NewType(int typeID){
this.typeID = typeID;
}
public int getTypeID() {
return typeID;
}
}
@@ -1,5 +1,10 @@
package us.myles.ViaVersion.metadata;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public enum Type {
Byte(0),
Short(1),
@@ -8,14 +13,11 @@ public enum Type {
String(4),
Slot(5),
Position(6),
Rotation(7);
Rotation(7),
NonExistent(-1);
private final int typeID;
Type(int typeID){
this.typeID = typeID;
}
public int getTypeID() {
return typeID;
public static Type byId(int id) {
return values()[id];
}
}
@@ -20,7 +20,7 @@ public enum PacketType {
/* Play serverbound */
PLAY_TP_CONFIRM(State.PLAY, Direction.INCOMING, -1, 0x00),
PLAY_TAB_COMPLETE_REQUEST(State.PLAY, Direction.INCOMING, 0x14, 0x01),
PLAY_CLICHAT_MESSAGE_CLIENT(State.PLAY, Direction.INCOMING, 0x01, 0x02),
PLAY_CHAT_MESSAGE_CLIENT(State.PLAY, Direction.INCOMING, 0x01, 0x02),
PLAY_CLIENT_STATUS(State.PLAY, Direction.INCOMING, 0x16, 0x03),
PLAY_CLIENT_SETTINGS(State.PLAY, Direction.INCOMING, 0x15, 0x04),
PLAY_CONFIRM_TRANS(State.PLAY, Direction.INCOMING, 0x0F, 0x05),
@@ -96,7 +96,7 @@ public enum PacketType {
PLAY_COMBAT_EVENT(State.PLAY, Direction.OUTGOING, 0x42, 0x2C),
PLAY_PLAYER_LIST_ITEM(State.PLAY, Direction.OUTGOING, 0x38, 0x2D),
PLAY_PLAYER_POSITION_LOOK(State.PLAY, Direction.OUTGOING, 0x08, 0x2E),
PLAY_USE_BED(State.PLAY, Direction.OUTGOING, 0x2F, 0x2F),
PLAY_USE_BED(State.PLAY, Direction.OUTGOING, 0x0A, 0x2F),
PLAY_DESTROY_ENTITIES(State.PLAY, Direction.OUTGOING, 0x13, 0x30),
PLAY_REMOVE_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1E, 0x31),
PLAY_RESOURCE_PACK_SEND(State.PLAY, Direction.OUTGOING, 0x48, 0x32),
@@ -170,7 +170,7 @@ public enum PacketType {
if(id == -1)
return null;
for (PacketType pt : values()) {
if (pt.getNewPacketID() == id && id != -1
if (pt.getNewPacketID() == id
&& pt.getState() == state
&& pt.getDirection() == direction)
return pt;
@@ -182,7 +182,7 @@ public enum PacketType {
if(id == -1)
return null;
for (PacketType pt : values()) {
if (pt.getPacketID() == id && id != -1
if (pt.getPacketID() == id
&& pt.getState() == state
&& pt.getDirection() == direction)
return pt;
@@ -0,0 +1,322 @@
package us.myles.ViaVersion.slot;
import io.netty.buffer.ByteBuf;
import org.bukkit.Material;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import org.spacehq.opennbt.tag.builtin.ListTag;
import org.spacehq.opennbt.tag.builtin.StringTag;
import org.spacehq.opennbt.tag.builtin.Tag;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.transformers.OutgoingTransformer;
import us.myles.ViaVersion.util.PacketUtil;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class ItemSlotRewriter {
private static final Map<String, Integer> ENTTIY_NAME_TO_ID = new HashMap<>();
private static final Map<Integer, String> ENTTIY_ID_TO_NAME = new HashMap<>();
private static final Map<String, Integer> POTION_NAME_TO_ID = new HashMap<>();
private static final Map<Integer, String> POTION_ID_TO_NAME = new HashMap<>();
static {
/* Entities */
registerEntity(1, "Item");
registerEntity(2, "XPOrb");
registerEntity(7, "ThrownEgg");
registerEntity(8, "LeashKnot");
registerEntity(9, "Painting");
registerEntity(10, "Arrow");
registerEntity(11, "Snowball");
registerEntity(12, "Fireball");
registerEntity(13, "SmallFireball");
registerEntity(14, "ThrownEnderpearl");
registerEntity(15, "EyeOfEnderSignal");
registerEntity(16, "ThrownPotion");
registerEntity(17, "ThrownExpBottle");
registerEntity(18, "ItemFrame");
registerEntity(19, "WitherSkull");
registerEntity(20, "PrimedTnt");
registerEntity(21, "FallingSand");
registerEntity(22, "FireworksRocketEntity");
registerEntity(30, "ArmorStand");
registerEntity(40, "MinecartCommandBlock");
registerEntity(41, "Boat");
registerEntity(42, "MinecartRideable");
registerEntity(43, "MinecartChest");
registerEntity(44, "MinecartFurnace");
registerEntity(45, "MinecartTNT");
registerEntity(46, "MinecartHopper");
registerEntity(47, "MinecartSpawner");
registerEntity(48, "Mob");
registerEntity(49, "Monster");
registerEntity(50, "Creeper");
registerEntity(51, "Skeleton");
registerEntity(52, "Spider");
registerEntity(53, "Giant");
registerEntity(54, "Zombie");
registerEntity(55, "Slime");
registerEntity(56, "Ghast");
registerEntity(57, "PigZombie");
registerEntity(58, "Enderman");
registerEntity(59, "CaveSpider");
registerEntity(60, "Silverfish");
registerEntity(61, "Blaze");
registerEntity(62, "LavaSlime");
registerEntity(63, "EnderDragon");
registerEntity(64, "WitherBoss");
registerEntity(65, "Bat");
registerEntity(66, "Witch");
registerEntity(67, "Endermite");
registerEntity(68, "Guardian");
registerEntity(90, "Pig");
registerEntity(91, "Sheep");
registerEntity(92, "Cow");
registerEntity(93, "Chicken");
registerEntity(94, "Squid");
registerEntity(95, "Wolf");
registerEntity(96, "MushroomCow");
registerEntity(97, "SnowMan");
registerEntity(98, "Ozelot");
registerEntity(99, "VillagerGolem");
registerEntity(100, "EntityHorse");
registerEntity(101, "Rabbit");
registerEntity(120, "Villager");
registerEntity(200, "EnderCrystal");
/* Potions */
registerPotion(0, "water");
registerPotion(64, "mundane");
registerPotion(32, "thick");
registerPotion(16, "awkward");
registerPotion(8198, "night_vision");
registerPotion(8262, "long_night_vision");
registerPotion(8206, "invisibility");
registerPotion(8270, "long_invisibility");
registerPotion(8203, "leaping");
registerPotion(8267, "long_leaping");
registerPotion(8235, "strong_leaping");
registerPotion(8195, "fire_resistance");
registerPotion(8259, "long_fire_resistance");
registerPotion(8194, "swiftness");
registerPotion(8258, "long_swiftness");
registerPotion(8226, "strong_swiftness");
registerPotion(8202, "slowness");
registerPotion(8266, "long_slowness");
registerPotion(8205, "water_breathing");
registerPotion(8269, "long_water_breathing");
registerPotion(8197, "healing");
registerPotion(8229, "strong_healing");
registerPotion(8204, "harming");
registerPotion(8236, "strong_harming");
registerPotion(8196, "poison");
registerPotion(8260, "long_poison");
registerPotion(8228, "strong_poison");
registerPotion(8193, "regeneration");
registerPotion(8257, "long_regeneration");
registerPotion(8225, "strong_regeneration");
registerPotion(8201, "strength");
registerPotion(8265, "long_strength");
registerPotion(8233, "strong_strength");
registerPotion(8200, "weakness");
registerPotion(8264, "long_weakness");
}
public static void rewrite1_9To1_8(ByteBuf input, ByteBuf output) throws CancelException {
try {
ItemStack item = readItemStack(input);
fixIdsFrom1_9To1_8(item);
writeItemStack(item, output);
} catch (Exception e) {
System.out.println("Error while rewriting an item slot.");
e.printStackTrace();
throw new CancelException();
}
}
public static void rewrite1_8To1_9(ByteBuf input, ByteBuf output) throws CancelException {
try {
ItemStack item = readItemStack(input);
fixIdsFrom1_8To1_9(item);
writeItemStack(item, output);
} catch (Exception e) {
System.out.println("Error while rewriting an item slot.");
e.printStackTrace();
throw new CancelException();
}
}
public static void fixIdsFrom1_9To1_8(ItemStack item) {
if (item != null) {
if (item.id == Material.MONSTER_EGG.getId() && item.data == 0) {
CompoundTag tag = item.tag;
int data = 0;
if (tag != null && tag.get("EntityTag") instanceof CompoundTag) {
CompoundTag entityTag = tag.get("EntityTag");
if (entityTag.get("id") instanceof StringTag) {
StringTag id = entityTag.get("id");
if (ENTTIY_NAME_TO_ID.containsKey(id.getValue()))
data = ENTTIY_NAME_TO_ID.get(id.getValue());
}
}
item.tag = null;
item.data = (short) data;
}
if (item.id == Material.POTION.getId()) {
CompoundTag tag = item.tag;
int data = 0;
if (tag != null && tag.get("Potion") instanceof StringTag) {
StringTag potion = tag.get("Potion");
String potionName = potion.getValue().replace("minecraft:", "");
if (POTION_NAME_TO_ID.containsKey(potionName)) {
data = POTION_NAME_TO_ID.get(potionName);
}
}
item.tag = null;
item.data = (short) data;
}
if (item.id == 438) {
CompoundTag tag = item.tag;
int data = 0;
item.id = (short) Material.POTION.getId();
if (tag != null && tag.get("Potion") instanceof StringTag) {
StringTag potion = tag.get("Potion");
String potionName = potion.getValue().replace("minecraft:", "");
if (POTION_NAME_TO_ID.containsKey(potionName)) {
data = POTION_NAME_TO_ID.get(potionName) + 8192;
}
}
item.tag = null;
item.data = (short) data;
}
}
}
public static void fixIdsFrom1_8To1_9(ItemStack item) {
if (item != null) {
if (item.id == Material.MONSTER_EGG.getId() && item.data != 0) {
CompoundTag tag = item.tag;
if (tag == null) {
tag = new CompoundTag("tag");
}
CompoundTag entityTag = new CompoundTag("EntityTag");
if (ENTTIY_ID_TO_NAME.containsKey((int) item.data)) {
StringTag id = new StringTag("id", ENTTIY_ID_TO_NAME.get((int) item.data));
entityTag.put(id);
tag.put(entityTag);
}
item.tag = tag;
item.data = 0;
}
if (item.id == Material.POTION.getId()) {
CompoundTag tag = item.tag;
if (tag == null) {
tag = new CompoundTag("tag");
}
if (item.data >= 16384) {
item.id = 438; // splash id
item.data = (short) (item.data - 8192);
}
if (POTION_ID_TO_NAME.containsKey((int) item.data)) {
String name = POTION_ID_TO_NAME.get((int) item.data);
StringTag potion = new StringTag("Potion", "minecraft:" + name);
tag.put(potion);
}
item.tag = tag;
item.data = 0;
}
if (item.id == Material.WRITTEN_BOOK.getId()) {
CompoundTag tag = item.tag;
if (tag == null) {
tag = new CompoundTag("tag");
}
ListTag pages = tag.get("pages");
if (pages == null) {
pages = new ListTag("pages", Collections.<Tag>singletonList(new StringTag(OutgoingTransformer.fixJson(""))));
tag.put(pages);
item.tag = tag;
return;
}
for (int i = 0; i < pages.size(); i++) {
if (!(pages.get(i) instanceof StringTag))
continue;
StringTag page = pages.get(i);
page.setValue(OutgoingTransformer.fixJson(page.getValue()));
}
item.tag = tag;
}
}
}
public static ItemStack readItemStack(ByteBuf input) throws IOException {
short id = input.readShort();
if (id < 0) {
return null;
} else {
ItemStack item = new ItemStack();
item.id = id;
item.amount = input.readByte();
item.data = input.readShort();
item.tag = PacketUtil.readNBT(input);
return item;
}
}
public static void writeItemStack(ItemStack item, ByteBuf output) throws IOException {
if (item == null) {
output.writeShort(-1);
} else {
output.writeShort(item.id);
output.writeByte(item.amount);
output.writeShort(item.data);
PacketUtil.writeNBT(output, item.tag);
}
}
private static void registerEntity(Integer id, String name) {
ENTTIY_ID_TO_NAME.put(id, name);
ENTTIY_NAME_TO_ID.put(name, id);
}
private static void registerPotion(Integer id, String name) {
POTION_ID_TO_NAME.put(id, name);
POTION_NAME_TO_ID.put(name, id);
}
public static class ItemStack {
public short id;
public byte amount;
public short data;
public CompoundTag tag;
public static ItemStack fromBukkit(org.bukkit.inventory.ItemStack stack) {
if(stack == null) return null;
ItemStack item = new ItemStack();
item.id = (short) stack.getTypeId();
item.amount = (byte) stack.getAmount();
item.data = stack.getData().getData();
// TODO: nbt
return item;
}
}
}
@@ -1,36 +1,25 @@
package us.myles.ViaVersion.sounds;
public enum SoundCategory {
import lombok.Getter;
import lombok.RequiredArgsConstructor;
MASTER("master", 0),
MUSIC("music", 1),
RECORD("record", 2),
WEATHER("weather", 3),
BLOCK("block", 4),
HOSTILE("hostile", 5),
NEUTRAL("neutral", 6),
PLAYER("player", 7),
AMBIENT("ambient", 8),
VOICE("voice", 9);
private String name;
private int id;
SoundCategory(String name, int id)
{
this.name = name;
this.id = id;
}
public String getName()
{
return name;
}
public int getId()
{
return id;
}
@RequiredArgsConstructor
@Getter
public enum SoundCategory {
MASTER("master", 0),
MUSIC("music", 1),
RECORD("record", 2),
WEATHER("weather", 3),
BLOCK("block", 4),
HOSTILE("hostile", 5),
NEUTRAL("neutral", 6),
PLAYER("player", 7),
AMBIENT("ambient", 8),
VOICE("voice", 9);
private final String name;
private final int id;
}
@@ -1,293 +1,283 @@
package us.myles.ViaVersion.sounds;
public enum SoundEffect {
MOB_HORSE_ZOMBIE_IDLE("mob.horse.zombie.idle", "entity.zombie_horse.ambient", SoundCategory.NEUTRAL),
NOTE_SNARE("note.snare", "block.note.snare", SoundCategory.RECORD),
RANDOM_WOOD_CLICK("random.wood_click", "block.wood_button.click_on", SoundCategory.BLOCK),
DIG_GRAVEL("dig.gravel", "block.gravel.place", SoundCategory.BLOCK),
RANDOM_BOWHIT("random.bowhit", "block.tripwire.detach", SoundCategory.NEUTRAL),
DIG_GLASS("dig.glass", "block.glass.break", SoundCategory.BLOCK),
MOB_ZOMBIE_SAY("mob.zombie.say", "entity.zombie_villager.ambient", SoundCategory.HOSTILE),
MOB_PIG_DEATH("mob.pig.death", "entity.pig.death", SoundCategory.NEUTRAL),
MOB_HORSE_DONKEY_HIT("mob.horse.donkey.hit", "entity.donkey.hurt", SoundCategory.NEUTRAL),
GAME_NEUTRAL_SWIM("game.neutral.swim", "entity.player.swim", SoundCategory.NEUTRAL),
GAME_PLAYER_SWIM("game.player.swim", "entity.player.swim", SoundCategory.PLAYER),
MOB_ENDERMEN_IDLE("mob.endermen.idle", "entity.endermen.ambient", SoundCategory.HOSTILE),
PORTAL_PORTAL("portal.portal", "block.portal.ambient", SoundCategory.BLOCK),
RANDOM_FIZZ("random.fizz", "entity.generic.extinguish_fire", SoundCategory.BLOCK),
NOTE_HARP("note.harp", "block.note.harp", SoundCategory.RECORD),
STEP_SNOW("step.snow", "block.snow.step", SoundCategory.NEUTRAL),
RANDOM_SUCCESSFUL_HIT("random.successful_hit", "entity.arrow.hit_player", SoundCategory.PLAYER),
MOB_ZOMBIEPIG_ZPIGHURT("mob.zombiepig.zpighurt", "entity.zombie_pig.hurt", SoundCategory.HOSTILE),
MOB_WOLF_HOWL("mob.wolf.howl", "entity.wolf.howl", SoundCategory.NEUTRAL),
FIREWORKS_LAUNCH("fireworks.launch", "entity.firework.launch", SoundCategory.AMBIENT),
MOB_COW_HURT("mob.cow.hurt", "entity.cow.death", SoundCategory.NEUTRAL),
FIREWORKS_LARGEBLAST("fireworks.largeBlast", "entity.firework.large_blast", SoundCategory.AMBIENT),
MOB_BLAZE_HIT("mob.blaze.hit", "entity.blaze.hurt", SoundCategory.HOSTILE),
MOB_VILLAGER_DEATH("mob.villager.death", "entity.villager.death", SoundCategory.NEUTRAL),
MOB_BLAZE_DEATH("mob.blaze.death", "entity.blaze.death", SoundCategory.HOSTILE),
MOB_HORSE_ZOMBIE_DEATH("mob.horse.zombie.death", "entity.zombie_horse.death", SoundCategory.NEUTRAL),
MOB_SILVERFISH_KILL("mob.silverfish.kill", "entity.endermite.death", SoundCategory.HOSTILE),
MOB_WOLF_PANTING("mob.wolf.panting", "entity.wolf.pant", SoundCategory.NEUTRAL),
NOTE_BASS("note.bass", "null", SoundCategory.RECORD),
DIG_STONE("dig.stone", "block.glass.place", SoundCategory.BLOCK),
MOB_ENDERMEN_STARE("mob.endermen.stare", "entity.endermen.stare", SoundCategory.HOSTILE),
GAME_PLAYER_SWIM_SPLASH("game.player.swim.splash", "entity.generic.splash", SoundCategory.BLOCK),
MOB_SLIME_SMALL("mob.slime.small", "block.slime.hit", SoundCategory.HOSTILE),
MOB_GHAST_DEATH("mob.ghast.death", "entity.ghast.death", SoundCategory.HOSTILE),
MOB_GUARDIAN_ATTACK("mob.guardian.attack", "entity.guardian.attack", SoundCategory.HOSTILE),
RANDOM_CLICK("random.click", "block.wood_pressureplate.click_on", SoundCategory.BLOCK),
MOB_ZOMBIEPIG_ZPIG("mob.zombiepig.zpig", "entity.zombie_pig.ambient", SoundCategory.HOSTILE),
GAME_PLAYER_DIE("game.player.die", "entity.player.death", SoundCategory.PLAYER),
FIREWORKS_TWINKLE_FAR("fireworks.twinkle_far", "entity.firework.twinkle_far", SoundCategory.AMBIENT),
MOB_GUARDIAN_LAND_IDLE("mob.guardian.land.idle", "entity.guardian.ambient_land", SoundCategory.HOSTILE),
DIG_GRASS("dig.grass", "block.grass.place", SoundCategory.BLOCK),
MOB_SKELETON_STEP("mob.skeleton.step", "entity.skeleton.step", SoundCategory.HOSTILE),
MOB_WITHER_DEATH("mob.wither.death", "entity.wither.death", SoundCategory.HOSTILE),
MOB_WOLF_HURT("mob.wolf.hurt", "entity.wolf.hurt", SoundCategory.NEUTRAL),
MOB_HORSE_LEATHER("mob.horse.leather", "entity.horse.saddle", SoundCategory.NEUTRAL),
MOB_BAT_LOOP("mob.bat.loop", "entity.bat.loop", SoundCategory.NEUTRAL),
MOB_GHAST_SCREAM("mob.ghast.scream", "entity.ghast.hurt", SoundCategory.HOSTILE),
GAME_PLAYER_HURT("game.player.hurt", "entity.player.death", SoundCategory.PLAYER),
GAME_NEUTRAL_DIE("game.neutral.die", "entity.player.death", SoundCategory.NEUTRAL),
MOB_CREEPER_DEATH("mob.creeper.death", "entity.creeper.death", SoundCategory.HOSTILE),
MOB_HORSE_GALLOP("mob.horse.gallop", "entity.horse.gallop", SoundCategory.NEUTRAL),
MOB_WITHER_SPAWN("mob.wither.spawn", "entity.wither.spawn", SoundCategory.HOSTILE),
MOB_ENDERMEN_HIT("mob.endermen.hit", "entity.endermen.hurt", SoundCategory.HOSTILE),
MOB_CREEPER_SAY("mob.creeper.say", "entity.creeper.hurt", SoundCategory.HOSTILE),
MOB_HORSE_WOOD("mob.horse.wood", "entity.horse.step_wood", SoundCategory.NEUTRAL),
MOB_ZOMBIE_UNFECT("mob.zombie.unfect", "entity.zombie_villager.converted", SoundCategory.HOSTILE),
RANDOM_ANVIL_USE("random.anvil_use", "block.anvil.use", SoundCategory.BLOCK),
RANDOM_CHESTCLOSED("random.chestclosed", "block.enderchest.close", SoundCategory.BLOCK),
MOB_SHEEP_SHEAR("mob.sheep.shear", "entity.sheep.shear", SoundCategory.NEUTRAL),
RANDOM_POP("random.pop", "entity.item.pickup", SoundCategory.PLAYER),
MOB_BAT_DEATH("mob.bat.death", "entity.bat.death", SoundCategory.NEUTRAL),
DIG_WOOD("dig.wood", "block.ladder.break", SoundCategory.BLOCK),
MOB_HORSE_DONKEY_DEATH("mob.horse.donkey.death", "entity.donkey.death", SoundCategory.NEUTRAL),
FIREWORKS_BLAST("fireworks.blast", "entity.firework.blast", SoundCategory.AMBIENT),
MOB_ZOMBIEPIG_ZPIGANGRY("mob.zombiepig.zpigangry", "entity.zombie_pig.angry", SoundCategory.HOSTILE),
GAME_HOSTILE_SWIM("game.hostile.swim", "entity.player.swim", SoundCategory.HOSTILE),
MOB_GUARDIAN_FLOP("mob.guardian.flop", "entity.guardian.flop", SoundCategory.HOSTILE),
MOB_VILLAGER_YES("mob.villager.yes", "entity.villager.yes", SoundCategory.NEUTRAL),
MOB_GHAST_CHARGE("mob.ghast.charge", "entity.ghast.warn", SoundCategory.HOSTILE),
CREEPER_PRIMED("creeper.primed", "entity.creeper.primed", SoundCategory.HOSTILE),
DIG_SAND("dig.sand", "block.sand.break", SoundCategory.BLOCK),
MOB_CHICKEN_SAY("mob.chicken.say", "entity.chicken.ambient", SoundCategory.NEUTRAL),
RANDOM_DOOR_CLOSE("random.door_close", "null", SoundCategory.BLOCK),
MOB_GUARDIAN_ELDER_DEATH("mob.guardian.elder.death", "entity.elder_guardian.death", SoundCategory.HOSTILE),
FIREWORKS_TWINKLE("fireworks.twinkle", "entity.firework.twinkle", SoundCategory.AMBIENT),
MOB_HORSE_SKELETON_DEATH("mob.horse.skeleton.death", "entity.skeleton_horse.death", SoundCategory.NEUTRAL),
AMBIENT_WEATHER_RAIN("ambient.weather.rain", "weather.rain.above", SoundCategory.WEATHER),
PORTAL_TRIGGER("portal.trigger", "block.portal.trigger", SoundCategory.BLOCK),
RANDOM_CHESTOPEN("random.chestopen", "block.enderchest.open", SoundCategory.BLOCK),
MOB_HORSE_LAND("mob.horse.land", "entity.horse.land", SoundCategory.NEUTRAL),
MOB_SILVERFISH_STEP("mob.silverfish.step", "entity.silverfish.step", SoundCategory.HOSTILE),
MOB_BAT_TAKEOFF("mob.bat.takeoff", "entity.bat.takeoff", SoundCategory.NEUTRAL),
MOB_VILLAGER_NO("mob.villager.no", "entity.villager.no", SoundCategory.NEUTRAL),
GAME_HOSTILE_HURT_FALL_BIG("game.hostile.hurt.fall.big", "entity.hostile.big_fall", SoundCategory.HOSTILE),
MOB_IRONGOLEM_WALK("mob.irongolem.walk", "entity.irongolem.step", SoundCategory.NEUTRAL),
NOTE_HAT("note.hat", "block.note.hat", SoundCategory.RECORD),
MOB_ZOMBIE_METAL("mob.zombie.metal", "entity.zombie.attack_iron_door", SoundCategory.HOSTILE),
MOB_VILLAGER_HAGGLE("mob.villager.haggle", "entity.villager.trading", SoundCategory.NEUTRAL),
MOB_GHAST_FIREBALL("mob.ghast.fireball", "entity.blaze.shoot", SoundCategory.HOSTILE),
MOB_IRONGOLEM_DEATH("mob.irongolem.death", "entity.irongolem.death", SoundCategory.NEUTRAL),
RANDOM_BREAK("random.break", "item.shield.break", SoundCategory.PLAYER),
MOB_ZOMBIE_REMEDY("mob.zombie.remedy", "entity.zombie_villager.cure", SoundCategory.HOSTILE),
RANDOM_BOW("random.bow", "entity.splash_potion.throw", SoundCategory.NEUTRAL),
MOB_VILLAGER_IDLE("mob.villager.idle", "entity.villager.ambient", SoundCategory.NEUTRAL),
STEP_CLOTH("step.cloth", "block.cloth.fall", SoundCategory.NEUTRAL),
MOB_SILVERFISH_HIT("mob.silverfish.hit", "entity.endermite.hurt", SoundCategory.HOSTILE),
LIQUID_LAVA("liquid.lava", "block.lava.ambient", SoundCategory.BLOCK),
GAME_NEUTRAL_HURT_FALL_BIG("game.neutral.hurt.fall.big", "entity.hostile.big_fall", SoundCategory.NEUTRAL),
FIRE_FIRE("fire.fire", "block.fire.ambient", SoundCategory.BLOCK),
MOB_ZOMBIE_WOOD("mob.zombie.wood", "entity.zombie.attack_door_wood", SoundCategory.HOSTILE),
MOB_CHICKEN_STEP("mob.chicken.step", "entity.chicken.step", SoundCategory.NEUTRAL),
MOB_GUARDIAN_LAND_HIT("mob.guardian.land.hit", "entity.guardian.hurt_land", SoundCategory.HOSTILE),
MOB_CHICKEN_PLOP("mob.chicken.plop", "entity.donkey.chest", SoundCategory.NEUTRAL),
MOB_ENDERDRAGON_WINGS("mob.enderdragon.wings", "entity.enderdragon.flap", SoundCategory.HOSTILE),
STEP_GRASS("step.grass", "block.grass.hit", SoundCategory.NEUTRAL),
MOB_HORSE_BREATHE("mob.horse.breathe", "entity.horse.breathe", SoundCategory.NEUTRAL),
GAME_PLAYER_HURT_FALL_BIG("game.player.hurt.fall.big", "entity.hostile.big_fall", SoundCategory.PLAYER),
MOB_HORSE_DONKEY_IDLE("mob.horse.donkey.idle", "entity.donkey.ambient", SoundCategory.NEUTRAL),
MOB_SPIDER_STEP("mob.spider.step", "entity.spider.step", SoundCategory.HOSTILE),
GAME_NEUTRAL_HURT("game.neutral.hurt", "entity.player.death", SoundCategory.NEUTRAL),
MOB_COW_SAY("mob.cow.say", "entity.cow.ambient", SoundCategory.NEUTRAL),
MOB_HORSE_JUMP("mob.horse.jump", "entity.horse.jump", SoundCategory.NEUTRAL),
MOB_HORSE_SOFT("mob.horse.soft", "entity.horse.step", SoundCategory.NEUTRAL),
GAME_NEUTRAL_SWIM_SPLASH("game.neutral.swim.splash", "entity.generic.splash", SoundCategory.NEUTRAL),
MOB_GUARDIAN_HIT("mob.guardian.hit", "entity.guardian.hurt", SoundCategory.HOSTILE),
MOB_ENDERDRAGON_END("mob.enderdragon.end", "entity.enderdragon.death", SoundCategory.HOSTILE),
MOB_ZOMBIE_STEP("mob.zombie.step", "entity.zombie.step", SoundCategory.HOSTILE),
MOB_ENDERDRAGON_GROWL("mob.enderdragon.growl", "entity.enderdragon.growl", SoundCategory.HOSTILE),
MOB_WOLF_SHAKE("mob.wolf.shake", "entity.wolf.shake", SoundCategory.NEUTRAL),
MOB_ENDERMEN_DEATH("mob.endermen.death", "entity.endermen.death", SoundCategory.HOSTILE),
RANDOM_ANVIL_LAND("random.anvil_land", "block.anvil.land", SoundCategory.BLOCK),
GAME_HOSTILE_HURT("game.hostile.hurt", "entity.player.death", SoundCategory.HOSTILE),
MINECART_INSIDE("minecart.inside", "entity.minecart.inside", SoundCategory.PLAYER),
MOB_SLIME_BIG("mob.slime.big", "entity.slime.death", SoundCategory.HOSTILE),
LIQUID_WATER("liquid.water", "block.water.ambient", SoundCategory.BLOCK),
MOB_PIG_SAY("mob.pig.say", "entity.pig.ambient", SoundCategory.NEUTRAL),
MOB_WITHER_SHOOT("mob.wither.shoot", "entity.wither.shoot", SoundCategory.HOSTILE),
ITEM_FIRECHARGE_USE("item.fireCharge.use", "entity.blaze.shoot", SoundCategory.BLOCK),
STEP_SAND("step.sand", "block.sand.fall", SoundCategory.NEUTRAL),
MOB_IRONGOLEM_HIT("mob.irongolem.hit", "entity.irongolem.hurt", SoundCategory.NEUTRAL),
MOB_HORSE_DEATH("mob.horse.death", "entity.horse.death", SoundCategory.NEUTRAL),
MOB_BAT_HURT("mob.bat.hurt", "entity.bat.hurt", SoundCategory.NEUTRAL),
MOB_GHAST_AFFECTIONATE_SCREAM("mob.ghast.affectionate_scream", "entity.ghast.scream", SoundCategory.HOSTILE),
MOB_GUARDIAN_ELDER_IDLE("mob.guardian.elder.idle", "entity.elder_guardian.ambient", SoundCategory.HOSTILE),
MOB_ZOMBIEPIG_ZPIGDEATH("mob.zombiepig.zpigdeath", "entity.zombie_pig.death", SoundCategory.HOSTILE),
AMBIENT_WEATHER_THUNDER("ambient.weather.thunder", "entity.lightning.thunder", SoundCategory.WEATHER),
MINECART_BASE("minecart.base", "entity.minecart.riding", SoundCategory.NEUTRAL),
STEP_LADDER("step.ladder", "block.ladder.hit", SoundCategory.NEUTRAL),
MOB_HORSE_DONKEY_ANGRY("mob.horse.donkey.angry", "entity.donkey.angry", SoundCategory.NEUTRAL),
AMBIENT_CAVE_CAVE("ambient.cave.cave", "ambient.cave", SoundCategory.AMBIENT),
FIREWORKS_BLAST_FAR("fireworks.blast_far", "entity.firework.blast_far", SoundCategory.AMBIENT),
GAME_NEUTRAL_HURT_FALL_SMALL("game.neutral.hurt.fall.small", "entity.generic.small_fall", SoundCategory.NEUTRAL),
GAME_HOSTILE_SWIM_SPLASH("game.hostile.swim.splash", "entity.generic.splash", SoundCategory.HOSTILE),
RANDOM_DRINK("random.drink", "entity.generic.drink", SoundCategory.PLAYER),
GAME_HOSTILE_DIE("game.hostile.die", "entity.player.death", SoundCategory.HOSTILE),
MOB_CAT_HISS("mob.cat.hiss", "entity.cat.hiss", SoundCategory.NEUTRAL),
NOTE_BD("note.bd", "block.note.basedrum", SoundCategory.RECORD),
MOB_SPIDER_SAY("mob.spider.say", "entity.spider.hurt", SoundCategory.HOSTILE),
STEP_STONE("step.stone", "block.anvil.hit", SoundCategory.NEUTRAL),
RANDOM_LEVELUP("random.levelup", "entity.player.levelup", SoundCategory.PLAYER),
LIQUID_LAVAPOP("liquid.lavapop", "block.lava.pop", SoundCategory.BLOCK),
MOB_SHEEP_SAY("mob.sheep.say", "entity.sheep.ambient", SoundCategory.NEUTRAL),
MOB_SKELETON_SAY("mob.skeleton.say", "entity.skeleton.ambient", SoundCategory.HOSTILE),
MOB_BLAZE_BREATHE("mob.blaze.breathe", "entity.blaze.ambient", SoundCategory.HOSTILE),
MOB_BAT_IDLE("mob.bat.idle", "entity.bat.ambient", SoundCategory.NEUTRAL),
MOB_MAGMACUBE_BIG("mob.magmacube.big", "entity.magmacube.squish", SoundCategory.HOSTILE),
MOB_HORSE_IDLE("mob.horse.idle", "entity.horse.ambient", SoundCategory.NEUTRAL),
GAME_HOSTILE_HURT_FALL_SMALL("game.hostile.hurt.fall.small", "entity.generic.small_fall", SoundCategory.HOSTILE),
MOB_HORSE_ZOMBIE_HIT("mob.horse.zombie.hit", "entity.zombie_horse.hurt", SoundCategory.NEUTRAL),
MOB_IRONGOLEM_THROW("mob.irongolem.throw", "entity.irongolem.attack", SoundCategory.NEUTRAL),
DIG_CLOTH("dig.cloth", "block.cloth.place", SoundCategory.BLOCK),
STEP_GRAVEL("step.gravel", "block.gravel.hit", SoundCategory.NEUTRAL),
MOB_SILVERFISH_SAY("mob.silverfish.say", "entity.silverfish.ambient", SoundCategory.HOSTILE),
MOB_CAT_PURR("mob.cat.purr", "entity.cat.purr", SoundCategory.NEUTRAL),
MOB_ZOMBIE_INFECT("mob.zombie.infect", "entity.zombie.infect", SoundCategory.HOSTILE),
RANDOM_EAT("random.eat", "entity.generic.eat", SoundCategory.PLAYER),
MOB_WOLF_BARK("mob.wolf.bark", "entity.wolf.ambient", SoundCategory.NEUTRAL),
GAME_TNT_PRIMED("game.tnt.primed", "entity.creeper.primed", SoundCategory.BLOCK),
MOB_SHEEP_STEP("mob.sheep.step", "entity.sheep.step", SoundCategory.NEUTRAL),
MOB_ZOMBIE_DEATH("mob.zombie.death", "entity.zombie.death", SoundCategory.HOSTILE),
RANDOM_DOOR_OPEN("random.door_open", "null", SoundCategory.BLOCK),
MOB_ENDERMEN_PORTAL("mob.endermen.portal", "entity.endermen.teleport", SoundCategory.HOSTILE),
MOB_HORSE_ANGRY("mob.horse.angry", "entity.horse.angry", SoundCategory.NEUTRAL),
MOB_WOLF_GROWL("mob.wolf.growl", "entity.wolf.growl", SoundCategory.NEUTRAL),
DIG_SNOW("dig.snow", "block.snow.place", SoundCategory.BLOCK),
TILE_PISTON_OUT("tile.piston.out", "block.piston.extend", SoundCategory.BLOCK),
RANDOM_BURP("random.burp", "entity.player.burp", SoundCategory.PLAYER),
MOB_COW_STEP("mob.cow.step", "entity.cow.step", SoundCategory.NEUTRAL),
MOB_WITHER_HURT("mob.wither.hurt", "entity.wither.hurt", SoundCategory.HOSTILE),
MOB_GUARDIAN_LAND_DEATH("mob.guardian.land.death", "entity.elder_guardian.death_land", SoundCategory.HOSTILE),
MOB_CHICKEN_HURT("mob.chicken.hurt", "entity.chicken.death", SoundCategory.NEUTRAL),
MOB_WOLF_STEP("mob.wolf.step", "entity.wolf.step", SoundCategory.NEUTRAL),
MOB_WOLF_DEATH("mob.wolf.death", "entity.wolf.death", SoundCategory.NEUTRAL),
MOB_WOLF_WHINE("mob.wolf.whine", "entity.wolf.whine", SoundCategory.NEUTRAL),
NOTE_PLING("note.pling", "block.note.pling", SoundCategory.RECORD),
GAME_PLAYER_HURT_FALL_SMALL("game.player.hurt.fall.small", "entity.generic.small_fall", SoundCategory.PLAYER),
MOB_CAT_PURREOW("mob.cat.purreow", "entity.cat.purreow", SoundCategory.NEUTRAL),
FIREWORKS_LARGEBLAST_FAR("fireworks.largeBlast_far", "entity.firework.large_blast_far", SoundCategory.AMBIENT),
MOB_SKELETON_HURT("mob.skeleton.hurt", "entity.skeleton.hurt", SoundCategory.HOSTILE),
MOB_SPIDER_DEATH("mob.spider.death", "entity.spider.death", SoundCategory.HOSTILE),
RANDOM_ANVIL_BREAK("random.anvil_break", "block.anvil.destroy", SoundCategory.BLOCK),
MOB_WITHER_IDLE("mob.wither.idle", "entity.wither.ambient", SoundCategory.HOSTILE),
MOB_GUARDIAN_ELDER_HIT("mob.guardian.elder.hit", "entity.elder_guardian.hurt", SoundCategory.HOSTILE),
MOB_ENDERMEN_SCREAM("mob.endermen.scream", "entity.endermen.scream", SoundCategory.HOSTILE),
MOB_CAT_HITT("mob.cat.hitt", "entity.cat.hurt", SoundCategory.NEUTRAL),
MOB_MAGMACUBE_SMALL("mob.magmacube.small", "entity.small_magmacube.squish", SoundCategory.HOSTILE),
FIRE_IGNITE("fire.ignite", "item.flintandsteel.use", SoundCategory.BLOCK),
MOB_ENDERDRAGON_HIT("mob.enderdragon.hit", "entity.enderdragon.hurt", SoundCategory.HOSTILE),
MOB_ZOMBIE_HURT("mob.zombie.hurt", "entity.zombie_villager.hurt", SoundCategory.HOSTILE),
RANDOM_EXPLODE("random.explode", "block.end_gateway.spawn", SoundCategory.BLOCK),
MOB_SLIME_ATTACK("mob.slime.attack", "entity.slime.attack", SoundCategory.HOSTILE),
MOB_MAGMACUBE_JUMP("mob.magmacube.jump", "entity.magmacube.jump", SoundCategory.HOSTILE),
RANDOM_SPLASH("random.splash", "entity.bobber.splash", SoundCategory.PLAYER),
MOB_HORSE_SKELETON_HIT("mob.horse.skeleton.hit", "entity.skeleton_horse.hurt", SoundCategory.NEUTRAL),
MOB_GHAST_MOAN("mob.ghast.moan", "entity.ghast.ambient", SoundCategory.HOSTILE),
MOB_GUARDIAN_CURSE("mob.guardian.curse", "entity.elder_guardian.curse", SoundCategory.HOSTILE),
GAME_POTION_SMASH("game.potion.smash", "block.glass.break", SoundCategory.NEUTRAL),
NOTE_BASSATTACK("note.bassattack", "block.note.bass", SoundCategory.RECORD),
GUI_BUTTON_PRESS("gui.button.press", "block.wood_pressureplate.click_on", SoundCategory.MASTER),
RANDOM_ORB("random.orb", "entity.experience_orb.pickup", SoundCategory.PLAYER),
MOB_ZOMBIE_WOODBREAK("mob.zombie.woodbreak", "entity.zombie.break_door_wood", SoundCategory.HOSTILE),
MOB_HORSE_ARMOR("mob.horse.armor", "entity.horse.armor", SoundCategory.NEUTRAL),
TILE_PISTON_IN("tile.piston.in", "block.piston.contract", SoundCategory.BLOCK),
MOB_CAT_MEOW("mob.cat.meow", "entity.cat.ambient", SoundCategory.NEUTRAL),
MOB_PIG_STEP("mob.pig.step", "entity.pig.step", SoundCategory.NEUTRAL),
STEP_WOOD("step.wood", "block.wood.step", SoundCategory.NEUTRAL),
PORTAL_TRAVEL("portal.travel", "block.portal.travel", SoundCategory.PLAYER),
MOB_GUARDIAN_DEATH("mob.guardian.death", "entity.guardian.death", SoundCategory.HOSTILE),
MOB_SKELETON_DEATH("mob.skeleton.death", "entity.skeleton.death", SoundCategory.HOSTILE),
MOB_HORSE_HIT("mob.horse.hit", "entity.horse.hurt", SoundCategory.NEUTRAL),
MOB_VILLAGER_HIT("mob.villager.hit", "entity.villager.hurt", SoundCategory.NEUTRAL),
MOB_HORSE_SKELETON_IDLE("mob.horse.skeleton.idle", "entity.skeleton_horse.ambient", SoundCategory.NEUTRAL);
//NOT ALL SOUNDS INCLUDED!
//Missing all new 1.9 sounds
//Missing (1.8 sound names):
//records.ward
//music.game.nether
//music.game.end.dragon
//mob.rabbit.death
//records.chirp
//records.13
//records.11
//music.game.end.credits
//records.mellohi
//music.game
//records.mall
//records.stal
//records.far
//records.blocks
//music.game.creative
//records.wait
//music.menu
//music.game.end
//mob.rabbit.hurt
//records.cat
//mob.guardian.idle
//mob.rabbit.hop
//mob.rabbit.idle
//records.strad
private String name;
private String newname;
private SoundCategory cat;
SoundEffect(String name, String newname, SoundCategory cat)
{
this.cat = cat;
this.newname = newname;
this.name = name;
}
public static SoundEffect getByName(String name)
{
name = name.toLowerCase();
for(SoundEffect e : SoundEffect.values())
{
if(e.getName().equals(name))
return e;
}
return null;
}
public String getNewName()
{
return newname;
}
public String getName()
{
return name;
}
public SoundCategory getCategory()
{
return cat;
}
}
package us.myles.ViaVersion.sounds;
import lombok.Getter;
@Getter
public enum SoundEffect {
MOB_HORSE_ZOMBIE_IDLE("mob.horse.zombie.idle", "entity.zombie_horse.ambient", SoundCategory.NEUTRAL),
NOTE_SNARE("note.snare", "block.note.snare", SoundCategory.RECORD),
RANDOM_WOOD_CLICK("random.wood_click", "block.wood_button.click_on", SoundCategory.BLOCK),
DIG_GRAVEL("dig.gravel", "block.gravel.place", SoundCategory.BLOCK),
RANDOM_BOWHIT("random.bowhit", "block.tripwire.detach", SoundCategory.NEUTRAL),
DIG_GLASS("dig.glass", "block.glass.break", SoundCategory.BLOCK),
MOB_ZOMBIE_SAY("mob.zombie.say", "entity.zombie_villager.ambient", SoundCategory.HOSTILE),
MOB_PIG_DEATH("mob.pig.death", "entity.pig.death", SoundCategory.NEUTRAL),
MOB_HORSE_DONKEY_HIT("mob.horse.donkey.hit", "entity.donkey.hurt", SoundCategory.NEUTRAL),
GAME_NEUTRAL_SWIM("game.neutral.swim", "entity.player.swim", SoundCategory.NEUTRAL),
GAME_PLAYER_SWIM("game.player.swim", "entity.player.swim", SoundCategory.PLAYER),
MOB_ENDERMEN_IDLE("mob.endermen.idle", "entity.endermen.ambient", SoundCategory.HOSTILE),
PORTAL_PORTAL("portal.portal", "block.portal.ambient", SoundCategory.BLOCK),
RANDOM_FIZZ("random.fizz", "entity.generic.extinguish_fire", SoundCategory.BLOCK),
NOTE_HARP("note.harp", "block.note.harp", SoundCategory.RECORD),
STEP_SNOW("step.snow", "block.snow.step", SoundCategory.NEUTRAL),
RANDOM_SUCCESSFUL_HIT("random.successful_hit", "entity.arrow.hit_player", SoundCategory.PLAYER),
MOB_ZOMBIEPIG_ZPIGHURT("mob.zombiepig.zpighurt", "entity.zombie_pig.hurt", SoundCategory.HOSTILE),
MOB_WOLF_HOWL("mob.wolf.howl", "entity.wolf.howl", SoundCategory.NEUTRAL),
FIREWORKS_LAUNCH("fireworks.launch", "entity.firework.launch", SoundCategory.AMBIENT),
MOB_COW_HURT("mob.cow.hurt", "entity.cow.death", SoundCategory.NEUTRAL),
FIREWORKS_LARGEBLAST("fireworks.largeBlast", "entity.firework.large_blast", SoundCategory.AMBIENT),
MOB_BLAZE_HIT("mob.blaze.hit", "entity.blaze.hurt", SoundCategory.HOSTILE),
MOB_VILLAGER_DEATH("mob.villager.death", "entity.villager.death", SoundCategory.NEUTRAL),
MOB_BLAZE_DEATH("mob.blaze.death", "entity.blaze.death", SoundCategory.HOSTILE),
MOB_HORSE_ZOMBIE_DEATH("mob.horse.zombie.death", "entity.zombie_horse.death", SoundCategory.NEUTRAL),
MOB_SILVERFISH_KILL("mob.silverfish.kill", "entity.endermite.death", SoundCategory.HOSTILE),
MOB_WOLF_PANTING("mob.wolf.panting", "entity.wolf.pant", SoundCategory.NEUTRAL),
NOTE_BASS("note.bass", "null", SoundCategory.RECORD),
DIG_STONE("dig.stone", "block.glass.place", SoundCategory.BLOCK),
MOB_ENDERMEN_STARE("mob.endermen.stare", "entity.endermen.stare", SoundCategory.HOSTILE),
GAME_PLAYER_SWIM_SPLASH("game.player.swim.splash", "entity.generic.splash", SoundCategory.BLOCK),
MOB_SLIME_SMALL("mob.slime.small", "block.slime.hit", SoundCategory.HOSTILE),
MOB_GHAST_DEATH("mob.ghast.death", "entity.ghast.death", SoundCategory.HOSTILE),
MOB_GUARDIAN_ATTACK("mob.guardian.attack", "entity.guardian.attack", SoundCategory.HOSTILE),
RANDOM_CLICK("random.click", "block.wood_pressureplate.click_on", SoundCategory.BLOCK),
MOB_ZOMBIEPIG_ZPIG("mob.zombiepig.zpig", "entity.zombie_pig.ambient", SoundCategory.HOSTILE),
GAME_PLAYER_DIE("game.player.die", "entity.player.death", SoundCategory.PLAYER),
FIREWORKS_TWINKLE_FAR("fireworks.twinkle_far", "entity.firework.twinkle_far", SoundCategory.AMBIENT),
MOB_GUARDIAN_LAND_IDLE("mob.guardian.land.idle", "entity.guardian.ambient_land", SoundCategory.HOSTILE),
DIG_GRASS("dig.grass", "block.grass.place", SoundCategory.BLOCK),
MOB_SKELETON_STEP("mob.skeleton.step", "entity.skeleton.step", SoundCategory.HOSTILE),
MOB_WITHER_DEATH("mob.wither.death", "entity.wither.death", SoundCategory.HOSTILE),
MOB_WOLF_HURT("mob.wolf.hurt", "entity.wolf.hurt", SoundCategory.NEUTRAL),
MOB_HORSE_LEATHER("mob.horse.leather", "entity.horse.saddle", SoundCategory.NEUTRAL),
MOB_BAT_LOOP("mob.bat.loop", "entity.bat.loop", SoundCategory.NEUTRAL),
MOB_GHAST_SCREAM("mob.ghast.scream", "entity.ghast.hurt", SoundCategory.HOSTILE),
GAME_PLAYER_HURT("game.player.hurt", "entity.player.death", SoundCategory.PLAYER),
GAME_NEUTRAL_DIE("game.neutral.die", "entity.player.death", SoundCategory.NEUTRAL),
MOB_CREEPER_DEATH("mob.creeper.death", "entity.creeper.death", SoundCategory.HOSTILE),
MOB_HORSE_GALLOP("mob.horse.gallop", "entity.horse.gallop", SoundCategory.NEUTRAL),
MOB_WITHER_SPAWN("mob.wither.spawn", "entity.wither.spawn", SoundCategory.HOSTILE),
MOB_ENDERMEN_HIT("mob.endermen.hit", "entity.endermen.hurt", SoundCategory.HOSTILE),
MOB_CREEPER_SAY("mob.creeper.say", "entity.creeper.hurt", SoundCategory.HOSTILE),
MOB_HORSE_WOOD("mob.horse.wood", "entity.horse.step_wood", SoundCategory.NEUTRAL),
MOB_ZOMBIE_UNFECT("mob.zombie.unfect", "entity.zombie_villager.converted", SoundCategory.HOSTILE),
RANDOM_ANVIL_USE("random.anvil_use", "block.anvil.use", SoundCategory.BLOCK),
RANDOM_CHESTCLOSED("random.chestclosed", "block.enderchest.close", SoundCategory.BLOCK),
MOB_SHEEP_SHEAR("mob.sheep.shear", "entity.sheep.shear", SoundCategory.NEUTRAL),
RANDOM_POP("random.pop", "entity.item.pickup", SoundCategory.PLAYER),
MOB_BAT_DEATH("mob.bat.death", "entity.bat.death", SoundCategory.NEUTRAL),
DIG_WOOD("dig.wood", "block.ladder.break", SoundCategory.BLOCK),
MOB_HORSE_DONKEY_DEATH("mob.horse.donkey.death", "entity.donkey.death", SoundCategory.NEUTRAL),
FIREWORKS_BLAST("fireworks.blast", "entity.firework.blast", SoundCategory.AMBIENT),
MOB_ZOMBIEPIG_ZPIGANGRY("mob.zombiepig.zpigangry", "entity.zombie_pig.angry", SoundCategory.HOSTILE),
GAME_HOSTILE_SWIM("game.hostile.swim", "entity.player.swim", SoundCategory.HOSTILE),
MOB_GUARDIAN_FLOP("mob.guardian.flop", "entity.guardian.flop", SoundCategory.HOSTILE),
MOB_VILLAGER_YES("mob.villager.yes", "entity.villager.yes", SoundCategory.NEUTRAL),
MOB_GHAST_CHARGE("mob.ghast.charge", "entity.ghast.warn", SoundCategory.HOSTILE),
CREEPER_PRIMED("creeper.primed", "entity.creeper.primed", SoundCategory.HOSTILE),
DIG_SAND("dig.sand", "block.sand.break", SoundCategory.BLOCK),
MOB_CHICKEN_SAY("mob.chicken.say", "entity.chicken.ambient", SoundCategory.NEUTRAL),
RANDOM_DOOR_CLOSE("random.door_close", "null", SoundCategory.BLOCK),
MOB_GUARDIAN_ELDER_DEATH("mob.guardian.elder.death", "entity.elder_guardian.death", SoundCategory.HOSTILE),
FIREWORKS_TWINKLE("fireworks.twinkle", "entity.firework.twinkle", SoundCategory.AMBIENT),
MOB_HORSE_SKELETON_DEATH("mob.horse.skeleton.death", "entity.skeleton_horse.death", SoundCategory.NEUTRAL),
AMBIENT_WEATHER_RAIN("ambient.weather.rain", "weather.rain.above", SoundCategory.WEATHER),
PORTAL_TRIGGER("portal.trigger", "block.portal.trigger", SoundCategory.BLOCK),
RANDOM_CHESTOPEN("random.chestopen", "block.enderchest.open", SoundCategory.BLOCK),
MOB_HORSE_LAND("mob.horse.land", "entity.horse.land", SoundCategory.NEUTRAL),
MOB_SILVERFISH_STEP("mob.silverfish.step", "entity.silverfish.step", SoundCategory.HOSTILE),
MOB_BAT_TAKEOFF("mob.bat.takeoff", "entity.bat.takeoff", SoundCategory.NEUTRAL),
MOB_VILLAGER_NO("mob.villager.no", "entity.villager.no", SoundCategory.NEUTRAL),
GAME_HOSTILE_HURT_FALL_BIG("game.hostile.hurt.fall.big", "entity.hostile.big_fall", SoundCategory.HOSTILE),
MOB_IRONGOLEM_WALK("mob.irongolem.walk", "entity.irongolem.step", SoundCategory.NEUTRAL),
NOTE_HAT("note.hat", "block.note.hat", SoundCategory.RECORD),
MOB_ZOMBIE_METAL("mob.zombie.metal", "entity.zombie.attack_iron_door", SoundCategory.HOSTILE),
MOB_VILLAGER_HAGGLE("mob.villager.haggle", "entity.villager.trading", SoundCategory.NEUTRAL),
MOB_GHAST_FIREBALL("mob.ghast.fireball", "entity.blaze.shoot", SoundCategory.HOSTILE),
MOB_IRONGOLEM_DEATH("mob.irongolem.death", "entity.irongolem.death", SoundCategory.NEUTRAL),
RANDOM_BREAK("random.break", "item.shield.break", SoundCategory.PLAYER),
MOB_ZOMBIE_REMEDY("mob.zombie.remedy", "entity.zombie_villager.cure", SoundCategory.HOSTILE),
RANDOM_BOW("random.bow", "entity.splash_potion.throw", SoundCategory.NEUTRAL),
MOB_VILLAGER_IDLE("mob.villager.idle", "entity.villager.ambient", SoundCategory.NEUTRAL),
STEP_CLOTH("step.cloth", "block.cloth.fall", SoundCategory.NEUTRAL),
MOB_SILVERFISH_HIT("mob.silverfish.hit", "entity.endermite.hurt", SoundCategory.HOSTILE),
LIQUID_LAVA("liquid.lava", "block.lava.ambient", SoundCategory.BLOCK),
GAME_NEUTRAL_HURT_FALL_BIG("game.neutral.hurt.fall.big", "entity.hostile.big_fall", SoundCategory.NEUTRAL),
FIRE_FIRE("fire.fire", "block.fire.ambient", SoundCategory.BLOCK),
MOB_ZOMBIE_WOOD("mob.zombie.wood", "entity.zombie.attack_door_wood", SoundCategory.HOSTILE),
MOB_CHICKEN_STEP("mob.chicken.step", "entity.chicken.step", SoundCategory.NEUTRAL),
MOB_GUARDIAN_LAND_HIT("mob.guardian.land.hit", "entity.guardian.hurt_land", SoundCategory.HOSTILE),
MOB_CHICKEN_PLOP("mob.chicken.plop", "entity.donkey.chest", SoundCategory.NEUTRAL),
MOB_ENDERDRAGON_WINGS("mob.enderdragon.wings", "entity.enderdragon.flap", SoundCategory.HOSTILE),
STEP_GRASS("step.grass", "block.grass.hit", SoundCategory.NEUTRAL),
MOB_HORSE_BREATHE("mob.horse.breathe", "entity.horse.breathe", SoundCategory.NEUTRAL),
GAME_PLAYER_HURT_FALL_BIG("game.player.hurt.fall.big", "entity.hostile.big_fall", SoundCategory.PLAYER),
MOB_HORSE_DONKEY_IDLE("mob.horse.donkey.idle", "entity.donkey.ambient", SoundCategory.NEUTRAL),
MOB_SPIDER_STEP("mob.spider.step", "entity.spider.step", SoundCategory.HOSTILE),
GAME_NEUTRAL_HURT("game.neutral.hurt", "entity.player.death", SoundCategory.NEUTRAL),
MOB_COW_SAY("mob.cow.say", "entity.cow.ambient", SoundCategory.NEUTRAL),
MOB_HORSE_JUMP("mob.horse.jump", "entity.horse.jump", SoundCategory.NEUTRAL),
MOB_HORSE_SOFT("mob.horse.soft", "entity.horse.step", SoundCategory.NEUTRAL),
GAME_NEUTRAL_SWIM_SPLASH("game.neutral.swim.splash", "entity.generic.splash", SoundCategory.NEUTRAL),
MOB_GUARDIAN_HIT("mob.guardian.hit", "entity.guardian.hurt", SoundCategory.HOSTILE),
MOB_ENDERDRAGON_END("mob.enderdragon.end", "entity.enderdragon.death", SoundCategory.HOSTILE),
MOB_ZOMBIE_STEP("mob.zombie.step", "entity.zombie.step", SoundCategory.HOSTILE),
MOB_ENDERDRAGON_GROWL("mob.enderdragon.growl", "entity.enderdragon.growl", SoundCategory.HOSTILE),
MOB_WOLF_SHAKE("mob.wolf.shake", "entity.wolf.shake", SoundCategory.NEUTRAL),
MOB_ENDERMEN_DEATH("mob.endermen.death", "entity.endermen.death", SoundCategory.HOSTILE),
RANDOM_ANVIL_LAND("random.anvil_land", "block.anvil.land", SoundCategory.BLOCK),
GAME_HOSTILE_HURT("game.hostile.hurt", "entity.player.death", SoundCategory.HOSTILE),
MINECART_INSIDE("minecart.inside", "entity.minecart.inside", SoundCategory.PLAYER),
MOB_SLIME_BIG("mob.slime.big", "entity.slime.death", SoundCategory.HOSTILE),
LIQUID_WATER("liquid.water", "block.water.ambient", SoundCategory.BLOCK),
MOB_PIG_SAY("mob.pig.say", "entity.pig.ambient", SoundCategory.NEUTRAL),
MOB_WITHER_SHOOT("mob.wither.shoot", "entity.wither.shoot", SoundCategory.HOSTILE),
ITEM_FIRECHARGE_USE("item.fireCharge.use", "entity.blaze.shoot", SoundCategory.BLOCK),
STEP_SAND("step.sand", "block.sand.fall", SoundCategory.NEUTRAL),
MOB_IRONGOLEM_HIT("mob.irongolem.hit", "entity.irongolem.hurt", SoundCategory.NEUTRAL),
MOB_HORSE_DEATH("mob.horse.death", "entity.horse.death", SoundCategory.NEUTRAL),
MOB_BAT_HURT("mob.bat.hurt", "entity.bat.hurt", SoundCategory.NEUTRAL),
MOB_GHAST_AFFECTIONATE_SCREAM("mob.ghast.affectionate_scream", "entity.ghast.scream", SoundCategory.HOSTILE),
MOB_GUARDIAN_ELDER_IDLE("mob.guardian.elder.idle", "entity.elder_guardian.ambient", SoundCategory.HOSTILE),
MOB_ZOMBIEPIG_ZPIGDEATH("mob.zombiepig.zpigdeath", "entity.zombie_pig.death", SoundCategory.HOSTILE),
AMBIENT_WEATHER_THUNDER("ambient.weather.thunder", "entity.lightning.thunder", SoundCategory.WEATHER),
MINECART_BASE("minecart.base", "entity.minecart.riding", SoundCategory.NEUTRAL),
STEP_LADDER("step.ladder", "block.ladder.hit", SoundCategory.NEUTRAL),
MOB_HORSE_DONKEY_ANGRY("mob.horse.donkey.angry", "entity.donkey.angry", SoundCategory.NEUTRAL),
AMBIENT_CAVE_CAVE("ambient.cave.cave", "ambient.cave", SoundCategory.AMBIENT),
FIREWORKS_BLAST_FAR("fireworks.blast_far", "entity.firework.blast_far", SoundCategory.AMBIENT),
GAME_NEUTRAL_HURT_FALL_SMALL("game.neutral.hurt.fall.small", "entity.generic.small_fall", SoundCategory.NEUTRAL),
GAME_HOSTILE_SWIM_SPLASH("game.hostile.swim.splash", "entity.generic.splash", SoundCategory.HOSTILE),
RANDOM_DRINK("random.drink", "entity.generic.drink", SoundCategory.PLAYER),
GAME_HOSTILE_DIE("game.hostile.die", "entity.player.death", SoundCategory.HOSTILE),
MOB_CAT_HISS("mob.cat.hiss", "entity.cat.hiss", SoundCategory.NEUTRAL),
NOTE_BD("note.bd", "block.note.basedrum", SoundCategory.RECORD),
MOB_SPIDER_SAY("mob.spider.say", "entity.spider.hurt", SoundCategory.HOSTILE),
STEP_STONE("step.stone", "block.anvil.hit", SoundCategory.NEUTRAL),
RANDOM_LEVELUP("random.levelup", "entity.player.levelup", SoundCategory.PLAYER),
LIQUID_LAVAPOP("liquid.lavapop", "block.lava.pop", SoundCategory.BLOCK),
MOB_SHEEP_SAY("mob.sheep.say", "entity.sheep.ambient", SoundCategory.NEUTRAL),
MOB_SKELETON_SAY("mob.skeleton.say", "entity.skeleton.ambient", SoundCategory.HOSTILE),
MOB_BLAZE_BREATHE("mob.blaze.breathe", "entity.blaze.ambient", SoundCategory.HOSTILE),
MOB_BAT_IDLE("mob.bat.idle", "entity.bat.ambient", SoundCategory.NEUTRAL),
MOB_MAGMACUBE_BIG("mob.magmacube.big", "entity.magmacube.squish", SoundCategory.HOSTILE),
MOB_HORSE_IDLE("mob.horse.idle", "entity.horse.ambient", SoundCategory.NEUTRAL),
GAME_HOSTILE_HURT_FALL_SMALL("game.hostile.hurt.fall.small", "entity.generic.small_fall", SoundCategory.HOSTILE),
MOB_HORSE_ZOMBIE_HIT("mob.horse.zombie.hit", "entity.zombie_horse.hurt", SoundCategory.NEUTRAL),
MOB_IRONGOLEM_THROW("mob.irongolem.throw", "entity.irongolem.attack", SoundCategory.NEUTRAL),
DIG_CLOTH("dig.cloth", "block.cloth.place", SoundCategory.BLOCK),
STEP_GRAVEL("step.gravel", "block.gravel.hit", SoundCategory.NEUTRAL),
MOB_SILVERFISH_SAY("mob.silverfish.say", "entity.silverfish.ambient", SoundCategory.HOSTILE),
MOB_CAT_PURR("mob.cat.purr", "entity.cat.purr", SoundCategory.NEUTRAL),
MOB_ZOMBIE_INFECT("mob.zombie.infect", "entity.zombie.infect", SoundCategory.HOSTILE),
RANDOM_EAT("random.eat", "entity.generic.eat", SoundCategory.PLAYER),
MOB_WOLF_BARK("mob.wolf.bark", "entity.wolf.ambient", SoundCategory.NEUTRAL),
GAME_TNT_PRIMED("game.tnt.primed", "entity.creeper.primed", SoundCategory.BLOCK),
MOB_SHEEP_STEP("mob.sheep.step", "entity.sheep.step", SoundCategory.NEUTRAL),
MOB_ZOMBIE_DEATH("mob.zombie.death", "entity.zombie.death", SoundCategory.HOSTILE),
RANDOM_DOOR_OPEN("random.door_open", "null", SoundCategory.BLOCK),
MOB_ENDERMEN_PORTAL("mob.endermen.portal", "entity.endermen.teleport", SoundCategory.HOSTILE),
MOB_HORSE_ANGRY("mob.horse.angry", "entity.horse.angry", SoundCategory.NEUTRAL),
MOB_WOLF_GROWL("mob.wolf.growl", "entity.wolf.growl", SoundCategory.NEUTRAL),
DIG_SNOW("dig.snow", "block.snow.place", SoundCategory.BLOCK),
TILE_PISTON_OUT("tile.piston.out", "block.piston.extend", SoundCategory.BLOCK),
RANDOM_BURP("random.burp", "entity.player.burp", SoundCategory.PLAYER),
MOB_COW_STEP("mob.cow.step", "entity.cow.step", SoundCategory.NEUTRAL),
MOB_WITHER_HURT("mob.wither.hurt", "entity.wither.hurt", SoundCategory.HOSTILE),
MOB_GUARDIAN_LAND_DEATH("mob.guardian.land.death", "entity.elder_guardian.death_land", SoundCategory.HOSTILE),
MOB_CHICKEN_HURT("mob.chicken.hurt", "entity.chicken.death", SoundCategory.NEUTRAL),
MOB_WOLF_STEP("mob.wolf.step", "entity.wolf.step", SoundCategory.NEUTRAL),
MOB_WOLF_DEATH("mob.wolf.death", "entity.wolf.death", SoundCategory.NEUTRAL),
MOB_WOLF_WHINE("mob.wolf.whine", "entity.wolf.whine", SoundCategory.NEUTRAL),
NOTE_PLING("note.pling", "block.note.pling", SoundCategory.RECORD),
GAME_PLAYER_HURT_FALL_SMALL("game.player.hurt.fall.small", "entity.generic.small_fall", SoundCategory.PLAYER),
MOB_CAT_PURREOW("mob.cat.purreow", "entity.cat.purreow", SoundCategory.NEUTRAL),
FIREWORKS_LARGEBLAST_FAR("fireworks.largeBlast_far", "entity.firework.large_blast_far", SoundCategory.AMBIENT),
MOB_SKELETON_HURT("mob.skeleton.hurt", "entity.skeleton.hurt", SoundCategory.HOSTILE),
MOB_SPIDER_DEATH("mob.spider.death", "entity.spider.death", SoundCategory.HOSTILE),
RANDOM_ANVIL_BREAK("random.anvil_break", "block.anvil.destroy", SoundCategory.BLOCK),
MOB_WITHER_IDLE("mob.wither.idle", "entity.wither.ambient", SoundCategory.HOSTILE),
MOB_GUARDIAN_ELDER_HIT("mob.guardian.elder.hit", "entity.elder_guardian.hurt", SoundCategory.HOSTILE),
MOB_ENDERMEN_SCREAM("mob.endermen.scream", "entity.endermen.scream", SoundCategory.HOSTILE),
MOB_CAT_HITT("mob.cat.hitt", "entity.cat.hurt", SoundCategory.NEUTRAL),
MOB_MAGMACUBE_SMALL("mob.magmacube.small", "entity.small_magmacube.squish", SoundCategory.HOSTILE),
FIRE_IGNITE("fire.ignite", "item.flintandsteel.use", SoundCategory.BLOCK, true),
MOB_ENDERDRAGON_HIT("mob.enderdragon.hit", "entity.enderdragon.hurt", SoundCategory.HOSTILE),
MOB_ZOMBIE_HURT("mob.zombie.hurt", "entity.zombie_villager.hurt", SoundCategory.HOSTILE),
RANDOM_EXPLODE("random.explode", "block.end_gateway.spawn", SoundCategory.BLOCK),
MOB_SLIME_ATTACK("mob.slime.attack", "entity.slime.attack", SoundCategory.HOSTILE),
MOB_MAGMACUBE_JUMP("mob.magmacube.jump", "entity.magmacube.jump", SoundCategory.HOSTILE),
RANDOM_SPLASH("random.splash", "entity.bobber.splash", SoundCategory.PLAYER),
MOB_HORSE_SKELETON_HIT("mob.horse.skeleton.hit", "entity.skeleton_horse.hurt", SoundCategory.NEUTRAL),
MOB_GHAST_MOAN("mob.ghast.moan", "entity.ghast.ambient", SoundCategory.HOSTILE),
MOB_GUARDIAN_CURSE("mob.guardian.curse", "entity.elder_guardian.curse", SoundCategory.HOSTILE),
GAME_POTION_SMASH("game.potion.smash", "block.glass.break", SoundCategory.NEUTRAL),
NOTE_BASSATTACK("note.bassattack", "block.note.bass", SoundCategory.RECORD),
GUI_BUTTON_PRESS("gui.button.press", "block.wood_pressureplate.click_on", SoundCategory.MASTER),
RANDOM_ORB("random.orb", "entity.experience_orb.pickup", SoundCategory.PLAYER),
MOB_ZOMBIE_WOODBREAK("mob.zombie.woodbreak", "entity.zombie.break_door_wood", SoundCategory.HOSTILE),
MOB_HORSE_ARMOR("mob.horse.armor", "entity.horse.armor", SoundCategory.NEUTRAL),
TILE_PISTON_IN("tile.piston.in", "block.piston.contract", SoundCategory.BLOCK),
MOB_CAT_MEOW("mob.cat.meow", "entity.cat.ambient", SoundCategory.NEUTRAL),
MOB_PIG_STEP("mob.pig.step", "entity.pig.step", SoundCategory.NEUTRAL),
STEP_WOOD("step.wood", "block.wood.step", SoundCategory.NEUTRAL),
PORTAL_TRAVEL("portal.travel", "block.portal.travel", SoundCategory.PLAYER),
MOB_GUARDIAN_DEATH("mob.guardian.death", "entity.guardian.death", SoundCategory.HOSTILE),
MOB_SKELETON_DEATH("mob.skeleton.death", "entity.skeleton.death", SoundCategory.HOSTILE),
MOB_HORSE_HIT("mob.horse.hit", "entity.horse.hurt", SoundCategory.NEUTRAL),
MOB_VILLAGER_HIT("mob.villager.hit", "entity.villager.hurt", SoundCategory.NEUTRAL),
MOB_HORSE_SKELETON_IDLE("mob.horse.skeleton.idle", "entity.skeleton_horse.ambient", SoundCategory.NEUTRAL),
RECORDS_CHIRP("records.chirp", "record.chirp", SoundCategory.RECORD),
MOB_RABBIT_HURT("mob.rabbit.hurt", "entity.rabbit.hurt", SoundCategory.NEUTRAL),
RECORDS_STAL("records.stal", "record.stal", SoundCategory.RECORD),
MUSIC_GAME_NETHER("music.game.nether", "music.nether", SoundCategory.MUSIC),
MUSIC_MENU("music.menu", "music.menu", SoundCategory.MUSIC),
RECORDS_MELLOHI("records.mellohi", "record.mellohi", SoundCategory.RECORD),
RECORDS_CAT("records.cat", "record.cat", SoundCategory.RECORD),
RECORDS_FAR("records.far", "record.far", SoundCategory.RECORD),
MUSIC_GAME_END_DRAGON("music.game.end.dragon", "music.dragon", SoundCategory.MUSIC),
MOB_RABBIT_DEATH("mob.rabbit.death", "entity.rabbit.death", SoundCategory.NEUTRAL),
MOB_RABBIT_IDLE("mob.rabbit.idle", "entity.rabbit.ambient", SoundCategory.NEUTRAL),
MUSIC_GAME_END("music.game.end", "music.end", SoundCategory.MUSIC),
MUSIC_GAME("music.game", "music.game", SoundCategory.MUSIC),
MOB_GUARDIAN_IDLE("mob.guardian.idle", "null", SoundCategory.HOSTILE),
RECORDS_WARD("records.ward", "record.ward", SoundCategory.RECORD),
RECORDS_13("records.13", "record.13", SoundCategory.RECORD),
MOB_RABBIT_HOP("mob.rabbit.hop", "entity.rabbit.jump", SoundCategory.NEUTRAL),
RECORDS_STRAD("records.strad", "record.strad", SoundCategory.RECORD),
RECORDS_11("records.11", "record.11", SoundCategory.RECORD),
RECORDS_MALL("records.mall", "record.mall", SoundCategory.RECORD),
RECORDS_BLOCKS("records.blocks", "record.blocks", SoundCategory.RECORD),
RECORDS_WAIT("records.wait", "record.wait", SoundCategory.RECORD),
MUSIC_GAME_END_CREDITS("music.game.end.credits", "music.credits", SoundCategory.MUSIC),
MUSIC_GAME_CREATIVE("music.game.creative", "music.creative", SoundCategory.MUSIC);
private final String name;
private final String newName;
private final SoundCategory category;
private final boolean breaksound;
SoundEffect(String name, String newname, SoundCategory cat) {
this.category = cat;
this.newName = newname;
this.name = name;
this.breaksound = name.startsWith("dig.");
}
SoundEffect(String name, String newname, SoundCategory cat, boolean shouldIgnore) {
this.category = cat;
this.newName = newname;
this.name = name;
this.breaksound = name.startsWith("dig.") || shouldIgnore;
}
public static SoundEffect getByName(String name) {
name = name.toLowerCase();
for (SoundEffect e : SoundEffect.values()) {
if (e.getName().equals(name))
return e;
}
return null;
}
}
@@ -1,25 +1,27 @@
package us.myles.ViaVersion.transformers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.buffer.Unpooled;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import us.myles.ViaVersion.*;
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.packets.PacketType;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.slot.ItemSlotRewriter;
import us.myles.ViaVersion.util.PacketUtil;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.io.IOException;
public class IncomingTransformer {
private final Channel channel;
private final ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
private final ConnectionInfo info;
private final ViaVersionInitializer init;
private boolean startedBlocking = false;
public IncomingTransformer(Channel channel, ConnectionInfo info, ViaVersionInitializer init) {
this.channel = channel;
public IncomingTransformer(ConnectionInfo info) {
this.info = info;
this.init = init;
}
public void transform(int packetID, ByteBuf input, ByteBuf output) throws CancelException {
@@ -33,10 +35,12 @@ public class IncomingTransformer {
if (packet.getPacketID() != -1) {
packetID = packet.getPacketID();
}
// if (packet != PacketType.PLAY_PLAYER_POSITION_LOOK_REQUEST && packet != PacketType.PLAY_KEEP_ALIVE_REQUEST && packet != PacketType.PLAY_PLAYER_POSITION_REQUEST && packet != PacketType.PLAY_PLAYER_LOOK_REQUEST) {
// System.out.println("Packet Type: " + packet + " New ID: " + packetID + " Original: " + original);
// }
if (packet == PacketType.PLAY_TP_CONFIRM) {
if (plugin.isDebug()) {
if (packet != PacketType.PLAY_PLAYER_POSITION_LOOK_REQUEST && packet != PacketType.PLAY_KEEP_ALIVE_REQUEST && packet != PacketType.PLAY_PLAYER_POSITION_REQUEST && packet != PacketType.PLAY_PLAYER_LOOK_REQUEST) {
System.out.println("Direction " + packet.getDirection().name() + " Packet Type: " + packet + " New ID: " + packetID + " Original: " + original + " Size: " + input.readableBytes());
}
}
if (packet == PacketType.PLAY_TP_CONFIRM || packet == PacketType.PLAY_VEHICLE_MOVE_REQUEST) { //TODO handle client-sided horse riding
throw new CancelException();
}
PacketUtil.writeVarInt(packetID, output);
@@ -46,8 +50,8 @@ public class IncomingTransformer {
PacketUtil.writeVarInt(protVer <= 102 ? protVer : 47, output); // pretend to be older
if (protVer <= 102) {
// Not 1.9 remove pipes
this.init.remove();
// not 1.9, remove pipes
info.setActive(false);
}
String serverAddress = PacketUtil.readString(input);
PacketUtil.writeString(serverAddress, output);
@@ -71,7 +75,7 @@ public class IncomingTransformer {
output.writeLong(location);
for (int i = 0; i < 4; i++) {
String line = PacketUtil.readString(input);
line = "{\"text\":\"" + line + "\"}";
line = OutgoingTransformer.fixJson(line);
PacketUtil.writeString(line, output);
}
return;
@@ -84,18 +88,31 @@ public class IncomingTransformer {
return;
}
if (packet == PacketType.PLAY_PLAYER_DIGGING) {
byte status = input.readByte();
int status = input.readByte() & 0xFF; // unsign
if (status == 5 && startedBlocking) {
// stopped blocking
startedBlocking = false;
sendSecondHandItem(null);
}
if (status == 6) { // item swap
throw new CancelException();
}
output.writeByte(status);
// read position
Long pos = input.readLong();
output.writeLong(pos);
short face = input.readUnsignedByte();
// write remaining bytes
Long position = input.readLong();
output.writeLong(position);
int face = input.readUnsignedByte();
output.writeByte(face);
return;
}
if (packet == PacketType.PLAY_HELD_ITEM_CHANGE_REQUEST) {
if (startedBlocking) {
// stopped blocking
startedBlocking = false;
sendSecondHandItem(null);
}
}
if (packet == PacketType.PLAY_CLICK_WINDOW) {
// if placed in new slot, reject :)
int windowID = input.readUnsignedByte();
@@ -103,32 +120,44 @@ public class IncomingTransformer {
byte button = input.readByte();
short action = input.readShort();
byte mode = input.readByte();
if (slot == 45 && windowID == 0) {
try {
Class<?> setSlot = ReflectionUtil.nms("PacketPlayOutSetSlot");
Object setSlotPacket = setSlot.getConstructors()[1].newInstance(windowID, slot, null);
channel.writeAndFlush(setSlotPacket); // slot is empty
slot = -999; // we're evil, they'll throw item on the ground
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
int mode = input.readByte();
// if the action is on an elytra armour slot
boolean throwItem = (slot == 45 && windowID == 0);
if (info.getOpenWindow() != null && windowID > 0) {
if (info.getOpenWindow().equals("minecraft:brewing_stand")) {
if (slot == 4) {
// throw
throwItem = true;
}
if (slot > 4)
slot = (short) (slot - 1);
}
}
if (throwItem) {
ByteBuf buf = info.getChannel().alloc().buffer();
PacketUtil.writeVarInt(PacketType.PLAY_SET_SLOT.getNewPacketID(), buf);
buf.writeByte(windowID);
buf.writeShort(slot);
buf.writeShort(-1); // empty
info.sendRawPacket(buf);
// Continue the packet simulating throw
mode = 0;
button = 0;
slot = -999;
}
output.writeByte(windowID);
output.writeShort(slot);
output.writeByte(button);
output.writeShort(action);
output.writeByte(mode);
output.writeBytes(input);
ItemSlotRewriter.rewrite1_9To1_8(input, output);
return;
}
if (packet == PacketType.PLAY_CLOSE_WINDOW_REQUEST) {
info.closeWindow();
}
if (packet == PacketType.PLAY_CLIENT_SETTINGS) {
String locale = PacketUtil.readString(input);
PacketUtil.writeString(locale, output);
@@ -152,6 +181,19 @@ public class IncomingTransformer {
PacketUtil.readVarInt(input);
return;
}
if (packet == PacketType.PLAY_ENTITY_ACTION) {
int playerId = PacketUtil.readVarInt(input);
int action = PacketUtil.readVarInt(input);
int jump = PacketUtil.readVarInt(input);
if (action == 6 || action == 8) //Ignore stop jumping / start elytra flying
throw new CancelException();
if (action == 7) //Change open horse inventory to the 1.8 value
action = 6;
PacketUtil.writeVarInt(playerId, output);
PacketUtil.writeVarInt(action, output);
PacketUtil.writeVarInt(jump, output);
return;
}
if (packet == PacketType.PLAY_USE_ENTITY) {
int target = PacketUtil.readVarInt(input);
PacketUtil.writeVarInt(target, output);
@@ -171,52 +213,135 @@ public class IncomingTransformer {
}
return;
}
if (packet == PacketType.PLAY_PLUGIN_MESSAGE_REQUEST) {
String name = PacketUtil.readString(input);
PacketUtil.writeString(name, output);
byte[] b = new byte[input.readableBytes()];
input.readBytes(b);
// patch books
switch (name) {
case "MC|BSign": {
ByteBuf in = Unpooled.wrappedBuffer(b);
try {
ItemSlotRewriter.ItemStack stack = ItemSlotRewriter.readItemStack(in);
if (stack != null)
stack.id = (short) Material.WRITTEN_BOOK.getId();
// write
ItemSlotRewriter.writeItemStack(stack, output);
} catch (IOException e) {
e.printStackTrace();
}
return;
}
case "MC|AutoCmd": {
ByteBuf in = Unpooled.wrappedBuffer(b);
int x = in.readInt();
int y = in.readInt();
int z = in.readInt();
String command = PacketUtil.readString(in);
boolean flag = in.readBoolean();
output.clear();
PacketUtil.writeVarInt(PacketType.PLAY_PLUGIN_MESSAGE_REQUEST.getPacketID(), output);
PacketUtil.writeString("MC|AdvCdm", output);
output.writeByte(0);
output.writeInt(x);
output.writeInt(y);
output.writeInt(z);
PacketUtil.writeString(command, output);
output.writeBoolean(flag);
return;
}
case "MC|AdvCmd":
output.clear();
PacketUtil.writeVarInt(PacketType.PLAY_PLUGIN_MESSAGE_REQUEST.getPacketID(), output);
PacketUtil.writeString("MC|AdvCdm", output);
output.writeBytes(b);
break;
}
output.writeBytes(b);
}
if (packet == PacketType.PLAY_PLAYER_BLOCK_PLACEMENT) {
Long position = input.readLong();
output.writeLong(position);
int face = PacketUtil.readVarInt(input);
output.writeByte(face);
int hand = PacketUtil.readVarInt(input);
PacketUtil.readVarInt(input);
ItemStack inHand = Core.getHandItem(info);
Object item = null;
ItemStack inHand = plugin.getHandItem(info);
try {
Method m = ReflectionUtil.obc("inventory.CraftItemStack").getDeclaredMethod("asNMSCopy", ItemStack.class);
item = m.invoke(null, inHand);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
ItemSlotRewriter.ItemStack item = ItemSlotRewriter.ItemStack.fromBukkit(inHand);
ItemSlotRewriter.fixIdsFrom1_9To1_8(item);
ItemSlotRewriter.writeItemStack(item, output);
} catch (Exception e) {
e.printStackTrace();
}
PacketUtil.writeItem(item, output);
short curX = input.readUnsignedByte();
output.writeByte(curX);
short curY = input.readUnsignedByte();
output.writeByte(curY);
short curZ = input.readUnsignedByte();
output.writeByte(curZ);
return;
short curX = input.readUnsignedByte();
output.writeByte(curX);
short curY = input.readUnsignedByte();
output.writeByte(curY);
short curZ = input.readUnsignedByte();
output.writeByte(curZ);
return;
}
if (packet == PacketType.PLAY_USE_ITEM) {
int hand = PacketUtil.readVarInt(input);
output.clear();
PacketUtil.writeVarInt(PacketType.PLAY_PLAYER_BLOCK_PLACEMENT.getPacketID(), output);
// Simulate using item :)
output.writeLong(-1L);
output.writeByte(-1);
output.writeByte(255);
// write item in hand
output.writeShort(-1);
ItemStack inHand = plugin.getHandItem(info);
if (inHand != null && plugin.isShieldBlocking()) {
if (inHand.getType().name().endsWith("SWORD")) {
// blocking?
if (hand == 0) {
if (!startedBlocking) {
startedBlocking = true;
ItemSlotRewriter.ItemStack shield = new ItemSlotRewriter.ItemStack();
shield.id = 442;
shield.amount = 1;
shield.data = 0;
sendSecondHandItem(shield);
}
throw new CancelException();
}
}
}
try {
ItemSlotRewriter.ItemStack item = ItemSlotRewriter.ItemStack.fromBukkit(inHand);
ItemSlotRewriter.fixIdsFrom1_9To1_8(item);
ItemSlotRewriter.writeItemStack(item, output);
} catch (Exception e) {
e.printStackTrace();
}
output.writeByte(-1);
output.writeByte(-1);
output.writeByte(-1);
output.writeByte(0); //Is zero in 1.8, not -1
output.writeByte(0);
output.writeByte(0);
return;
}
if (packet == PacketType.PLAY_CREATIVE_INVENTORY_ACTION) {
short slot = input.readShort();
output.writeShort(slot);
ItemSlotRewriter.rewrite1_9To1_8(input, output);
}
output.writeBytes(input);
}
private void sendSecondHandItem(ItemSlotRewriter.ItemStack o) {
ByteBuf buf = info.getChannel().alloc().buffer();
PacketUtil.writeVarInt(PacketType.PLAY_ENTITY_EQUIPMENT.getNewPacketID(), buf);
PacketUtil.writeVarInt(info.getEntityID(), buf);
PacketUtil.writeVarInt(1, buf); // slot
// write shield
try {
ItemSlotRewriter.writeItemStack(o, buf);
} catch (IOException e) {
e.printStackTrace();
}
info.sendRawPacket(buf);
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,22 @@
package us.myles.ViaVersion.update;
import lombok.RequiredArgsConstructor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.Plugin;
@RequiredArgsConstructor
public class UpdateListener implements Listener {
private final Plugin plugin;
@EventHandler
public void onJoin(PlayerJoinEvent e) {
if(e.getPlayer().hasPermission("viaversion.update")
&& plugin.getConfig().getBoolean("checkforupdates", true)) {
UpdateUtil.sendUpdateMessage(e.getPlayer().getUniqueId(), plugin);
}
}
}
@@ -0,0 +1,125 @@
package us.myles.ViaVersion.update;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import us.myles.ViaVersion.api.ViaVersion;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;
public class UpdateUtil {
private final static String URL = "http://api.spiget.org/v1/resources/";
private final static int PLUGIN = 19254;
public final static String PREFIX = ChatColor.GREEN + "" + ChatColor.BOLD + "[ViaVersion] " + ChatColor.GREEN;
public static void sendUpdateMessage(final UUID uuid, final Plugin plugin) {
new BukkitRunnable() {
@Override
public void run() {
final String message = getUpdateMessage(false);
if (message != null) {
new BukkitRunnable() {
@Override
public void run() {
Player p = Bukkit.getPlayer(uuid);
if (p != null) {
p.sendMessage(PREFIX + message);
}
}
}.runTask(plugin);
}
}
}.runTaskAsynchronously(plugin);
}
public static void sendUpdateMessage(final Plugin plugin) {
new BukkitRunnable() {
@Override
public void run() {
final String message = getUpdateMessage(true);
if (message != null) {
new BukkitRunnable() {
@Override
public void run() {
plugin.getLogger().warning(message);
}
}.runTask(plugin);
}
}
}.runTaskAsynchronously(plugin);
}
private static String getUpdateMessage(boolean console) {
if (ViaVersion.getInstance().getVersion().equals("${project.version}")) {
return "You are using a debug/custom version, consider updating.";
}
String newestString = getNewestVersion();
if (newestString == null) {
if (console) {
return "Could not check for updates, check your connection.";
} else {
return null;
}
}
Version current;
try {
current = new Version(ViaVersion.getInstance().getVersion());
} catch (IllegalArgumentException e) {
return "You are using a debug/custom version, consider updating.";
}
Version newest = new Version(newestString);
if (current.compareTo(newest) < 0)
return "There is a newer version available: " + newest.toString();
else if (console && current.compareTo(newest) != 0) {
return "You are running a newer version than is released!";
}
return null;
}
private static String getNewestVersion() {
try {
URL url = new URL(URL + PLUGIN + "?" + System.currentTimeMillis());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(true);
connection.addRequestProperty("User-Agent", "ViaVersion " + ViaVersion.getInstance().getVersion());
connection.setDoOutput(true);
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String input;
String content = "";
while ((input = br.readLine()) != null) {
content = content + input;
}
br.close();
JSONParser parser = new JSONParser();
JSONObject statistics;
try {
statistics = (JSONObject) parser.parse(content);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
return (String) statistics.get("version");
} catch (MalformedURLException e) {
return null;
} catch (IOException e) {
return null;
}
}
}
@@ -0,0 +1,62 @@
package us.myles.ViaVersion.update;
import org.apache.commons.lang.StringUtils;
public class Version implements Comparable<Version> {
private int[] parts;
public Version(String value) {
if (value == null)
throw new IllegalArgumentException("Version can not be null");
if (!value.matches("^[0-9]+(\\.[0-9]+)*$"))
throw new IllegalArgumentException("Invalid version format");
String[] split = value.split("\\.");
parts = new int[split.length];
for (int i = 0; i < split.length; i += 1)
parts[i] = Integer.parseInt(split[i]);
}
public static int compare(Version verA, Version verB) {
if (verA == verB) return 0;
if (verA == null) return -1;
if (verB == null) return 1;
int max = Math.max(verA.parts.length, verB.parts.length);
for (int i = 0; i < max; i += 1) {
int partA = i < verA.parts.length ? verA.parts[i] : 0;
int partB = i < verB.parts.length ? verB.parts[i] : 0;
if (partA < partB) return -1;
if (partA > partB) return 1;
}
return 0;
}
public static boolean equals(Version verA, Version verB) {
return verA == verB || verA != null && verB != null && compare(verA, verB) == 0;
}
@Override
public String toString() {
String[] split = new String[parts.length];
for (int i = 0; i < parts.length; i += 1)
split[i] = String.valueOf(parts[i]);
return StringUtils.join(split, ".");
}
@Override
public int compareTo(Version that) {
return compare(this, that);
}
@Override
public boolean equals(Object that) {
return that instanceof Version && equals(this, (Version) that);
}
}
@@ -0,0 +1,92 @@
package us.myles.ViaVersion.util;
import org.bukkit.entity.EntityType;
public class EntityUtil {
public static EntityType getTypeFromID(int typeID, boolean isObject) {
if (isObject) {
return getObjectFromID(typeID);
} else {
return EntityType.fromId(typeID);
}
}
// based on http://wiki.vg/index.php?title=Entities
public static EntityType getObjectFromID(int objectID) {
EntityType type;
switch (objectID) {
case 2:
type = EntityType.DROPPED_ITEM;
break;
case 77:
type = EntityType.LEASH_HITCH;
break;
case 60:
type = EntityType.ARROW;
break;
case 61:
type = EntityType.SNOWBALL;
break;
case 63:
type = EntityType.FIREBALL;
break;
case 64:
type = EntityType.SMALL_FIREBALL;
break;
case 65:
type = EntityType.ENDER_PEARL;
break;
case 72:
type = EntityType.ENDER_SIGNAL;
break;
case 75:
type = EntityType.THROWN_EXP_BOTTLE;
break;
case 71:
type = EntityType.ITEM_FRAME;
break;
case 66:
type = EntityType.WITHER_SKULL;
break;
case 50:
type = EntityType.PRIMED_TNT;
break;
case 70:
type = EntityType.FALLING_BLOCK;
break;
case 76:
type = EntityType.FIREWORK;
break;
case 78:
type = EntityType.ARMOR_STAND;
break;
case 1:
type = EntityType.BOAT;
break;
case 10:
type = EntityType.MINECART;
break;
case 51:
type = EntityType.ENDER_CRYSTAL;
break;
case 73:
type = EntityType.SPLASH_POTION;
break;
case 62:
type = EntityType.EGG;
break;
case 90:
type = EntityType.FISHING_HOOK;
break;
default:
type = EntityType.fromId(objectID);
if (type == null) {
System.out.println("Unable to find entity type for " + objectID);
type = EntityType.UNKNOWN;
}
break;
}
return type;
}
}
@@ -0,0 +1,138 @@
package us.myles.ViaVersion.util;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public abstract class ListWrapper implements List {
private final List list;
public ListWrapper(List inputList) {
this.list = inputList;
}
public abstract void handleAdd(Object o);
@Override
public synchronized int size() {
return this.list.size();
}
@Override
public synchronized boolean isEmpty() {
return this.list.isEmpty();
}
@Override
public synchronized boolean contains(Object o) {
return this.list.contains(o);
}
@Override
public synchronized Iterator iterator() {
return this.list.iterator();
}
@Override
public synchronized Object[] toArray() {
return this.list.toArray();
}
@Override
public synchronized boolean add(Object o) {
handleAdd(o);
return this.list.add(o);
}
@Override
public synchronized boolean remove(Object o) {
return this.list.remove(o);
}
@Override
public synchronized boolean addAll(Collection c) {
for (Object o : c) {
handleAdd(o);
}
return this.list.addAll(c);
}
@Override
public synchronized boolean addAll(int index, Collection c) {
for (Object o : c) {
handleAdd(o);
}
return this.list.addAll(index, c);
}
@Override
public synchronized void clear() {
this.list.clear();
}
@Override
public synchronized Object get(int index) {
return this.list.get(index);
}
@Override
public synchronized Object set(int index, Object element) {
return this.list.set(index, element);
}
@Override
public synchronized void add(int index, Object element) {
this.list.add(index, element);
}
@Override
public synchronized Object remove(int index) {
return this.list.remove(index);
}
@Override
public synchronized int indexOf(Object o) {
return this.list.indexOf(o);
}
@Override
public synchronized int lastIndexOf(Object o) {
return this.list.lastIndexOf(o);
}
@Override
public synchronized ListIterator listIterator() {
return this.list.listIterator();
}
@Override
public synchronized ListIterator listIterator(int index) {
return this.list.listIterator(index);
}
@Override
public synchronized List subList(int fromIndex, int toIndex) {
return this.list.subList(fromIndex, toIndex);
}
@Override
public synchronized boolean retainAll(Collection c) {
return this.list.retainAll(c);
}
@Override
public synchronized boolean removeAll(Collection c) {
return this.list.removeAll(c);
}
@Override
public synchronized boolean containsAll(Collection c) {
return this.list.containsAll(c);
}
@Override
public synchronized Object[] toArray(Object[] a) {
return this.list.toArray(a);
}
}
@@ -1,23 +1,22 @@
package us.myles.ViaVersion;
package us.myles.ViaVersion.util;
import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import us.myles.ViaVersion.chunks.MagicBitSet;
import us.myles.ViaVersion.chunks.PacketChunk;
import us.myles.ViaVersion.chunks.PacketChunkData;
import org.spacehq.opennbt.NBTIO;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.UUID;
@@ -42,29 +41,64 @@ public class PacketUtil {
}
}
public static ByteBuf decompress(ChannelHandlerContext ctx, ByteBuf msg) {
ByteToMessageDecoder x = (ByteToMessageDecoder) ctx.pipeline().get("decompress");
List<Object> output = new ArrayList<Object>();
public static CompoundTag readNBT(ByteBuf input) throws IOException {
int readerIndex = input.readerIndex();
byte b = input.readByte();
if (b == 0) {
return null;
} else {
input.readerIndex(readerIndex);
ByteBufInputStream bytebufStream = new ByteBufInputStream(input);
DataInputStream dataInputStream = new DataInputStream(bytebufStream);
try {
return (CompoundTag) NBTIO.readTag(dataInputStream);
} finally {
dataInputStream.close();
}
}
}
public static void writeNBT(ByteBuf output, CompoundTag tag) throws IOException {
if (tag == null) {
output.writeByte(0);
} else {
ByteBufOutputStream bytebufStream = new ByteBufOutputStream(output);
DataOutputStream dataOutputStream = new DataOutputStream(bytebufStream);
NBTIO.writeTag(dataOutputStream, tag);
dataOutputStream.close();
}
}
public static List<Object> callDecode(ByteToMessageDecoder decoder, ChannelHandlerContext ctx, Object input) {
List<Object> output = new ArrayList<>();
try {
PacketUtil.DECODE_METHOD.invoke(x, ctx, msg, output);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
PacketUtil.DECODE_METHOD.invoke(decoder, ctx, input, output);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return output;
}
public static void callEncode(MessageToByteEncoder encoder, ChannelHandlerContext ctx, Object msg, ByteBuf output) {
try {
PacketUtil.ENCODE_METHOD.invoke(encoder, ctx, msg, output);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
public static ByteBuf decompress(ChannelHandlerContext ctx, ByteBuf msg) {
ByteToMessageDecoder x = (ByteToMessageDecoder) ctx.pipeline().get("decompress");
List<Object> output = callDecode(x, ctx, msg);
return output.size() == 0 ? null : (ByteBuf) output.get(0);
}
public static ByteBuf compress(ChannelHandlerContext ctx, ByteBuf msg) {
MessageToByteEncoder x = (MessageToByteEncoder) ctx.pipeline().get("compress");
ByteBuf output = ctx.alloc().buffer();
try {
PacketUtil.ENCODE_METHOD.invoke(x, ctx, msg, output);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
callEncode(x, ctx, msg, output);
return output;
}
@@ -134,7 +168,7 @@ public class PacketUtil {
public static List<String> readStringArray(ByteBuf buf) {
int len = readVarInt(buf);
List<String> ret = new ArrayList<String>(len);
List<String> ret = new ArrayList<>(len);
for (int i = 0; i < len; i++) {
ret.add(readString(buf));
}
@@ -184,6 +218,13 @@ public class PacketUtil {
}
}
public static void writeVarIntArray(List<Integer> integers, ByteBuf output) {
writeVarInt(integers.size(), output);
for (Integer i : integers) {
writeVarInt(i, output);
}
}
public static int readVarShort(ByteBuf buf) {
int low = buf.readUnsignedShort();
int high = 0;
@@ -216,8 +257,8 @@ public class PacketUtil {
}
public static void writeLongs(long[] data, ByteBuf output) {
for (int index = 0; index < data.length; index++) {
output.writeLong(data[index]);
for (long aData : data) {
output.writeLong(aData);
}
}
@@ -230,130 +271,34 @@ public class PacketUtil {
return data;
}
// This method is based on one from here
// https://github.com/Steveice10/MCProtocolLib/blob/master/src/main/java/org/spacehq/mc/protocol/util/NetUtil.java
public static PacketChunk readChunkData(boolean isFullChunk, int bitmask, byte[] input) {
PacketChunkData[] chunks = new PacketChunkData[16];
boolean sky = false;
int expected = 0;
int position = 0;
ShortBuffer blockData = ByteBuffer.wrap(input).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
for (int i = 0; i < chunks.length; i++) {
if ((bitmask & 1 << i) != 0) {
expected += (4096 * 2) + 2048;
}
}
// If there is more data, then there must be skylights :D
if (input.length > expected) {
sky = true;
}
// Read block data
for (int i = 0; i < chunks.length; i++) {
if ((bitmask & 1 << i) != 0) {
chunks[i] = new PacketChunkData(sky);
blockData.position(position / 2);
blockData.get(chunks[i].getBlocks(), 0, 4096);
position = position + (4096 * 2);
} else {
chunks[i] = new PacketChunkData(sky);
}
}
// Read blocklight data
for (int i = 0; i < chunks.length; i++) {
if ((bitmask & 1 << i) != 0) {
System.arraycopy(input, position, chunks[i].getBlockLight(), 0, 2048);
position = position + 2048;
}
}
// Read skylight data
if (sky) {
for (int i = 0; i < chunks.length; i++) {
if ((bitmask & 1 << i) != 0) {
System.arraycopy(input, position, chunks[i].getSkyLight(), 0, 2048);
position = position + 2048;
}
}
}
byte[] biomeData = null;
if (isFullChunk) {
// yay im a full chunk meaning i know my biomes, mommy get the camera!
biomeData = new byte[256];
System.arraycopy(input, position, biomeData, 0, 256);
}
return new PacketChunk(chunks, biomeData);
public static long[] readBlockPosition(ByteBuf buf) {
long val = buf.readLong();
long x = (val >> 38); // signed
long y = (val >> 26) & 0xfff; // unsigned
// this shifting madness is used to preserve sign
long z = (val << 38) >> 38; // signed
return new long[]{x, y, z};
}
public static void writeNewChunk(ByteBuf buffer, PacketChunkData chunk) {
// Bits Per Block (We use 0, cause we're not gonna write a palette ;) )
buffer.writeByte(0);
// No Palette nor length :D
// Data Array Length
byte[] blockData = convertBlockArray(chunk.getBlocks());
writeVarInt(blockData.length / 8, buffer); // Notchian is divide by 8
buffer.writeBytes(blockData);
// Block Light
buffer.writeBytes(chunk.getBlockLight());
// If has skylight, write it
if (chunk.getSkyLight() != null) {
buffer.writeBytes(chunk.getSkyLight());
}
public static void writeBlockPosition(ByteBuf buf, long x, long y, long z) {
buf.writeLong(((x & 0x3ffffff) << 38) | ((y & 0xfff) << 26) | (z & 0x3ffffff));
}
private static byte[] convertBlockArray(short[] blocks) {
// block ID for the first 9 bits, and the block damage value for the last 4 bits
byte[] output = new byte[6664]; // (16 * 16 * 16 * 13) / 8 :) (plus some for padding ...)
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (short block : blocks) {
int blockID = block >> 4; // (Needs to be to 9 bits)
int data = block & 0xF; // 8 bits
public static int[] readVarInts(int amount, ByteBuf input) {
int data[] = new int[amount];
for (int index = 0; index < amount; index++) {
data[index] = PacketUtil.readVarInt(input);
}
return null; // todo: finish
return data;
}
private static BitSet append(BitSet base, int index, MagicBitSet toAdd) {
int length = index;
for (int i = 0; i < toAdd.getTrueLength(); i++) {
base.set(length + i, toAdd.get(i));
}
return base;
}
private static MagicBitSet getPaddedBitSet(int value, int bitSize) {
MagicBitSet output = new MagicBitSet(bitSize);
BitSet temp = BitSet.valueOf(new long[]{value});
for (int i = 0; i < bitSize; i++) {
output.set(i, false);
}
int toShift = bitSize - temp.length();
for (int i = 0; i < temp.length(); i++) {
output.set(toShift + i, temp.get(i));
}
return output;
}
public static void writeItem(Object value, ByteBuf output) {
try {
Class<?> serializer = ReflectionUtil.nms("PacketDataSerializer");
Object init = serializer.getDeclaredConstructor(ByteBuf.class).newInstance(output);
Method toCall = init.getClass().getDeclaredMethod("a", ReflectionUtil.nms("ItemStack"));
toCall.invoke(init, value);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
public static boolean containsCause(Throwable t, Class<? extends Throwable> c) {
while (t != null) {
t = t.getCause();
if (t != null)
if (c.isAssignableFrom(t.getClass())) return true;
}
return false;
}
}
@@ -1,4 +1,4 @@
package us.myles.ViaVersion;
package us.myles.ViaVersion.util;
import org.bukkit.Bukkit;
@@ -27,6 +27,18 @@ public class ReflectionUtil {
return m.invoke(o);
}
public static <T> T getStatic(Class<?> clazz, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
Field field = clazz.getDeclaredField(f);
field.setAccessible(true);
return (T) field.get(null);
}
public static <T> T get(Object instance, Class<?> clazz, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
Field field = clazz.getDeclaredField(f);
field.setAccessible(true);
return (T) field.get(instance);
}
public static <T> T get(Object o, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
Field field = o.getClass().getDeclaredField(f);
field.setAccessible(true);
+14
View File
@@ -0,0 +1,14 @@
# Should ViaVersion check for updates?
checkforupdates: true
# Should we send any bulk chunks, in sync (may be slower but fixes timings)
# Currently broken due to sign updates, possibly will return
sync-chunks: true
# No collide options, these allow you to configure how collision works.
# Do you want us to prevent collision?
prevent-collision: true
# If the above is true, should we automatically team players until you do?
auto-team: true
# When enabled if certain metadata can't be read we won't tell you about it
suppress-metadata-errors: false
# When enabled 1.9 will be able to block by using shields
shield-blocking: true
+9 -2
View File
@@ -1,4 +1,11 @@
name: ViaVersion
main: us.myles.ViaVersion.Core
main: us.myles.ViaVersion.ViaVersionPlugin
author: _MylesC
version: 0.3.2
version: ${project.version}
load: startup
loadbefore: [ProtocolLib, ProxyPipe]
commands:
viaversion:
description: Shows ViaVersion Version and more.
permission: viaversion.admin
aliases: [viaver]