346 Commits
Author SHA1 Message Date
NotAlexNoyle 007799734f Exclude CODEOWNERS from language statistics 2026-10-28 08:31:41 -04:00
NotAlexNoyle 2a2cfd20a5 Add CODEOWNERS (one staff approval) 2026-10-28 08:31:41 -04:00
NotAlexNoyle 197288a47e normalize client animations 2026-08-09 16:32:33 -04:00
NotAlexNoyle 44e478ebe7 Merge branch 'ViaVersion:master' into master 2026-05-26 08:38:28 -04:00
dependabot[bot] ea548dfd91 [ci skip] Bump gradle-wrapper from 9.4.1 to 9.5.0 (#681)
Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.4.1 to 9.5.0.
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](https://github.com/gradle/gradle/compare/v9.4.1...v9.5.0)

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 20:48:44 +02:00
Florian Reuth d0561f2e19 ViaRewind 4.1.1 2026-05-05 20:42:51 +02:00
Beanes 2c8189a447 Fix edge case when server sends a useless packet (#679) 2026-04-28 23:06:11 +02:00
Beanes 48c9e45bcf Also rewrite extra entity ids for other interaction modes (#678) 2026-04-26 16:56:26 +02:00
Gabik21 ecb4f4bf00 Fix nametag visibility duplicate names edge case (#675) 2026-04-24 21:34:24 +02:00
Kichura 6ea9377622 [ci skip] Fix version comments, Unsubscribe from proprietary caching tier. (#677) 2026-04-24 21:34:05 +02:00
Beanes b789fdebb7 Fix set score packet crashing (#674) 2026-04-22 15:16:00 +02:00
Beanes e7b0606e18 Rewrite "no face" in digging packet to a valid 1.8 value (#673) 2026-04-22 13:43:35 +02:00
NotAlexNoyle 14991b61e7 Merge branch 'ViaVersion:master' into master 2026-04-20 16:17:40 -04:00
NotAlexNoyle bf490c3805 Fix brewing stand titles for 1.8 clients on 1.9+ servers (#672) 2026-04-20 22:10:04 +02:00
Florian Reuth 7ca7078141 Start 4.1.1 cycle
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-04-20 22:09:12 +02:00
NotAlexNoyle 9c72c68d11 Merge branch 'ViaVersion:master' into master 2026-04-20 15:32:16 -04:00
NotAlexNoyle 91643b8a53 Fix brewing stand title display for 1.8 clients on 1.9+ servers 2026-04-20 15:31:44 -04:00
Florian Reuth 170af55f91 ViaRewind 4.1.0
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-04-20 21:15:13 +02:00
dependabot[bot] 00d82f9f2f [ci skip] Bump actions/upload-artifact from 7.0.0 to 7.0.1 (#671)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 21:13:24 +02:00
Beanes 79ef613c15 Implement invisible name tag tracking in 1.8->1.7 (#666)
Fixes https://github.com/ViaVersion/ViaRewind/issues/518
Fixes https://github.com/ViaVersion/ViaRewind/issues/364
2026-04-19 21:58:18 +02:00
Beanes e2fcbafc70 Improve hologram emulation in 1.8->1.7 (#667)
* Fix metadata flags not saving cross packets syncing

* Fix marker zombie no gravity offsets

* Improve interaction by rewriting "extra" entity ids of holograms to normal hologram id
2026-04-19 17:40:18 +02:00
dependabot[bot] 9ae46145e5 [ci skip] Bump gradle/actions from 5.0.2 to 6.1.0 (#669)
Bumps [gradle/actions](https://github.com/gradle/actions) from 5.0.2 to 6.1.0.
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/0723195856401067f7a2779048b490ace7a47d7c...50e97c2cd7a37755bbfafc9c5b7cafaece252f6e)

---
updated-dependencies:
- dependency-name: gradle/actions
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-19 17:27:54 +02:00
dependabot[bot] 76f90b68b8 Bump de.florianreuth.baseproject from 2.0.1 to 2.0.2 (#665)
Bumps de.florianreuth.baseproject from 2.0.1 to 2.0.2.

---
updated-dependencies:
- dependency-name: de.florianreuth.baseproject
  dependency-version: 2.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-09 17:59:11 +02:00
Florian Reuth 32a2ee6bfa 26.1.2
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-04-09 17:54:37 +02:00
Florian Reuth 04878b7e34 26.1.1
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-04-02 20:50:46 +02:00
NotAlexNoyle 45508ddf4d Use live TrueOG Network config file 2026-04-01 12:42:16 -04:00
Florian Reuth adccdc4b41 26.1
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-03-27 17:39:20 +01:00
dependabot[bot] 0accea66f2 Bump gradle-wrapper from 9.4.0 to 9.4.1 (#662)
Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.4.0 to 9.4.1.
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](https://github.com/gradle/gradle/compare/v9.4.0...v9.4.1)

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-26 16:11:29 +01:00
NotAlexNoyle 47535748c4 Add eclipse plugin to gradle 2026-03-18 12:09:49 -04:00
dependabot[bot] 65257be3ee Bump actions/upload-artifact from 6.0.0 to 7.0.0 (#658)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/b7c566a772e6b6bfb58ed0dc250532a479d7789f...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-11 21:58:54 +01:00
dependabot[bot] 880e879dce Bump gradle/actions from 5.0.1 to 5.0.2 (#659)
Bumps [gradle/actions](https://github.com/gradle/actions) from 5.0.1 to 5.0.2.
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/f29f5a9d7b09a7c6b29859002d29d24e1674c884...0723195856401067f7a2779048b490ace7a47d7c)

---
updated-dependencies:
- dependency-name: gradle/actions
  dependency-version: 5.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-11 21:58:46 +01:00
dependabot[bot] 0ccc6a0923 Bump gradle-wrapper from 9.3.1 to 9.4.0 (#660)
Bumps gradle-wrapper from 9.3.1 to 9.4.0.

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-11 21:58:40 +01:00
dependabot[bot] 7bff361e14 Bump de.florianreuth.baseproject from 2.0.0 to 2.0.1 (#657)
Bumps de.florianreuth.baseproject from 2.0.0 to 2.0.1.

---
updated-dependencies:
- dependency-name: de.florianreuth.baseproject
  dependency-version: 2.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-03 20:34:07 +01:00
Florian Reuth c2c28473cc Start 4.1.0 cycle
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-03-01 18:10:12 +01:00
Florian Reuth 048d502998 ViaRewind 4.0.15
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-03-01 18:05:34 +01:00
Beanes e0c1f53115 Manually split newlines in chat messages in 1.8->1.7 (#655) 2026-02-16 17:55:48 +01:00
dependabot[bot] e5313a466b Bump gradle/actions from 5.0.0 to 5.0.1 (#654)
Bumps [gradle/actions](https://github.com/gradle/actions) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2...f29f5a9d7b09a7c6b29859002d29d24e1674c884)

---
updated-dependencies:
- dependency-name: gradle/actions
  dependency-version: 5.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-12 15:20:14 +01:00
dependabot[bot] e30633e367 Bump gradle-wrapper from 9.3.0 to 9.3.1 (#653)
Bumps gradle-wrapper from 9.3.0 to 9.3.1.

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-07 16:04:17 +01:00
Florian Reuth a443dd5d11 Update my name
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-02-07 16:00:19 +01:00
dependabot[bot] 3820426bce Bump actions/setup-java from 5.1.0 to 5.2.0 (#651)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/f2beeb24e141e01a676f977032f5a29d81c9e27e...be666c2fcd27ec809703dec50e508c2fdc7f6654)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: 5.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-03 16:32:51 +01:00
Beanes 031ae32f27 Only set hologram state if name tag is visible (#652) 2026-02-03 16:32:38 +01:00
FlorianMichael e83616139e Update supported Velocity versions
Signed-off-by: FlorianMichael <git@florianmichael.de>
2026-01-31 20:16:07 +01:00
dependabot[bot] 7325b733d6 Bump actions/checkout from 6.0.1 to 6.0.2 (#650)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/8e8c483db84b4bee98b60c0593521ed34d9990e8...de0fac2e4500dabe0009e67214ff5f5447ce83dd)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-27 10:57:27 +01:00
Alessandro e64501eae8 Fix red sandstone stairs rotation in 1.8->1.7 (#649) 2026-01-25 17:09:32 +01:00
FlorianMichael 2d99607c35 Start 4.0.15 cycle
Signed-off-by: FlorianMichael <git@florianmichael.de>
2026-01-18 16:31:36 +01:00
FlorianMichael 4d159189c0 ViaRewind 4.0.14
Signed-off-by: FlorianMichael <git@florianmichael.de>
2026-01-18 16:19:42 +01:00
FlorianMichael 2076294856 Gradle 9.3.0
Signed-off-by: FlorianMichael <git@florianmichael.de>
2026-01-18 13:36:11 +01:00
FlorianMichael 49f7bd22be Add default impl class 2026-01-17 14:19:49 +01:00
FlorianMichael 298605874d Remove special sign component type 2026-01-10 00:39:23 +01:00
BeanesandFlorianMichael 35b94f1878 Use velocity native compression if available (#647)
* Optimize 1.7 compression by using velocity-native compressor

* Rewrite 1.7 chunk serializing to reduce allocations

* Don't include velocity native as shaded dependency, add fallback and only use velocity compression if available

* Change chunk compression back to default java as chunks are serialized on heap byte arrays so native compression has no use

* Move velocity only code in custom decoder/encoder overrides

* Remove debug

* Move compression into non static context

---------

Co-authored-by: FlorianMichael <git@florianmichael.de>
2026-01-06 03:25:48 +01:00
FlorianMichael 37955059c4 Don't require config impl class in ViaRewindPlatform#init 2026-01-04 13:01:44 +01:00
FlorianMichael af4306bc81 Start 4.0.14 cycle 2025-12-29 15:08:09 +01:00
FlorianMichael 98ca00f625 ViaRewind 4.0.13 2025-12-29 15:04:19 +01:00
dependabot[bot] 598804432b Bump actions/upload-artifact from 5.0.0 to 6.0.0 (#648)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5.0.0 to 6.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/330a01c490aca151604b8cf639adc76d48f6c5d4...b7c566a772e6b6bfb58ed0dc250532a479d7789f)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-29 14:30:50 +01:00
FlorianMichael 92bae0a5c4 Update VV API usage 2025-12-29 14:23:20 +01:00
FlorianMichael d50b6a2f89 Prepare for next year (2026) 2025-12-29 00:12:28 +01:00
Kichura 54cc085717 Change schedule's interval to monthly. (#633) 2025-12-20 14:30:53 +01:00
dependabot[bot] bd0d4c31b2 Bump actions/checkout from 6.0.0 to 6.0.1 (#644)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/1af3b93b6815bc44a9784bd300feb67ff0d1eeb3...8e8c483db84b4bee98b60c0593521ed34d9990e8)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 21:41:52 +01:00
dependabot[bot] 705c88f4b3 Bump actions/setup-java from 5.0.0 to 5.1.0 (#645)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.0.0 to 5.1.0.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/dded0888837ed1f317902acf8a20df0ad188d165...f2beeb24e141e01a676f977032f5a29d81c9e27e)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: 5.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 21:41:45 +01:00
FlorianMichael 7306a795b9 [ci skip] Include the newest ViaProxy version from 3.0.0 to 4.0.0 2025-12-13 20:00:44 +01:00
FlorianMichael dfdfad4bfc Add ViaRewindPlatform#init with config instance 2025-12-13 19:59:51 +01:00
FlorianMichael c87654848d Start 4.0.13 cycle 2025-12-12 16:08:44 +01:00
FlorianMichael 08a7077d10 ViaRewind 4.0.12 2025-12-12 16:04:46 +01:00
dependabot[bot] 73afaaf493 Bump io.papermc.hangar-publish-plugin from 0.1.3 to 0.1.4 (#636)
Bumps io.papermc.hangar-publish-plugin from 0.1.3 to 0.1.4.

---
updated-dependencies:
- dependency-name: io.papermc.hangar-publish-plugin
  dependency-version: 0.1.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 14:29:12 +01:00
dependabot[bot] f0f8038b18 Bump de.florianmichael.baseproject.BaseProject from 1.2.5 to 1.2.6 (#631)
Bumps de.florianmichael.baseproject.BaseProject from 1.2.5 to 1.2.6.

---
updated-dependencies:
- dependency-name: de.florianmichael.baseproject.BaseProject
  dependency-version: 1.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-29 23:11:31 +01:00
Kichura 540c0d0d47 Mitigate security vulnerabilities in CI. (#632) 2025-11-29 23:10:32 +01:00
dependabot[bot] d00b0c8afe Bump de.florianmichael.baseproject.BaseProject from 1.2.4 to 1.2.5 (#628)
Bumps de.florianmichael.baseproject.BaseProject from 1.2.4 to 1.2.5.

---
updated-dependencies:
- dependency-name: de.florianmichael.baseproject.BaseProject
  dependency-version: 1.2.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 21:59:31 +01:00
dependabot[bot] b34385c09e Bump actions/checkout from 5 to 6 (#630)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 21:59:24 +01:00
FlorianMichael ff47845df1 Gradle 9.2.0 2025-11-03 16:18:55 +01:00
FlorianMichael fc37b9c0ba Only send start fall flying if player has elytra on chestplate in 1.9->1.8
Closes https://github.com/ViaVersion/ViaRewind/pull/625
2025-10-29 15:28:17 +01:00
FlorianMichael e3baafa2a2 4.0.11 Release 2025-10-12 19:05:30 +02:00
Nassim Jahnke 11914da37e Use VV contained sound mappings in 1.9->1.8 2025-10-12 13:58:31 +02:00
FlorianMichael 30fa58af81 Fix boat y offset in 1.9->1.8 2025-10-09 21:40:47 +02:00
dependabot[bot] 52b6aed005 Bump de.florianmichael.baseproject.BaseProject from 1.2.2 to 1.2.3 (#620)
Bumps de.florianmichael.baseproject.BaseProject from 1.2.2 to 1.2.3.

---
updated-dependencies:
- dependency-name: de.florianmichael.baseproject.BaseProject
  dependency-version: 1.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 17:51:03 +02:00
dependabot[bot] 9d74706e84 Bump gradle/actions from 4 to 5 (#621)
Bumps [gradle/actions](https://github.com/gradle/actions) from 4 to 5.
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/v4...v5)

---
updated-dependencies:
- dependency-name: gradle/actions
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 17:50:55 +02:00
FlorianMichael 7d5ad45ffc Update VV api usage 2025-10-07 17:50:24 +02:00
FlorianMichael bd3593e15a 4.0.10 Release 2025-10-03 13:54:15 +02:00
FlorianMichael 835fb5de08 Update VV api usage 2025-09-30 19:57:11 +02:00
FlorianMichael 8b2769f19b Don't include subprojects as dependencies in the root project 2025-09-25 21:03:21 +02:00
FlorianMichael 4da08b5a35 Auto: Gradle 9.1.0 2025-09-22 21:46:11 +02:00
dependabot[bot] 7da8e62a39 Bump actions/setup-java from 4 to 5 (#619)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-30 18:26:38 +02:00
FlorianMichael 31c62f96b9 [ci skip] Fix SECURITY.md formatting 2025-08-12 06:05:37 +02:00
FlorianMichael 0f866d8b50 Fix sign update component read types in 1.7<->1.9
Closes https://github.com/ViaVersion/ViaRewind/issues/613
2025-08-12 06:02:30 +02:00
dependabot[bot] 32d265116a [ci skip] Bump actions/checkout from 4 to 5 (#617)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 05:50:50 +02:00
dependabot[bot] b7d1197be3 [ci skip] Bump de.florianmichael.baseproject.BaseProject from 1.1.1 to 1.2.1 (#614)
Bumps de.florianmichael.baseproject.BaseProject from 1.1.1 to 1.2.1.

---
updated-dependencies:
- dependency-name: de.florianmichael.baseproject.BaseProject
  dependency-version: 1.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-08 02:08:39 +02:00
FlorianMichael d4363b67b6 Gradle 9.0.0 2025-08-03 01:35:34 +02:00
FlorianMichael dcdce8ad52 4.0.9 Release 2025-07-27 14:51:16 +02:00
Ambassator af44f88d6e Remove the wither outline when using the bossbar on 1.9->1.8 (#604)
Adds metadata to the spawn packet to make the wither tiny so the player doesn't see a wither outline when the bossbar is on low health
2025-07-27 14:27:06 +02:00
Beanes 1d1d77abfd Add support for armor stands with no gravity as zombie in 1.8->1.7 (#609) 2025-07-27 14:24:06 +02:00
BeanesandFlorianMichael ae800f16be Basic chat item handling in 1.8->1.7 (#606)
This is still missing most packets and should one day be moved into a proper component rewriter, but this works for now.


Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-07-27 14:17:55 +02:00
BeanesandFlorianMichael f31d731f34 Cleanup player info logic 1.8->1.7 (#608)
* Cleanup player info logic

* Don't update ping if it's the same

* Cleanup

---------

Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-07-26 20:10:15 +02:00
Beanes 2ddd0d8b66 [ci skip] Clarify respawn metadata resending (#612) 2025-07-26 13:43:57 +02:00
BeanesandFlorianMichael f97884158b Implement play state compression and handle compression being set twice (#607)
* Implement play state compression and handle compression being set twice

* Fix 0 threshold; Code cleanup

---------

Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-07-25 20:57:49 +02:00
FlorianMichael 1e2fcb9c58 [ci skip] Reformat all classes 2025-07-25 11:26:09 +02:00
FlorianMichael 5110326a90 Aggressively validate sign update component 2025-07-25 11:20:40 +02:00
FlorianMichael 6887556b2c [ci skip] Add SECURITY.md 2025-07-25 08:37:43 +02:00
LabyStudio 66cf650d36 Limit legacy string trimming (#605) 2025-07-25 08:36:05 +02:00
FlorianMichael 1426631c97 [ci skip] Update ViaProxy 2025-07-24 20:15:40 +02:00
EthanKeating b6a32823cc Fix hologram height offsets in 1.8->1.7 (#601) 2025-07-23 18:27:28 +02:00
EthanKeatingandFlorianMichael aff88a6ca3 Fix respawn screen appearing twice in 1.8->1.7 (#597)
* Fixed double respawn screen displaying

* Only remove, don't re-add

---------

Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-07-22 16:32:49 +02:00
FlorianMichaelandNassim Jahnke 0edfd844b9 [ci skip] Split up publishing steps
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
2025-07-22 16:26:41 +02:00
FlorianMichael 57a64740aa [ci skip] Mark 1.21.8 release 2025-07-17 21:27:26 +02:00
EthanKeating f7903050bf Update ping value in player list entry instead of sending a new one in 1.8->1.7 (#599) 2025-07-14 00:18:29 +02:00
EthanKeatingandEnZaXD 3a7ac0765b Also pass sneaking through hologram emulation; fix attachments 1.8->1.7 (#598)
* Fixed holograms flying up + Hologram sneaking

* Code cleanup

---------

Co-authored-by: EnZaXD <florian.michael07@gmail.com>
2025-07-13 21:13:47 +02:00
FlorianMichael 48f500a470 Copy over always show nametag 1:1 2025-07-13 21:00:22 +02:00
EthanKeating c3e19b769b Don't drop alwaysShowNametag entity data in hologram emulation 1.8->1.7 (#600) 2025-07-13 20:49:05 +02:00
dependabot[bot] 561829d952 Bump net.raphimc.class-token-replacer from 1.1.6 to 1.1.7 (#594)
Bumps net.raphimc.class-token-replacer from 1.1.6 to 1.1.7.

---
updated-dependencies:
- dependency-name: net.raphimc.class-token-replacer
  dependency-version: 1.1.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 21:04:07 +02:00
FlorianMichael 6767379526 Mark 1.21.7 release 2025-06-30 21:02:49 +02:00
mariaum a10ce1f35f Remap yaw values correctly when teleporting entities in 1.9->1.8 (#585) 2025-06-27 02:40:40 +02:00
FlorianMichael 49f0c673e6 Bump version to 4.0.9-SNAPSHOT 2025-06-27 02:39:00 +02:00
dependabot[bot] fd2c81a6fd [ci skip] Bump de.florianmichael.baseproject.BaseProject from 1.0.7 to 1.1.1 (#588)
Bumps de.florianmichael.baseproject.BaseProject from 1.0.7 to 1.1.1.

---
updated-dependencies:
- dependency-name: de.florianmichael.baseproject.BaseProject
  dependency-version: 1.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-27 02:10:49 +02:00
FlorianMichael 901463e095 4.0.8 Release 2025-06-20 20:11:01 +02:00
FlorianMichael 227d37b2b9 Update VV api usage 2025-06-16 18:27:46 +02:00
FlorianMichael be5bb6e07c Write flags as byte in PLAYER_INPUT 1.8->1.7 2025-06-10 20:16:14 +02:00
Nassim Jahnke 064dbee920 Update profile properties type 2025-05-26 17:32:13 +02:00
FlorianMichael 783006baa5 Auto: Gradle 8.14.1 2025-05-22 17:51:04 +02:00
Adrian ba93a40d22 Change end rod block state mapping to white stained glass in 1.9->1.8 (#584) 2025-05-22 00:18:48 +02:00
dependabot[bot] 422f81dd2e Bump org.gradle.toolchains.foojay-resolver-convention (#583)
Bumps org.gradle.toolchains.foojay-resolver-convention from 0.10.0 to 1.0.0.

---
updated-dependencies:
- dependency-name: org.gradle.toolchains.foojay-resolver-convention
  dependency-version: 1.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-22 00:12:32 +02:00
FlorianMichael aa47e3c0a5 Update BaseProject 2025-05-19 00:12:39 +02:00
FlorianMichael 094298771e Update ClassTokenReplacer 2025-05-17 17:57:07 +02:00
FlorianMichael 66133d1ccc Update VV api usage 2025-05-17 15:37:37 +02:00
FlorianMichael 11011d59aa Rewrite build files 2025-05-15 15:28:44 +02:00
FlorianMichael 691cbf1b2a Small cleanup 2025-05-15 11:18:26 +02:00
EthanKeating 8d8675a891 Fix hologram movement by wrapping them to an interpolated entity in 1.8->1.7 (#580)
* Hologram movement fix for 1.7 clients

* fix: addressed feedback from PR review
2025-05-15 08:26:12 +02:00
Beanes 4fa2f10f3a Use correct entity id data type in 1.8->1.7 entity data sending (#579) 2025-05-08 20:24:50 +02:00
FlorianMichael c2e516dcd2 Auto: Gradle 8.14 2025-04-26 16:25:07 +02:00
BeanesandFlorianMichael 153eedd5eb Optimize memory usage for 1.7 chunk rewriting (#577)
* Optimize memory usage

* Bump version; cleanup code

---------

Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-04-22 23:52:39 +02:00
FlorianMichael 2d404608ee [ci skip] Reformat GH issue templates 2025-04-20 14:41:56 +02:00
FlorianMichael bbc1d77939 4.0.7 Release 2025-03-31 01:08:03 +02:00
dependabot[bot] fa36428391 Bump io.papermc.hangar-publish-plugin from 0.1.2 to 0.1.3 (#568)
Bumps io.papermc.hangar-publish-plugin from 0.1.2 to 0.1.3.

---
updated-dependencies:
- dependency-name: io.papermc.hangar-publish-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-29 14:47:08 +01:00
FlorianMichael b6dee43620 Update VV api usage 2025-03-29 14:46:44 +01:00
FlorianMichael 371c25f9d0 Update MCStructs to 3.0.0 2025-03-29 14:46:14 +01:00
FlorianMichael a41bbc2d67 4.0.6 Release 2025-03-28 19:07:24 +01:00
Nassim Jahnke de84a8fffc Replace deprecated class use 2025-03-26 13:47:29 +01:00
Nassim Jahnke 22ff1416c2 Fix serverbound container_close container types
Fixes #566
2025-03-13 13:58:14 +01:00
FlorianMichael 00b74ef2dd Update container id types 2025-03-12 18:31:20 +01:00
FlorianMichael 8d5b348318 Fix data field getting in ADD_ENTITY handler in 1.9->1.8 2025-03-09 01:06:11 +01:00
FlorianMichael 51f001ac3e Don't use -1 as indicator in EntityTracker1_9#getVehicle 2025-02-26 20:21:50 +01:00
FlorianMichael e27caba231 Cleanup code here and there 2025-02-25 21:40:03 +01:00
FlorianMichael 07aab015ea Auto: Gradle 8.13, .editorconfig 2025-02-25 18:44:28 +01:00
FlorianMichael 6bcf8d8895 Update ViaProxy, exclude run folder in .gitignore 2025-02-12 16:28:41 +01:00
FlorianMichael 43c42f44f6 Move handler names to the platform
As needs platform handling it should be directly exposed to the wrapper rather than being in the storage
2025-02-12 16:25:37 +01:00
FlorianMichael 295d87d49f Add functions to allow changing the handler names in TrackingCompressionHandlerProvider 2025-01-28 19:01:45 +01:00
FlorianMichael ab97e248da Auto: Gradle 8.12.1 2025-01-24 15:44:23 +01:00
FlorianMichael 276b9ba386 Update VV API usage 2025-01-10 22:44:59 +01:00
FlorianMichael 351ff79187 4.0.5 Release 2025-01-01 21:29:53 +01:00
FlorianMichael 87ed2160c9 Auto: 2025 2025-01-01 01:07:59 +01:00
FlorianMichael 668ed3c455 Auto: Gradle 8.12 2024-12-22 02:12:08 +01:00
FlorianMichael 3a0c742878 Auto: Migrate to setup-gradle action 2024-12-17 00:29:36 +01:00
FlorianMichael bc7b33f28a Handle unknown entity types correctly 2024-12-16 01:27:26 +01:00
FlorianMichael 657dcaa682 Do not persist credentials 2024-12-15 18:05:25 +01:00
FlorianMichael 3676906fbf Remove wiki.vg references 2024-12-13 22:50:24 +01:00
FlorianMichael dc9dbe9900 Bump version to 4.0.5-SNAPSHOT 2024-12-13 22:50:06 +01:00
FlorianMichael d8924485ac 4.0.4 Release 2024-12-06 16:34:00 +01:00
LeeGod b02a257383 Fix data loose in enchantment table item rewriting in 1.8->1.7 (#554) 2024-12-03 21:24:29 +01:00
FlorianMichael a4b666724f Use correct array type for reading passengers in 1.9->1.8
Closes https://github.com/ViaVersion/ViaRewind/issues/552
2024-11-27 21:51:25 +01:00
github-actions[bot]andgradle-update-robot e92b15c19f Update Gradle Wrapper from 8.11 to 8.11.1 (#551)
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
Co-authored-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2024-11-24 02:04:41 +01:00
3fd2da9bf8 Update Gradle Wrapper from 8.10.2 to 8.11 (#549)
* Update Gradle Wrapper from 8.10.2 to 8.11

Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>

* Update Gradle API usage

---------

Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
Co-authored-by: gradle-update-robot <gradle-update-robot@regolo.cc>
Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2024-11-14 23:28:48 +01:00
FlorianMichael ff4fbe2029 Bump version to 4.0.4-SNAPSHOT 2024-11-07 19:25:17 +01:00
Remigio c3d32874a7 Correct wrong name in plugin.yml (#548) 2024-11-07 19:24:04 +01:00
FlorianMichael 7b9888c758 [ci skip] Add gradle task to quickly test/debug code changes 2024-10-31 21:27:50 +01:00
FlorianMichael e0c05df633 [ci skip] Update version ranges in gradle.properties 2024-10-23 15:49:10 +02:00
FlorianMichael 3af661b256 4.0.3 Release 2024-10-14 17:26:28 +02:00
FlorianMichael 74ebb09ebc Update required ViaFabric version, don't require fabric-loader 2024-10-10 15:44:20 +02:00
FlorianMichael 36396c10b0 Define as Sponge plugin for ViaSponge 2024-10-03 18:59:02 +02:00
github-actions[bot]andgradle-update-robot bc9b84464b Update Gradle Wrapper from 8.10.1 to 8.10.2 (#544)
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
Co-authored-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2024-09-29 04:21:22 +02:00
FlorianMichaelandBT (calcastor/mame) 0ee7c1cf16 Update correct entity data list in 1.8->1.7
Co-authored-by: "BT (calcastor/mame)" <43831917+calcastor@users.noreply.github.com>
2024-09-26 15:08:18 +02:00
dependabot[bot] 6d35536862 Bump gradle-update/update-gradle-wrapper-action from 1 to 2 (#542)
Bumps [gradle-update/update-gradle-wrapper-action](https://github.com/gradle-update/update-gradle-wrapper-action) from 1 to 2.
- [Release notes](https://github.com/gradle-update/update-gradle-wrapper-action/releases)
- [Changelog](https://github.com/gradle-update/update-gradle-wrapper-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gradle-update/update-gradle-wrapper-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: gradle-update/update-gradle-wrapper-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-25 17:11:17 +02:00
FlorianMichael 8945193a8a Improve spectating client entity id tracking 2024-09-20 14:36:17 +02:00
FlorianMichael 546f4b14fa Add setting for player combat packet handling 2024-09-18 00:10:37 +02:00
FlorianMichael e8028cf446 Show player combat death message above hotbar in 1.9->1.8 2024-09-17 23:45:36 +02:00
FlorianMichael 6a85860132 Use RewriterBase API class for packet rewriter classes 2024-09-17 23:31:10 +02:00
FlorianMichael 4b11b8e1bb Fix client world get on level chunk packet in 1.8->1.7 2024-09-17 23:18:06 +02:00
FlorianMichael 724a6b7a4b Check if client entity id is set 2024-09-17 23:16:06 +02:00
FlorianMichael c785df5fc0 Refactor dimension switch handling 2024-09-15 22:20:36 +02:00
github-actions[bot]andgradle-update-robot de92c06dfd Update Gradle Wrapper from 8.10 to 8.10.1. (#541)
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
Co-authored-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2024-09-15 09:55:02 +02:00
FlorianMichael 31f427a1b6 Cleanup LOGIN packet handlers 2024-08-25 21:44:17 +02:00
github-actions[bot]andgradle-update-robot fffcae9c0e Update Gradle Wrapper from 8.9 to 8.10. (#540)
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
Co-authored-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2024-08-18 03:17:39 +02:00
FlorianMichael 594dbbcbe9 Only print broken components if suppression disabled 2024-08-13 04:54:38 +02:00
Clairton Santos 8c4efbbb13 Fix race condition when destroy entities on 1.7 (#539) 2024-08-11 02:46:18 +02:00
FlorianMichael 5b1dcf63d2 Add gradle wrapper update workflow 2024-08-07 00:03:39 +02:00
FlorianMichael beead5773c Update IDEA copyright configuration files 2024-08-05 19:51:47 +02:00
FlorianMichael 60a5c4ae2f Setup dependabot, cleanup build files 2024-08-05 19:48:46 +02:00
FlorianMichael d707e20b05 Bump version to 4.0.3-SNAPSHOT 2024-08-05 19:46:22 +02:00
FlorianMichael 14bad1d36f 4.0.2 Release 2024-07-28 16:36:21 +02:00
FlorianMichael 7a9bf5f465 Code cleanup 2024-07-25 18:23:45 +02:00
FlorianMichael f290af7b81 Deep copy items 2024-07-25 17:52:13 +02:00
FlorianMichael 064d0008f5 Keep entity data after respawn in 1.8->1.7 2024-07-25 17:28:04 +02:00
FlorianMichael fbe30d9da5 Cleanup build files
Delete not needed gradle.properties and moves the universal submodule to the root project
2024-07-21 19:43:38 +02:00
FlorianMichael 31490069ea Gradle 8.9 2024-07-14 20:31:37 +02:00
FlorianMichael 1b8d5eacc0 Print death message in chat 2024-07-12 01:53:45 +02:00
FlorianMichael abdb79598b Emulate PLAYER_COMBAT packet in 1.9->1.8 2024-07-12 01:27:33 +02:00
FlorianMichael 1b5b59317c Rename VREntityRewriter#removeEntities, move PLAYER_COMBAT to player packets 2024-07-12 00:59:58 +02:00
FlorianMichael 6e4ac65983 Update VB API usage 2024-07-06 21:20:23 +02:00
FlorianMichael 64cce82140 Properly skip entity data packets 2024-07-04 22:03:28 +02:00
FlorianMichael cb79316d6a Update potion mappings documentation 2024-07-04 00:03:47 +02:00
FlorianMichael 7d34c3838a Fix sign rewriting in 1.8->1.7 2024-07-04 00:03:35 +02:00
FlorianMichael c60152532d Only continue item rewriting if tag is present in 1.8->1.7 2024-06-29 22:59:22 +02:00
FlorianMichael 1894bac11b Fix nullable tag issues in 1.9->1.8 item rewriter 2024-06-29 22:57:59 +02:00
FlorianMichael a80ca442e5 Bump gradle wrapper validation to v3 2024-06-29 15:59:58 +02:00
FlorianMichael c69ce24d32 Only allow VB 5.0.0+ in fabric.mod.json 2024-06-29 15:26:54 +02:00
FlorianMichael e937a886ec Bump version to 4.0.2-SNAPSHOT 2024-06-27 18:21:39 +02:00
FlorianMichael 3e261824ef 4.0.1 Release 2024-06-27 18:13:39 +02:00
FlorianMichael 43c3bb11dc Skip metadata of entities which aren't spawned (yet) 2024-06-27 15:52:00 +02:00
FlorianMichael f57ac05bd4 Add setting for levitation emulation, cleanup code 2024-06-27 02:17:59 +02:00
FlorianMichael a3c623c202 Slightly improve wording in config.yml 2024-06-22 00:56:42 +02:00
FlorianMichael 481315f1e6 Cleanup code 2024-06-22 00:55:50 +02:00
FlorianMichael 21e50421e5 Rename Gradle convention plugin 2024-06-21 11:28:07 +02:00
FlorianMichael 233d52281b Add getter/setter for CooldownStorage#visualizationFactory
Allows servers to override the existing visualization factory with their own ones
2024-06-21 11:25:25 +02:00
FlorianMichael 6807a02de7 Bump version to 4.0.1-SNAPSHOT 2024-06-21 11:23:57 +02:00
FlorianMichael b34cc42a65 4.0.0 Release 2024-06-16 18:10:25 +02:00
FlorianMichael 7b1f0a8737 Rename build-logic submodule 2024-06-15 21:14:47 +02:00
FlorianMichael a171e4013b Only accept correct byte type in custom payload 1.8->1.7 2024-06-11 15:38:34 +02:00
FlorianMichael 3e3561c18f Update VV API usage 2024-06-11 15:36:03 +02:00
FlorianMichael 0097a97ab0 Add note for J8 builds 2024-06-06 05:20:24 +02:00
FlorianMichael 6e583a0c8e Remove missing bungee/sponge references 2024-06-06 05:11:00 +02:00
FlorianMichael 780b981c68 Fixup hologram handling 1.8->1.7
Closes https://github.com/ViaVersion/ViaRewind/issues/509
2024-06-06 05:07:47 +02:00
FlorianMichael 5df933f0e2 Fix 1.7->1.8 player action rewriting 2024-06-03 03:02:45 +02:00
FlorianMichael 750a98cb06 Fixup position reading 2024-06-02 17:50:56 +02:00
FlorianMichael 1ebfa0a715 Update Gradle Wrapper 2024-06-01 17:41:58 +02:00
Nassim Jahnke dc82de8ba2 Move Sponge and Bungee modules to separate plugins 2024-05-30 22:45:53 +02:00
Nassim Jahnke 9ecdaa30bf Use unsigned byte for facing direction in player action 2024-05-30 11:33:49 +02:00
FlorianMichael ee69005318 Delete temporary fix for shulker box window titles
Properly fixed by https://github.com/ViaVersion/ViaBackwards/pull/761
2024-05-28 18:11:08 +02:00
FlorianMichael 740a6d9b96 Finish up v5 migration
Also:
- Reduces the amount of anonymous classes
- Removes usages of PacketWrapper#create with raw ids
2024-05-22 23:36:51 +02:00
Nassim Jahnke b1d680468b Update VV API usage 2024-05-22 12:11:11 +02:00
FlorianMichael 64c18af7b6 Update Via API usage 2024-05-18 21:33:21 +02:00
FlorianMichael 6728a8a809 Port to upstream changes (hopefully) 2024-05-15 00:08:22 +02:00
FlorianMichael 0cb70b0a04 Rename protocol packages and classes 2024-05-11 15:18:21 +02:00
FlorianMichael 2f7f108cd8 Bump version to 4.0.0-SNAPSHOT 2024-05-11 15:12:41 +02:00
FlorianMichael c595c654aa 3.1.2 Release 2024-05-10 13:19:10 +02:00
FlorianMichael c0d1cabb12 Fix bow animation not working in 1.9->1.8
Closes https://github.com/ViaVersion/ViaRewind/issues/516
2024-05-10 00:29:41 +02:00
FlorianMichael 51e81c7bb1 Fix mappings and update project description
Closes https://github.com/ViaVersion/ViaRewind/issues/514
2024-05-10 00:08:00 +02:00
FlorianMichael 6bdaa54ce8 Use 1.9.0 sounds for name<->id conversion
1.9.1 added a new sound so mapping files were previously wrong
2024-05-09 01:03:39 +02:00
FlorianMichael 65ac2f37f2 Don't throw metadata away in 1.8->1.7
Closes https://github.com/ViaVersion/ViaRewind/issues/512
2024-05-09 00:25:13 +02:00
FlorianMichael b08bb90cef Fix packet send usages 2024-05-08 21:31:47 +02:00
FlorianMichael 89e76d369b Fix destroy entities handling in 1.7->1.8
Split into multiple packets since 1.8 can handle a larger list of entities than 1.7 can, causing NegativeArraySizeException's to appear on some servers.
2024-05-07 00:09:24 +02:00
FlorianMichael ed8cc47c7a Bump version to 3.1.2-SNAPSHOT 2024-05-06 23:51:55 +02:00
FlorianMichael d988fdc849 3.1.1 Release 2024-05-05 16:45:42 +02:00
FlorianMichael a0ff53fb9d Don't handle entity properties for holograms 2024-04-30 19:08:19 +02:00
FlorianMichael 1d1dd7dc66 Catch exceptions in custom payload handling
Closes https://github.com/ViaVersion/ViaRewind/issues/192
2024-04-29 02:25:21 +02:00
FlorianMichael cb4ef9ffa8 Fix mob spawner entity data translation in 1.8->1.9
Closes https://github.com/ViaVersion/ViaRewind/issues/126
2024-04-29 02:05:15 +02:00
FlorianMichael 459f403541 Map END_GATEWAY to END_PORTAL in 1.8->1.9
Closes https://github.com/ViaVersion/ViaRewind/issues/150
2024-04-29 01:54:46 +02:00
FlorianMichael 465962b939 Clear enchantments on screen close 2024-04-29 01:42:51 +02:00
FlorianMichael 2fad493eac Rewrite enchantment window properties in 1.8->1.9
Closes https://github.com/ViaVersion/ViaRewind/issues/485
2024-04-29 01:38:29 +02:00
FlorianMichael fb8ea8c4f8 Merge remote-tracking branch 'origin/master' 2024-04-29 00:33:00 +02:00
FlorianMichael 9713e5a8a4 Update mapping files 2024-04-29 00:32:30 +02:00
Nassim Jahnke 7cee59f548 Set paperweight-mappings-namespace manifest attribute 2024-04-28 12:34:56 +02:00
FlorianMichael c7e638fc70 Fix 1.8->1.9 window items translation 2024-04-27 13:58:42 +02:00
FlorianMichael a4b445cf1f Use correct method to remove vehicle in 1.8->1.9
Closes https://github.com/ViaVersion/ViaRewind/issues/505
2024-04-27 13:10:02 +02:00
FlorianMichael 6859f6125c Bump version to 3.1.1-SNAPSHOT 2024-04-27 12:58:07 +02:00
FlorianMichael d85e043325 3.1.0 Release 2024-04-26 15:32:46 +02:00
FlorianMichael 967adaa607 Update item mappings
Adds support for https://github.com/ViaVersion/ViaBackwards/pull/728 as well as missing blockstate mappings from before the rewrite.
2024-04-26 00:27:44 +02:00
FlorianMichael e233b0fa09 Fix and clean hologram emulation 2024-04-24 18:10:29 +02:00
FlorianMichael 2e52a396d3 Migrate 1.7->1.8 as well 2024-04-24 16:57:00 +02:00
FlorianMichael 93731be764 Add new config options for /offhand, also some cleanup 2024-04-23 23:49:43 +02:00
FlorianMichael 8a5d826fd3 Tidy up a few things and fixed tons of bugs 2024-04-23 22:29:37 +02:00
FlorianMichael d5fa0ff8e8 Migrate 1.8->1.9 and removed tons of outdated code 2024-04-23 20:35:27 +02:00
FlorianMichael 823b00930e Merge remote-tracking branch 'refs/remotes/origin/dev' into refactor/viabackwards
# Conflicts:
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/packets/BlockItemPackets1_8.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/rewriter/ReplacementItemRewriter1_7_6_10.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/metadata/MetadataRewriter.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/packets/InventoryPackets.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/rewriter/ReplacementItemRewriter1_8.java
2024-04-22 11:46:53 +02:00
Nassim Jahnke da449f2a9e Add UserConnection param to item rewriter methods 2024-04-21 22:48:30 +02:00
FlorianMichael 8835ee4ed2 Update metadata rewriter 2024-04-09 16:00:48 +02:00
FlorianMichael 3ef9dbec1f Merge branch 'refs/heads/dev' into refactor/viabackwards
# Conflicts:
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/metadata/MetadataRewriter.java
2024-04-09 15:59:31 +02:00
FlorianMichael b2a78d6dd2 Merge remote-tracking branch 'refs/remotes/origin/master' into dev 2024-04-09 15:57:56 +02:00
FlorianMichael 1aaba348d2 Update build script 2024-04-09 15:56:46 +02:00
FlorianMichael 4d5c4e6223 Removed non-existent meta type 2024-04-09 15:53:42 +02:00
FlorianMichael d08739839e Fix universal module name 2024-04-09 15:51:35 +02:00
FlorianMichael e891696387 Start with porting protocol code 2024-04-09 15:47:45 +02:00
vadage 08cb78f065 Support config loading from input stream (#502)
* Support config loading from input stream

* Fix formatting issue to be consistent with spaces
2024-04-05 20:38:35 +02:00
FlorianMichael 819a4d8bb3 More work 2024-03-29 18:13:05 +01:00
FlorianMichael aa5696e586 Overall improvements to README.md 2024-03-29 13:00:02 +01:00
FlorianMichael 3c9232949a Rename classes to match VB 2024-03-29 12:47:38 +01:00
FlorianMichael a43ad2b737 Prepare entity rewriter migration 2024-03-29 12:41:17 +01:00
FlorianMichael 7e5e8fd2c1 Fix enchantments in 1.7->1.8 2024-03-28 18:08:24 +01:00
FlorianMichael 7fc2530693 Compile from repository server 2024-03-28 11:46:11 +01:00
FlorianMichael e104df51b0 Drop format reset 2024-03-28 10:44:32 +01:00
FlorianMichael 6d237cc337 Deprecate and move classes 2024-03-27 20:34:23 +01:00
FlorianMichael a982ac8c38 Move particle class 2024-03-27 20:26:28 +01:00
FlorianMichael 8494976e4f Port 1.8 -> 1.9 item rewriter as well 2024-03-27 20:02:50 +01:00
FlorianMichael 7b2ad249da Use EnchantmentRewriter base (probably) 2024-03-27 18:22:31 +01:00
FlorianMichael 5f73bee3c5 Start with using ViaBackwards API 2024-03-27 18:04:04 +01:00
FlorianMichael 709f918272 Generate item mappings 2024-03-27 13:55:39 +01:00
FlorianMichael dca9854486 Removed support status from README 2024-03-27 13:54:44 +01:00
FlorianMichael d93dce88d8 So it begins... 2024-03-27 11:12:37 +01:00
FlorianMichael 5ae0f29f42 Fixed version range 2024-03-25 17:35:55 +01:00
FlorianMichael eae4a3ac09 Renamed universal artifact to viarewind, fixed platform name in Via dumps 2024-03-25 17:34:07 +01:00
FlorianMichael 5e1ae7ac0f Back to VV dev 2024-03-24 13:06:13 +01:00
FlorianMichael 2422588db5 Remove viafabricplus from dependency list 2024-03-24 13:01:43 +01:00
FlorianMichael 0a1707f1d0 Fix up again 2024-03-23 13:18:47 +01:00
FlorianMichael c6d6128c5e Update publishing plugin usage 2024-03-23 13:11:40 +01:00
FlorianMichael 8f2072d2af [ci skip] Removed unused import 2024-03-23 12:32:59 +01:00
FlorianMichael 42fbcfb26a Gradle 8.7 2024-03-23 12:31:27 +01:00
FlorianMichael a9568d388f Update Hangar publish plugin 2024-03-23 12:29:42 +01:00
FlorianMichael 36ea0fecc6 Fixed compile error 2024-03-09 14:11:41 +01:00
FlorianMichael 6a26bbdf84 Back to VV master 2024-03-09 14:09:30 +01:00
FlorianMichael 45deefdea3 Update ViaNBT API usage 2024-03-09 14:04:37 +01:00
FlorianMichael 476c5f2077 Updated Via API usage 2024-03-09 13:51:19 +01:00
FlorianMichael aaddfb186b Fixed API usage 2024-03-05 21:02:35 +01:00
FlorianMichael 5407bf9922 Bump version to 3.0.7-24w09a-SNAPSHOT 2024-03-05 20:13:44 +01:00
FlorianMichael 8aea3e43aa Bump version to 3.0.7-SNAPSHOT 2024-03-05 20:11:38 +01:00
FlorianMichael 38e59d7cb5 3.0.6 2024-03-05 19:55:56 +01:00
FlorianMichael 66851feaff [ci skip] Create FUNDING.yml 2024-03-05 13:46:58 +01:00
FlorianMichael 2474f2f347 Merge remote-tracking branch 'origin/master' 2024-03-04 22:18:51 +01:00
FlorianMichael 3322b77afb Merge dev changes into master 2024-03-04 22:18:39 +01:00
FlorianMichael fc7b10e4aa Merge remote-tracking branch 'origin/dev' 2024-03-04 22:15:27 +01:00
FlorianMichael 000c414418 Change dev branch version to 3.0.6-24w07a-SNAPSHOT 2024-03-04 22:13:44 +01:00
FlorianMichael 26b9a83f5a Fixed api usages 2024-02-29 15:25:04 +01:00
FlorianMichael 37a671dfa1 Simplified entity rewriter 2024-02-29 15:21:01 +01:00
FlorianMichael 6a1c89676c Fixed painting rotations in 1.7 -> 1.8 2024-02-29 14:51:56 +01:00
FlorianMichael f0706eca23 Cleaned up token replacement 2024-02-29 14:22:15 +01:00
FlorianMichael 0610ed53ab Finished ReplacementEntityTracker rewrite for now (?) 2024-02-29 14:10:11 +01:00
FlorianMichael dbe26e0ecc Move some classes 2024-02-29 14:04:17 +01:00
FlorianMichael 62606d604e Random code cleanup 2024-02-29 14:01:44 +01:00
FlorianMichael 7254e1ce42 [ci skip] Removed debug code 2024-02-29 13:53:32 +01:00
FlorianMichael b3b6bb325f Proper include of project description 2024-02-29 13:33:21 +01:00
FlorianMichael a0eb8aee24 Mark VR as library for ModMenu 2024-02-29 12:25:16 +01:00
FlorianMichael 630e0224e6 Use equals in legacy custom payload channel comparisons 2024-02-29 12:23:12 +01:00
EnZaXD 224cc121d7 Merge pull request #488 from Kichura/master
paste.gg -> mclo.gs
2024-02-18 23:12:57 +01:00
Kichura a6d9b601d1 paste.gg -> mclo.gs. 2024-02-18 23:10:28 +01:00
FlorianMichael 97044dbe2c Back to VV master 2024-02-18 22:43:35 +01:00
FlorianMichael bb5610c072 Added ViaRewindPlatform#getDataFolder to match VV/VB style 2024-02-18 22:27:08 +01:00
FlorianMichael 57997b25cf Sync fabric.mod.json description with project description 2024-02-18 22:18:33 +01:00
FlorianMichael fc85a00d8c Updated mcVersions in gradle.properties 2024-02-14 20:41:47 +01:00
FlorianMichael f6ceeba636 Updated Via API usage 2024-02-14 20:39:57 +01:00
FlorianMichael 66c810c284 Merge remote-tracking branch 'origin/master' into dev 2024-01-26 15:28:48 +01:00
EnZaXD 3422d90882 Merge pull request #481 from Kichura/master
Update JDK to 17, Cache to v4
2024-01-20 21:24:04 +01:00
Kichura 1f4ab995c5 Update JDK to 17, Cache to v4. 2024-01-20 21:13:17 +01:00
EnZaXD 6a726a289d Merge pull request #479 from ItsClairton/master
fix: Add missing creeper metadata
2024-01-19 14:04:00 +01:00
Clairton (Aiko - W11) 4abe3fb7e8 Add missing creeper metadata, index 18 2024-01-18 00:17:13 -03:00
EnZaXD db93bbbc3e Merge pull request #476 from Kichura/master
Update Velocity to 3.3
2024-01-14 17:25:20 +01:00
Kichura dd220ccf7f Update Velocity to 3.3. 2024-01-14 13:09:37 +01:00
FlorianMichael 0a20ead08b Compile against dev branch of VV again ™️ 2024-01-13 06:37:57 +01:00
FlorianMichael 1eb0d1672e Merge branch 'master' into dev 2024-01-13 06:36:29 +01:00
FlorianMichael f0969b5515 Fixed Via API usage 2024-01-13 06:35:20 +01:00
FlorianMichael 05dea07d99 Delete a lot unused code 2024-01-02 18:53:03 +01:00
FlorianMichael 4d3e5264bc Read names 2024-01-02 18:49:13 +01:00
FlorianMichael fba5a1c7d1 Compile against master branch of VV 2024-01-02 18:21:14 +01:00
EnZaXD 171d33525f Merge pull request #473 from ViaVersion/master
Update dev branch for master changes
2024-01-02 18:20:45 +01:00
FlorianMichael 8d35b00fd7 2024 2024-01-01 00:47:57 +01:00
FlorianMichael 572551b670 Fixed 1.8 -> 1.9 explosion packet translation being broken.
Closes https://github.com/ViaVersion/ViaRewind/issues/471
2023-12-28 00:27:33 +01:00
FlorianMichael 531e564d0b Use correct version for serializing the json component 2023-12-27 20:09:35 +01:00
FlorianMichael 81840dc643 Updated Via API usage 2023-12-27 20:03:00 +01:00
FlorianMichael a9f0b72adc Merge remote-tracking branch 'origin/master' 2023-12-27 17:55:23 +01:00
FlorianMichael e1b9c76063 Updated copyright profile 2023-12-27 17:54:52 +01:00
Kichura 2da271ffe7 [ci skip] Update checkout and setup-java to v4. (#470) 2023-12-27 17:26:33 +01:00
Kichura f27b4f0df6 Add description for ViaRewind. (#468)
This properly describes on what viarewind is for when viewing it in Mod Menu.
2023-12-23 11:51:37 +01:00
SplotyCode cf64b7ffcc Fix 1.9->1.8 use item (#466) 2023-12-21 10:19:12 +01:00
FlorianMichael 6829af6cb7 Bump version to 3.0.6-SNAPSHOT 2023-12-13 23:21:04 +01:00
216 changed files with 11964 additions and 12756 deletions

No files matched your search

+14 -2
View File
@@ -1,4 +1,16 @@
root = true
[*]
charset = utf-8
indent_size = 4
indent_style = space
insert_final_newline = true
tab_width = 4
[*.java]
indent_style = tab
ij_java_class_count_to_use_import_on_demand = 999999
ij_java_names_count_to_use_import_on_demand = 999999
ij_java_imports_layout = *, |, $*
ij_java_generate_final_locals = true
ij_java_generate_final_parameters = true
[{*.json,*.yml}]
indent_size = 2
+1
View File
@@ -0,0 +1 @@
.gitea/CODEOWNERS linguist-detectable=false
+3
View File
@@ -0,0 +1,3 @@
# Pull requests request review from the eligible staff team(s).
# One approval from either an Admin or Developer satisfies branch protection.
* @trueog/Admins @trueog/Developers
+2
View File
@@ -0,0 +1,2 @@
github: florianreuth
custom: [ 'https://florianreuth.de/donate', 'https://creeper123123321.github.io/#donate' ]
+7 -7
View File
@@ -1,6 +1,6 @@
name: Bug report
description: Report a bug or console error
labels: [Unconfirmed]
labels: [ Unconfirmed ]
body:
- type: markdown
@@ -23,11 +23,11 @@ body:
attributes:
label: Console Error
description: |
If you encounter warnings/errors in your console, **paste them with https://paste.gg/ and put the paste link here**.
If you encounter warnings/errors in your console, **paste them with https://mclo.gs/ and put the paste link here**.
If the error is small/less than 10 lines, you may put it directly into this field.
value: |
```
Put the paste.gg link or text here.
Put the mclo.gs link or text here.
```
placeholder: Please do not remove the grave accents; simply replace the line of text in the middle.
validations:
@@ -71,9 +71,9 @@ body:
attributes:
label: Additional Server Info
description: |
Do you use a proxy (eg. BungeeCord)? What software do you use and what plugins?
Do you use a proxy (eg. Velocity)? What software do you use and what plugins?
placeholder: |
Example: "I also use BungeeCord with the following plugins: x, y, z"
Example: "I also use Velocity with the following plugins: x, y, z"
validations:
required: false
@@ -82,7 +82,7 @@ body:
label: Checklist
description: Make sure you have followed each of the steps outlined here.
options:
- label: Via plugins are only running on **EITHER** the backend servers (e.g. Paper) **OR** the proxy (e.g. BungeeCord), **not on both**.
- label: Via plugins are only running on **EITHER** the backend servers (e.g. Paper) **OR** the proxy (e.g. Velocity), **not on both**.
required: true
- label: I have included a ViaVersion dump.
required: true
@@ -91,4 +91,4 @@ body:
- label: I have tried the latest build(s) from https://ci.viaversion.com/ and the issue still persists.
required: true
- label: I have looked at https://www.spigotmc.org/resources/viarewind-legacy-support.52924/ and it does not offer a fix for my problem
required: true
required: true
+18 -18
View File
@@ -5,34 +5,34 @@ labels: [ Feature Request ]
body:
- type: textarea
attributes:
label: Problem Description
description: |
Describe the issue you are facing or why you need the feature to be added.
placeholder: |
I am always frustrated with...
label: Problem Description
description: |
Describe the issue you are facing or why you need the feature to be added.
placeholder: |
I am always frustrated with...
validations:
required: true
required: true
- type: textarea
attributes:
label: Solution Description
description: |
Describe the solution you would like to see.
label: Solution Description
description: |
Describe the solution you would like to see.
validations:
required: true
required: true
- type: textarea
attributes:
label: Alternatives
description: |
Describe alternatives you have considered.
label: Alternatives
description: |
Describe alternatives you have considered.
validations:
required: false
required: false
- type: textarea
attributes:
label: Additional Info
description: |
Does the feature apply to any specific version or environment?
label: Additional Info
description: |
Does the feature apply to any specific version or environment?
validations:
required: false
required: false
+14
View File
@@ -0,0 +1,14 @@
version: 2
updates:
- package-ecosystem: "gradle"
cooldown:
default-days: 7
directory: "/"
schedule:
interval: "monthly"
- package-ecosystem: "github-actions"
cooldown:
default-days: 7
directory: "/"
schedule:
interval: "monthly"
+22 -17
View File
@@ -1,28 +1,33 @@
name: ViaRewind CI
name: Build
on: [pull_request, push, workflow_dispatch]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-22.04
# Only run on PRs if the source branch is on a different repo. We do not need to run everything twice.
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Set up JDK 8
uses: actions/setup-java@v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
with:
cache-disabled: false
cache-provider: basic
- name: Set up JDK 17
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: 'temurin'
java-version: 8
java-version: 17
check-latest: true
- name: Cache Dependencies
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build with Gradle
run: ./gradlew build
- name: Upload Artifacts to GitHub
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: Artifacts
path: build/libs/
+25 -9
View File
@@ -4,24 +4,40 @@ on:
branches:
- master
- dev
workflow_dispatch:
permissions:
contents: read
jobs:
publish:
if: github.repository_owner == 'ViaVersion'
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Set up JDK 8
uses: actions/setup-java@v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
with:
cache-disabled: false
cache-provider: basic
- name: Set up JDK 17
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: 'temurin'
java-version: 8
java-version: 17
check-latest: true
- name: Publish
- name: Build with Gradle
run: ./gradlew build
- name: Publish to Hangar
env:
HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }}
run: ./gradlew publishAllPublicationsToHangar --stacktrace
continue-on-error: true
- name: Publish to Modrinth
env:
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
run: ./gradlew build modrinth publishAllPublicationsToHangar
run: ./gradlew modrinth --stacktrace
continue-on-error: true
+20 -97
View File
@@ -1,113 +1,36 @@
### Java files ###
*.class
# Gradle
# Package Files
#*.jar
*.war
*.ear
.gradle/
build/
out/
classes/
.kotlin/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# Eclipse
*.launch
# Idea
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
# Ignore project files
.idea/
!.idea/copyright/*
!.idea/scopes/*
*.iml
# Ignore IDEA directory
.idea/*
# Include the project's dictionary
!.idea/dictionaries/
!.idea/dictionaries/*
# File-based project format:
*.ipr
*.iws
### Plugin-specific files: ###
# IntelliJ
/out/
# VSCode
# 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
.vscode/
bin/
.classpath
.project
# External tool builders
.externalToolBuilders/
# macOS
# Locally stored "Eclipse launch configurations"
*.launch
DS_Store
# CDT-specific
.cproject
# Misc
# 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
run/
@@ -1,5 +1,5 @@
<component name="CopyrightManager">
<settings>
<settings default="viarewind-gpl">
<module2copyright>
<element module="ViaRewind" copyright="viarewind-gpl" />
</module2copyright>
+1 -1
View File
@@ -1,6 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind&#10;Copyright (C) &amp;#36;originalComment.match(&quot;Copyright \(C\) (\d+)&quot;, 1, &quot;-&quot;)&amp;#36;today.year ViaVersion and contributors&#10;&#10;This program is free software: you can redistribute it and/or modify&#10;it under the terms of the GNU General Public License as published by&#10;the Free Software Foundation, either version 3 of the License, or&#10;(at your option) any later version.&#10;&#10;This program is distributed in the hope that it will be useful,&#10;but WITHOUT ANY WARRANTY; without even the implied warranty of&#10;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10;GNU General Public License for more details.&#10;&#10;You should have received a copy of the GNU General Public License&#10;along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;." />
<option name="notice" value="This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind&#10;Copyright (C) 2018-&amp;#36;today.year ViaVersion and contributors&#10;&#10;This program is free software: you can redistribute it and/or modify&#10;it under the terms of the GNU General Public License as published by&#10;the Free Software Foundation, either version 3 of the License, or&#10;(at your option) any later version.&#10;&#10;This program is distributed in the hope that it will be useful,&#10;but WITHOUT ANY WARRANTY; without even the implied warranty of&#10;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10;GNU General Public License for more details.&#10;&#10;You should have received a copy of the GNU General Public License&#10;along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;." />
<option name="myName" value="viarewind-gpl" />
</copyright>
</component>
+28 -7
View File
@@ -1,22 +1,32 @@
# ViaRewind
[![Latest Release](https://img.shields.io/github/v/release/ViaVersion/ViaRewind)](https://github.com/ViaVersion/ViaRewind/releases)
[![Build Status](https://github.com/ViaVersion/ViaRewind/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/ViaVersion/ViaRewind/actions)
[![Discord](https://img.shields.io/badge/chat-on%20discord-blue.svg)](https://viaversion.com/discord)
**ViaVersion addon to allow 1.8.x and 1.7.x clients on newer server versions.** <br>
Runs on 1.9-latest servers or 1.8 clients and lower.
**You can override the included version in [ViaFabric](https://modrinth.com/mod/viafabric) or [ViaProxy](https://github.com/ViaVersion/ViaProxy):**
**You can override the included version in [ViaFabric](https://modrinth.com/mod/viafabric)
or [ViaProxy](https://github.com/ViaVersion/ViaProxy):**
- in **ViaFabric**, put ViaRewind into the `mods` folder
- in **ViaProxy**, put ViaRewind into the `jars` folder
**Depending on the platform and version, this also requires [ViaVersion](https://modrinth.com/mod/viaversion) and [ViaBackwards](https://modrinth.com/mod/viabackwards).**
Note: when using ViaFabric <= 1.16.5 or J8 ViaProxy builds, you
need [J8 ViaRewind](https://ci.viaversion.com/view/ViaRewind/job/ViaRewind-Java8/) builds.
Support Status
-
While ViaRewind will keep getting updates to function with changes to ViaVersion or ViaBackwards, it will likely not receive many bug fixes or additional features anymore.
**Requires [ViaVersion](https://hangar.papermc.io/ViaVersion/ViaVersion)
and [ViaBackwards](https://hangar.papermc.io/ViaVersion/ViaBackwards) to be installed..**
Releases / Dev Builds
Releases/Dev Builds
-
You can find releases in the following places:
- **Hangar (for our plugins)**: https://hangar.papermc.io/ViaVersion/ViaRewind
- **Modrinth (for our mods)**: https://modrinth.com/mod/viarewind
- **GitHub**: https://github.com/ViaVersion/ViaRewind/releases
Dev builds for **all** of our projects are on our Jenkins server:
- **Jenkins**: https://ci.viaversion.com/view/ViaRewind/
@@ -27,4 +37,15 @@ Other Links
**Issue tracker:** https://github.com/ViaVersion/ViaRewind/issues
**List of contributors:** https://github.com/ViaVersion/ViaRewind/graphs/contributors
**List of contributors:** https://github.com/ViaVersion/ViaRewind/graphs/contributors
Building
-
After cloning this repository, build the project with Gradle by running `./gradlew build` and take the created jar out
of the `build/libs` directory.
You need JDK 17 or newer to build ViaRewind.
License
-
This project is licensed under the [GNU General Public License Version 3](LICENSE).
+15
View File
@@ -0,0 +1,15 @@
# Security Policy
## Reporting a Vulnerability
If you discover a **security vulnerability**, please **do not** open a public issue. Instead, use one of the following
**confidential contact methods**:
* **Email:** [security@viaversion.com](mailto:security@viaversion.com)
* **Discord:** Join our [Discord server](https://discord.gg/viaversion) and visit
the [#exploit-report](https://discord.com/channels/316206679014244363/1388847764137316485) channel for further
instructions.
If your issue is **not security-related** (e.g., bug reports, feature requests, or usage questions), please use
the [GitHub Issues page](https://github.com/ViaVersion/ViaRewind/issues) or contact us via
the [Discord server](https://discord.gg/viaversion).
+143
View File
@@ -0,0 +1,143 @@
import de.florianreuth.baseproject.*
plugins {
`java-library`
eclipse
id("io.papermc.hangar-publish-plugin")
id("com.modrinth.minotaur")
id("de.florianreuth.baseproject")
}
allprojects {
setupProject()
setupViaPublishing()
repositories {
mavenCentral()
maven("https://repo.viaversion.com")
maven("https://repo.papermc.io/repository/maven-public")
maven("https://maven.fabricmc.net")
}
}
subprojects {
dependencies {
compileOnly("com.viaversion:viaversion:5.7.2")
compileOnly("com.viaversion:viabackwards:5.7.2")
}
tasks {
processResources {
val projectVersion = project.version
val projectDescription = project.description
filesMatching(listOf("plugin.yml", "fabric.mod.json", "META-INF/sponge_plugins.json")) {
expand(mapOf("version" to projectVersion, "description" to projectDescription))
}
}
}
}
base {
archivesName.set("ViaRewind")
}
val shade = configureShadedDependencies(false) // Only shade, don't add them as dependency
dependencies {
subprojects.forEach {
shade(it)
}
}
tasks {
jar {
manifest {
attributes("paperweight-mappings-namespace" to "mojang")
}
}
}
val branch = branchName()
val baseVersion = version as String
val isRelease = !baseVersion.contains('-')
val isMainBranch = branch == "master"
if (!isRelease || isMainBranch) { // Only publish releases from the main branch
val suffixedVersion = if (isRelease) baseVersion else baseVersion + "+" + System.getenv("GITHUB_RUN_NUMBER")
val changelogContent = if (isRelease) {
"See [GitHub](https://github.com/ViaVersion/ViaRewind) for release notes."
} else {
val commitHash = latestCommitHash()
"[$commitHash](https://github.com/ViaVersion/ViaRewind/commit/$commitHash) ${latestCommitMessage()}"
}
modrinth {
val mcVersions: List<String> = (property("minecraft_versions") as String)
.split(",")
.map { it.trim() }
token.set(System.getenv("MODRINTH_TOKEN"))
projectId.set("viarewind")
versionType.set(if (isRelease) "release" else if (isMainBranch) "beta" else "alpha")
versionNumber.set(suffixedVersion)
versionName.set(suffixedVersion)
changelog.set(changelogContent)
uploadFile.set(tasks.jar.flatMap { it.archiveFile })
gameVersions.set(mcVersions)
loaders.add("fabric")
loaders.add("paper")
loaders.add("folia")
loaders.add("velocity")
autoAddDependsOn.set(false)
detectLoaders.set(false)
dependencies {
required.project("viaversion")
required.project("viabackwards")
optional.project("viafabric")
}
}
tasks.modrinth {
notCompatibleWithConfigurationCache("")
}
hangarPublish {
publications.register("plugin") {
version.set(suffixedVersion)
id.set("ViaRewind")
channel.set(if (isRelease) "Release" else if (isMainBranch) "Snapshot" else "Alpha")
changelog.set(changelogContent)
apiKey.set(System.getenv("HANGAR_TOKEN"))
platforms {
paper {
jar.set(tasks.jar.flatMap { it.archiveFile })
platformVersions.set(listOf(property("minecraft_version_range") as String))
dependencies {
hangar("ViaVersion") {
required = true
}
hangar("ViaBackwards") {
required = true
}
}
}
velocity {
jar.set(tasks.jar.flatMap { it.archiveFile })
platformVersions.set(listOf(property("velocity_version") as String))
dependencies {
hangar("ViaVersion") {
required = true
}
hangar("ViaBackwards") {
required = true
}
}
}
}
}
}
tasks.named("publishPluginPublicationToHangar") {
notCompatibleWithConfigurationCache("")
}
}
-7
View File
@@ -1,7 +0,0 @@
plugins {
id "groovy-gradle-plugin"
}
repositories {
gradlePluginPortal()
}
@@ -1,91 +0,0 @@
plugins {
id "java-library"
id "maven-publish"
}
repositories {
mavenLocal()
maven {
url = uri("https://repo.viaversion.com")
}
maven {
url = uri("https://repo.maven.apache.org/maven2/")
}
maven {
url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
}
maven {
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
}
maven {
url = uri("https://maven.fabricmc.net/")
}
maven {
url = uri("https://repo.spongepowered.org/repository/maven-public/")
}
maven {
url = uri("https://nexus.velocitypowered.com/repository/maven-public/")
}
}
dependencies {
compileOnly "com.viaversion:viaversion:${project.viaversion_version}"
compileOnly "io.netty:netty-all:${project.netty_version}"
compileOnly "com.google.guava:guava:${project.guava_version}"
}
archivesBaseName = project.maven_name
group = project.maven_group
version = project.maven_version
java.sourceCompatibility = JavaVersion.VERSION_1_8
tasks {
// Variable replacements
processResources {
inputs.property "version", project.version
for (final def file in ["plugin.yml", "bungee.yml", "META-INF/sponge_plugins.json", "fabric.mod.json"]) {
filesMatching(file) {
expand "version": version
}
}
}
}
publishing {
repositories {
maven {
name = "Via"
url = "https://repo.viaversion.com/"
credentials(PasswordCredentials)
authentication {
basic(BasicAuthentication)
}
}
}
publications {
main(MavenPublication) {
artifactId = project.maven_name
groupId = project.maven_group
version = project.maven_version
from(components.java)
}
}
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
tasks.withType(Javadoc) {
options.encoding = 'UTF-8'
}
-9
View File
@@ -1,9 +0,0 @@
plugins {
id "com.viaversion.java-conventions"
}
dependencies {
api project(":viarewind-common")
compileOnly(annotationProcessor("org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT"))
}
+4
View File
@@ -0,0 +1,4 @@
dependencies {
compileOnly(project(":viarewind-common"))
compileOnly("org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT")
}
-1
View File
@@ -1 +0,0 @@
maven_name=viarewind-bukkit
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,18 +15,25 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind;
import com.viaversion.viarewind.api.ViaRewindPlatform;
import com.viaversion.viarewind.protocol.v1_9to1_8.provider.InventoryProvider;
import com.viaversion.viarewind.provider.BukkitInventoryProvider;
import com.viaversion.viaversion.api.Via;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import org.bukkit.plugin.java.JavaPlugin;
public class BukkitPlugin extends JavaPlugin implements ViaRewindPlatform {
public BukkitPlugin() {
Via.getManager().addEnableListener(() -> this.init(new File(getDataFolder(), "config.yml")));
}
public BukkitPlugin() {
Via.getManager().addEnableListener(() -> this.init(new File(getDataFolder(), "config.yml")));
}
@Override
public void onEnable() {
final ViaProviders providers = Via.getManager().getProviders();
providers.use(InventoryProvider.class, new BukkitInventoryProvider());
}
}
@@ -0,0 +1,36 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.provider;
import com.viaversion.viarewind.protocol.v1_9to1_8.provider.InventoryProvider;
import com.viaversion.viaversion.api.connection.UserConnection;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public final class BukkitInventoryProvider extends InventoryProvider {
@Override
public boolean hasElytra(final UserConnection connection) {
final Player player = Bukkit.getPlayer(connection.getProtocolInfo().getUuid());
final ItemStack chestplate = player.getInventory().getChestplate();
return chestplate != null && chestplate.getType() == Material.ELYTRA;
}
}
+5 -7
View File
@@ -1,12 +1,10 @@
name: ViaRewind
version: ${version}
main: com.viaversion.viarewind.BukkitPlugin
authors: [ EnZaXD, Gerrygames, creeper123123321 ]
version: ${version}
description: ${description}
website: https://viaversion.com/rewind
api-version: 1.13
folia-supported: true
authors: [Gerrygames, FlorianMichael/EnZaXD, creeper123321123]
website: https://viaversion.com/rewind
load: STARTUP
depend: [ViaVersion]
softdepend: [ViaBackwards]
depend: [ ViaVersion, ViaBackwards ]
-9
View File
@@ -1,9 +0,0 @@
plugins {
id "com.viaversion.java-conventions"
}
dependencies {
api project(":viarewind-common")
compileOnly(annotationProcessor("net.md-5:bungeecord-api:1.19-R0.1-SNAPSHOT"))
}
-1
View File
@@ -1 +0,0 @@
maven_name=viarewind-bungee
-7
View File
@@ -1,7 +0,0 @@
name: ViaRewind
main: com.viaversion.viarewind.BungeePlugin
authors: [Gerrygames, FlorianMichael/EnZaXD, creeper123321123]
version: ${version}
depends: [ViaVersion]
softdepends: [ViaBackwards]
website: https://viaversion.com/rewind
-28
View File
@@ -1,28 +0,0 @@
plugins {
id "com.viaversion.java-conventions"
}
plugins {
id "net.raphimc.class-token-replacer" version "1.0.0"
}
dependencies {
}
sourceSets {
main {
classTokenReplacer {
property("\${version}", rootProject.maven_version)
property("\${impl_version}", "git-${project.name}-${rootProject.maven_version}:${project.latestCommitHash()}")
}
}
}
String latestCommitHash() {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = stdout
}
return stdout.toString().trim()
}
+59
View File
@@ -0,0 +1,59 @@
import de.florianreuth.baseproject.latestCommitHash
plugins {
id("net.raphimc.class-token-replacer")
}
val viaProxy: Configuration by configurations.creating
dependencies {
compileOnly("io.netty:netty-all:4.0.20.Final")
compileOnly("com.google.guava:guava:17.0")
compileOnly("com.velocitypowered:velocity-native:3.4.0-SNAPSHOT")
viaProxy("net.raphimc:ViaProxy:[3.0.0,4.0.0)") {
isTransitive = false
}
}
sourceSets.configureEach {
classTokenReplacer {
replaceInPlace.set(true)
property("\${version}", project.version)
property("\${impl_version}", "git-ViaRewind-${project.version}:${latestCommitHash()}")
}
}
// Task to quickly test/debug code changes using https://github.com/ViaVersion/ViaProxy
// For further instructions see the ViaProxy repository README
val prepareViaProxyFiles by tasks.registering(Copy::class) {
dependsOn(project.tasks.jar)
from(project.tasks.jar.get().archiveFile.get().asFile)
into(layout.projectDirectory.dir("run/jars"))
val projectName = project.name
rename { "${projectName}.jar" }
}
val cleanupViaProxyFiles by tasks.registering(Delete::class) {
delete(
layout.projectDirectory.file("run/jars/${project.name}.jar"),
layout.projectDirectory.dir("run/logs")
)
}
tasks.register<JavaExec>("runViaProxy") {
dependsOn(prepareViaProxyFiles)
finalizedBy(cleanupViaProxyFiles)
mainClass.set("net.raphimc.viaproxy.ViaProxy")
classpath = viaProxy
workingDir = layout.projectDirectory.dir("run").asFile
jvmArgs = listOf("-DskipUpdateCheck")
if (System.getProperty("viaproxy.gui.autoStart") != null) {
jvmArgs("-Dviaproxy.gui.autoStart")
}
}
-1
View File
@@ -1 +0,0 @@
maven_name=viarewind-common
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind;
import com.google.common.base.Preconditions;
@@ -24,21 +23,21 @@ import com.viaversion.viarewind.api.ViaRewindPlatform;
public class ViaRewind {
private static ViaRewindPlatform platform;
private static ViaRewindConfig config;
private static ViaRewindPlatform platform;
private static ViaRewindConfig config;
public static void init(ViaRewindPlatform platform, ViaRewindConfig config) {
Preconditions.checkArgument(ViaRewind.platform == null, "ViaRewind is already initialized");
public static void init(ViaRewindPlatform platform, ViaRewindConfig config) {
Preconditions.checkArgument(ViaRewind.platform == null, "ViaRewind is already initialized");
ViaRewind.platform = platform;
ViaRewind.config = config;
}
ViaRewind.platform = platform;
ViaRewind.config = config;
}
public static ViaRewindPlatform getPlatform() {
return ViaRewind.platform;
}
public static ViaRewindPlatform getPlatform() {
return ViaRewind.platform;
}
public static ViaRewindConfig getConfig() {
return ViaRewind.config;
}
public static ViaRewindConfig getConfig() {
return ViaRewind.config;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,67 +15,129 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind;
import com.viaversion.viaversion.util.Config;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
public class ViaRewindConfig extends Config implements com.viaversion.viarewind.api.ViaRewindConfig {
public ViaRewindConfig(File configFile) {
super(configFile);
reload();
private CooldownIndicator cooldownIndicator;
private boolean replaceAdventureMode;
private boolean replaceParticles;
private int maxBookPages;
private int maxBookPageSize;
private boolean emulateWorldBorder;
private boolean alwaysShowOriginalMobName;
private String worldBorderParticle;
private boolean enableOffhand;
private String offhandCommand;
private boolean emulateLevitationEffect;
private boolean handlePlayerCombatPacket;
public ViaRewindConfig(File configFile, Logger logger) {
super(configFile, logger);
}
@Override
public void reload() {
super.reload();
loadFields();
}
private void loadFields() {
cooldownIndicator = CooldownIndicator.valueOf(getString("cooldown-indicator", "TITLE").toUpperCase());
replaceAdventureMode = getBoolean("replace-adventure", false);
replaceParticles = getBoolean("replace-particles", false);
maxBookPages = getInt("max-book-pages", 100);
maxBookPageSize = getInt("max-book-page-length", 5000);
emulateWorldBorder = getBoolean("emulate-world-border", true);
alwaysShowOriginalMobName = getBoolean("always-show-original-mob-name", true);
worldBorderParticle = getString("world-border-particle", "fireworksSpark");
enableOffhand = getBoolean("enable-offhand", true);
offhandCommand = getString("offhand-command", "/offhand");
emulateLevitationEffect = getBoolean("emulate-levitation-effect", true);
handlePlayerCombatPacket = getBoolean("handle-player-combat-packet", true);
}
@Override
public CooldownIndicator getCooldownIndicator() {
return CooldownIndicator.valueOf(getString("cooldown-indicator", "TITLE").toUpperCase());
return cooldownIndicator;
}
@Override
public boolean isReplaceAdventureMode() {
return getBoolean("replace-adventure", false);
return replaceAdventureMode;
}
@Override
public boolean isReplaceParticles() {
return getBoolean("replace-particles", false);
return replaceParticles;
}
@Override
public int getMaxBookPages() {
return getInt("max-book-pages", 100);
return maxBookPages;
}
@Override
public int getMaxBookPageSize() {
return getInt("max-book-page-length", 5000);
return maxBookPageSize;
}
@Override
public boolean isEmulateWorldBorder() {
return getBoolean("emulate-world-border", true);
}
@Override
public boolean isEmulateWorldBorder() {
return emulateWorldBorder;
}
@Override
public String getWorldBorderParticle() {
return getString("world-border-particle", "fireworksSpark");
}
@Override
public boolean alwaysShowOriginalMobName() {
return alwaysShowOriginalMobName;
}
@Override
@Override
public String getWorldBorderParticle() {
return worldBorderParticle;
}
@Override
public boolean isEnableOffhand() {
return enableOffhand;
}
@Override
public String getOffhandCommand() {
return offhandCommand;
}
@Override
public boolean emulateLevitationEffect() {
return emulateLevitationEffect;
}
@Override
public boolean handlePlayerCombatPacket() {
return handlePlayerCombatPacket;
}
@Override
public URL getDefaultConfigURL() {
return getClass().getClassLoader().getResource("assets/viarewind/config.yml");
}
@Override
protected void handleConfig(Map<String, Object> map) {
public InputStream getDefaultConfigInputStream() {
return getClass().getClassLoader().getResourceAsStream("assets/viarewind/config.yml");
}
@Override
protected void handleConfig(Map<String, Object> map) {
}
@Override
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,19 +15,29 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind;
import com.viaversion.viarewind.api.ViaRewindPlatform;
import com.viaversion.viaversion.api.Via;
import net.md_5.bungee.api.plugin.Plugin;
import java.io.File;
import java.util.logging.Logger;
public class BungeePlugin extends Plugin implements ViaRewindPlatform {
public class ViaRewindPlatformImpl implements ViaRewindPlatform {
@Override
public void onLoad() {
Via.getManager().addEnableListener(() -> this.init(new File(getDataFolder(), "config.yml")));
}
private final Logger logger;
public ViaRewindPlatformImpl() {
logger = Via.getPlatform().createLogger("ViaRewind");
init(new File(getDataFolder(), "viarewind.yml"));
}
@Override
public Logger getLogger() {
return logger;
}
@Override
public File getDataFolder() {
return Via.getPlatform().getDataFolder();
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api;
import com.viaversion.viaversion.api.configuration.Config;
@@ -25,62 +24,97 @@ import com.viaversion.viaversion.api.configuration.Config;
*/
public interface ViaRewindConfig extends Config {
enum CooldownIndicator {
TITLE, ACTION_BAR, BOSS_BAR, DISABLED
}
/**
* Specifies how 1.8.x clients should see the cooldown indicator
* You can choose between TITLE, ACTION_BAR, BOSS_BAR and DISABLED
* ONLY DISABLE IF YOU HAVE 1.9 COOLDOWN DISABLED ON YOUR SERVER
* 1.8 PLAYERS MAY ASK WHY PVP IS NOT WORKING OTHERWISE
*
* @return the cooldown indicator
*/
CooldownIndicator getCooldownIndicator();
/**
* Specifies how 1.8.x clients should see the cooldown indicator
* You can choose between TITLE, ACTION_BAR, BOSS_BAR and DISABLED
* ONLY DISABLE IF YOU HAVE 1.9 COOLDOWN DISABLED ON YOUR SERVER
* 1.8 PLAYERS MAY ASK WHY PVP IS NOT WORKING OTHERWISE
*
* @return the cooldown indicator
*/
CooldownIndicator getCooldownIndicator();
/**
* Replaces Adventure mode with Survival mode for 1.7.x clients
* Enable this option if your server is using the 'CanDestroy'
* or 'CanPlaceOn' flags on items
*
* @return true if enabled
*/
boolean isReplaceAdventureMode();
/**
* Replaces Adventure mode with Survival mode for 1.7.x clients
* Enable this option if your server is using the 'CanDestroy'
* or 'CanPlaceOn' flags on items
*
* @return true if enabled
*/
boolean isReplaceAdventureMode();
/**
* Whether 1.9 particles should be replaced by similar ones in
* 1.8 and lower
*
* @return true if enabled
*/
boolean isReplaceParticles();
/**
* Whether 1.9 particles should be replaced by similar ones in
* 1.8 and lower
*
* @return true if enabled
*/
boolean isReplaceParticles();
/**
* Max amount of pages for written books before a client gets kicked
*
* @return the max amount of pages
*/
int getMaxBookPages();
/**
* Max amount of pages for written books before a client gets kicked
*
* @return the max amount of pages
*/
int getMaxBookPages();
/**
* Max amount of characters in the json (!) string of a book page before a client gets kicked
*
* @return the max amount of characters
*/
int getMaxBookPageSize();
/**
* Max amount of characters in the json (!) string of a book page before a client gets kicked
*
* @return the max amount of characters
*/
int getMaxBookPageSize();
/**
* Whether to emulate the 1.8+ world border for 1.7.x clients
*
* @return true if enabled
*/
boolean isEmulateWorldBorder();
/**
* Whether to emulate the 1.8+ world border for 1.7.x clients
*
* @return true if enabled
*/
boolean isEmulateWorldBorder();
/**
* Always shows the original mob's name instead of only when hovering over them with the cursor.
*
* @return true if enabled
*/
boolean alwaysShowOriginalMobName();
/**
* The particle to show the world border for the 1.8+ world border for 1.7.x clients
*
* @return the particle name (see <a href="https://wiki.vg/index.php?title=Protocol&oldid=7368#Particle_2">Particle registry for Packet</a>)
*/
String getWorldBorderParticle();
/**
* The particle to show the world border for the 1.8+ world border for 1.7.x clients
*
* @return the particle name
*/
String getWorldBorderParticle();
/**
* If enabled, 1.8 players on 1.9+ servers can use /offhand to switch items between their main hand and offhand.
*
* @return true if enabled
*/
boolean isEnableOffhand();
/**
* Allows to define the offhand command
*
* @return the offhand command
*/
String getOffhandCommand();
/**
* If enabled, 1.8 players on 1.9+ servers will also experience the levitation effect by sending velocity packets.
*
* @return true if enabled
*/
boolean emulateLevitationEffect();
/**
* If enabled, 1.8 players will handle the player combat packet added in 1.9 by showing the custom death message above the hotbar.
*
* @return true if enabled
*/
boolean handlePlayerCombatPacket();
enum CooldownIndicator {
TITLE, ACTION_BAR, BOSS_BAR, DISABLED
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,18 +15,16 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.ViaRewindConfig;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.Protocol1_7_2_5To1_7_6_10;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.Protocol1_7_6_10To1_7_2_5;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
import com.viaversion.viarewind.protocol.v1_9to1_8.Protocol1_9To1_8;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.ProtocolManager;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.io.File;
import java.util.logging.Logger;
@@ -35,32 +33,62 @@ import java.util.logging.Logger;
*/
public interface ViaRewindPlatform {
String VERSION = "${version}";
String IMPL_VERSION = "${impl_version}";
String VERSION = "${version}";
String IMPL_VERSION = "${impl_version}";
/**
* Initialize ViaRewind
*/
default void init(final File configFile) {
ViaRewindConfig config = new ViaRewindConfig(configFile);
config.reload();
Via.getManager().getConfigurationProvider().register(config);
default void init(final File configFile) {
init(new ViaRewindConfig(configFile, getLogger()));
}
ViaRewind.init(this, config);
/**
* Initialize ViaRewind
*/
default void init(final com.viaversion.viarewind.api.ViaRewindConfig config) {
config.reload();
Via.getManager().getConfigurationProvider().register(config);
Via.getManager().getSubPlatforms().add(IMPL_VERSION);
ViaRewind.init(this, config);
final ProtocolManager protocolManager = Via.getManager().getProtocolManager();
Via.getManager().getSubPlatforms().add(IMPL_VERSION);
protocolManager.registerProtocol(new Protocol1_7_2_5To1_7_6_10(), ProtocolVersion.v1_7_1, ProtocolVersion.v1_7_6);
protocolManager.registerProtocol(new Protocol1_7_6_10To1_8(), ProtocolVersion.v1_7_6, ProtocolVersion.v1_8);
protocolManager.registerProtocol(new Protocol1_8To1_9(), ProtocolVersion.v1_8, ProtocolVersion.v1_9);
}
getLogger().info("Registering protocols...");
final ProtocolManager protocolManager = Via.getManager().getProtocolManager();
protocolManager.registerProtocol(new Protocol1_7_6_10To1_7_2_5(), ProtocolVersion.v1_7_2, ProtocolVersion.v1_7_6);
protocolManager.registerProtocol(new Protocol1_8To1_7_6_10(), ProtocolVersion.v1_7_6, ProtocolVersion.v1_8);
protocolManager.registerProtocol(new Protocol1_9To1_8(), ProtocolVersion.v1_8, ProtocolVersion.v1_9);
}
/**
* Get the platform logger
*
* @return the logger
*/
Logger getLogger();
/**
* Returns ViaRewind's data folder.
*
* @return data folder
*/
File getDataFolder();
/**
* Returns the platform's compression handler name. Only used in the 1.8 -> 1.7 protocol.
*
* @return the compression handler name
*/
default String compressHandlerName() {
return "compress";
}
/**
* Returns the platform's decompression handler name. Only used in the 1.8 -> 1.7 protocol.
*
* @return the decompression handler name
*/
default String decompressHandlerName() {
return "decompress";
}
/**
* Get the platform logger
*
* @return the logger
*/
Logger getLogger();
}
@@ -0,0 +1,40 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.data;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
import com.viaversion.viarewind.ViaRewind;
import java.util.logging.Logger;
public class RewindMappingData extends BackwardsMappingData {
public RewindMappingData(String unmappedVersion, String mappedVersion) {
super(unmappedVersion, mappedVersion);
}
@Override
protected Logger getLogger() {
return ViaRewind.getPlatform().getLogger();
}
@Override
protected CompoundTag readMappingsFile(String name) {
return RewindMappingDataLoader.INSTANCE.loadNBTFromDir(name);
}
}
@@ -0,0 +1,43 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.data;
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
import com.viaversion.viarewind.ViaRewind;
import java.io.File;
import java.util.logging.Logger;
public class RewindMappingDataLoader extends BackwardsMappingDataLoader {
public static final RewindMappingDataLoader INSTANCE = new RewindMappingDataLoader();
public RewindMappingDataLoader() {
super(RewindMappingDataLoader.class, "assets/viarewind/data/");
}
@Override
public Logger getLogger() {
return ViaRewind.getPlatform().getLogger();
}
@Override
public File getDataFolder() {
return ViaRewind.getPlatform().getDataFolder();
}
}
@@ -1,102 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.minecraft;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.Protocol;
import java.util.List;
/**
* Represents a model that is replacing an entity on the client side (e.g. armor stand)
*/
public abstract class EntityModel<T extends Protocol<?, ?, ?, ?>> {
protected final UserConnection user;
protected final T protocol;
public EntityModel(final UserConnection user, final T protocol) {
this.user = user;
this.protocol = protocol;
}
/**
* @return The entity id of the entity this model is replacing
*/
public abstract int getEntityId();
/**
* Updates the position of the entity this model is replacing
*
* @param x The new x position
* @param y The new y position
* @param z The new z position
*/
public abstract void updateReplacementPosition(final double x, final double y, final double z);
/**
* Handles the original movement packet of the entity this model is replacing
*
* @param x The x position
* @param y The y position
* @param z The z position
*/
public abstract void handleOriginalMovementPacket(final double x, final double y, final double z);
/**
* Sets the yaw and pitch of the entity this model is replacing
*
* @param yaw The new yaw
* @param pitch The new pitch
*/
public abstract void setYawPitch(final float yaw, final float pitch);
/**
* Sets the head yaw of the entity this model is replacing
*
* @param yaw The new head yaw
*/
public abstract void setHeadYaw(final float yaw);
/**
* Spawns the entity this model is replacing
*/
public abstract void sendSpawnPacket();
/**
* Destroys the entity this model is replacing
*/
public abstract void deleteEntity();
/**
* Updates the metadata of the entity this model is replacing
*
* @param metadataList The new metadata
*/
public abstract void updateMetadata(final List<Metadata> metadataList);
public UserConnection getUser() {
return user;
}
public T getProtocol() {
return protocol;
}
}
@@ -1,78 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.minecraft;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.NibbleArray;
public class ExtendedBlockStorage {
private final byte[] blockLSBArray = new byte[4096];
private final NibbleArray blockMetadataArray = new NibbleArray(this.blockLSBArray.length);
private final NibbleArray blockLightArray = new NibbleArray(this.blockLSBArray.length);
private NibbleArray blockMSBArray;
private NibbleArray skyLightArray;
public ExtendedBlockStorage(final boolean skylight) {
if (skylight) {
this.skyLightArray = new NibbleArray(this.blockLSBArray.length);
}
}
public void setBlockId(final int x, final int y, final int z, final int value) {
this.blockLSBArray[ChunkSection.index(x, y, z)] = (byte) (value & 255);
if (value > 255) {
this.getOrCreateBlockMSBArray().set(x, y, z, (value & 0xF00) >> 8);
} else if (this.blockMSBArray != null) {
this.blockMSBArray.set(x, y, z, 0);
}
}
public void setBlockMetadata(final int x, final int y, final int z, final int value) {
this.blockMetadataArray.set(x, y, z, value);
}
public boolean hasBlockMSBArray() {
return this.blockMSBArray != null;
}
public byte[] getBlockLSBArray() {
return this.blockLSBArray;
}
public NibbleArray getOrCreateBlockMSBArray() {
if (this.blockMSBArray == null) {
return this.blockMSBArray = new NibbleArray(this.blockLSBArray.length);
}
return this.blockMSBArray;
}
public NibbleArray getBlockMetadataArray() {
return this.blockMetadataArray;
}
public NibbleArray getBlockLightArray() {
return this.blockLightArray;
}
public NibbleArray getSkyLightArray() {
return this.skyLightArray;
}
}
@@ -0,0 +1,55 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.minecraft.entitydata;
import com.viaversion.viarewind.api.type.RewindTypes;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
public enum EntityDataTypes1_7_6_10 implements EntityDataType {
BYTE(0, Types.BYTE),
SHORT(1, Types.SHORT),
INT(2, Types.INT),
FLOAT(3, Types.FLOAT),
STRING(4, Types.STRING),
ITEM(5, RewindTypes.COMPRESSED_NBT_ITEM),
POSITION(6, Types.VECTOR);
private final int typeID;
private final Type<?> type;
EntityDataTypes1_7_6_10(int typeID, Type<?> type) {
this.typeID = typeID;
this.type = type;
}
public static EntityDataTypes1_7_6_10 byId(int id) {
return values()[id];
}
@Override
public int typeId() {
return this.typeID;
}
@Override
public Type<?> type() {
return this.type;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,23 +15,22 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.utils.math;
package com.viaversion.viarewind.api.minecraft.math;
public class AABB {
Vector3d min;
Vector3d max;
Vector3d min;
Vector3d max;
public AABB(Vector3d min, Vector3d max) {
this.min = min;
this.max = max;
}
public AABB(Vector3d min, Vector3d max) {
this.min = min;
this.max = max;
}
public Vector3d getMin() {
return this.min;
}
public Vector3d getMin() {
return this.min;
}
public Vector3d getMax() {
return this.max;
}
public Vector3d getMax() {
return this.max;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,23 +15,22 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.utils.math;
package com.viaversion.viarewind.api.minecraft.math;
public class Ray3d {
Vector3d start;
Vector3d dir;
Vector3d start;
Vector3d dir;
public Ray3d(Vector3d start, Vector3d dir) {
this.start = start;
this.dir = dir;
}
public Ray3d(Vector3d start, Vector3d dir) {
this.start = start;
this.dir = dir;
}
public Vector3d getStart() {
return this.start;
}
public Vector3d getStart() {
return this.start;
}
public Vector3d getDir() {
return this.dir;
}
public Vector3d getDir() {
return this.dir;
}
}
@@ -0,0 +1,58 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.minecraft.math;
public class RayTracing {
public static Vector3d trace(Ray3d ray, AABB aabb, double distance) {
Vector3d invDir = new Vector3d(1f / ray.dir.x, 1f / ray.dir.y, 1f / ray.dir.z);
boolean signDirX = invDir.x < 0;
boolean signDirY = invDir.y < 0;
boolean signDirZ = invDir.z < 0;
Vector3d bbox = signDirX ? aabb.max : aabb.min;
double tmin = (bbox.x - ray.start.x) * invDir.x;
bbox = signDirX ? aabb.min : aabb.max;
double tmax = (bbox.x - ray.start.x) * invDir.x;
bbox = signDirY ? aabb.max : aabb.min;
double tymin = (bbox.y - ray.start.y) * invDir.y;
bbox = signDirY ? aabb.min : aabb.max;
double tymax = (bbox.y - ray.start.y) * invDir.y;
if (tmin > tymax || tymin > tmax) return null;
if (tymin > tmin) tmin = tymin;
if (tymax < tmax) tmax = tymax;
bbox = signDirZ ? aabb.max : aabb.min;
double tzmin = (bbox.z - ray.start.z) * invDir.z;
bbox = signDirZ ? aabb.min : aabb.max;
double tzmax = (bbox.z - ray.start.z) * invDir.z;
if (tmin > tzmax || tzmin > tmax) return null;
if (tzmin > tmin) tmin = tzmin;
if (tzmax < tmax) tmax = tzmax;
return tmin <= distance && tmax > 0 ? ray.start.clone().add(ray.dir.clone().normalize().multiply(tmin)) : null;
}
}
@@ -0,0 +1,103 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.minecraft.math;
import com.viaversion.viarewind.protocol.v1_9to1_8.Protocol1_9To1_8;
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.EntityTracker1_9;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Vector;
@Deprecated // ?????????
public class RelativeMoveUtil {
public static Vector[] calculateRelativeMoves(UserConnection user, int entityId, int relX, int relY, int relZ) {
EntityTracker1_9 tracker = user.getEntityTracker(Protocol1_9To1_8.class);
int x;
int y;
int z;
Vector offset = tracker.getEntityOffset(entityId);
if (offset != null) {
relX += offset.blockX();
relY += offset.blockY();
relZ += offset.blockZ();
}
if (relX > Short.MAX_VALUE) {
x = relX - Short.MAX_VALUE;
relX = Short.MAX_VALUE;
} else if (relX < Short.MIN_VALUE) {
x = relX - Short.MIN_VALUE;
relX = Short.MIN_VALUE;
} else {
x = 0;
}
if (relY > Short.MAX_VALUE) {
y = relY - Short.MAX_VALUE;
relY = Short.MAX_VALUE;
} else if (relY < Short.MIN_VALUE) {
y = relY - Short.MIN_VALUE;
relY = Short.MIN_VALUE;
} else {
y = 0;
}
if (relZ > Short.MAX_VALUE) {
z = relZ - Short.MAX_VALUE;
relZ = Short.MAX_VALUE;
} else if (relZ < Short.MIN_VALUE) {
z = relZ - Short.MIN_VALUE;
relZ = Short.MIN_VALUE;
} else {
z = 0;
}
int sentRelX, sentRelY, sentRelZ;
Vector[] moves;
if (relX > Byte.MAX_VALUE * 128 || relX < Byte.MIN_VALUE * 128 || relY > Byte.MAX_VALUE * 128 || relY < Byte.MIN_VALUE * 128 || relZ > Byte.MAX_VALUE * 128 || relZ < Byte.MIN_VALUE * 128) {
byte relX1 = (byte) (relX / 256);
byte relX2 = (byte) (Math.round((relX - relX1 * 128) / 128f));
byte relY1 = (byte) (relY / 256);
byte relY2 = (byte) (Math.round((relY - relY1 * 128) / 128f));
byte relZ1 = (byte) (relZ / 256);
byte relZ2 = (byte) (Math.round((relZ - relZ1 * 128) / 128f));
sentRelX = relX1 + relX2;
sentRelY = relY1 + relY2;
sentRelZ = relZ1 + relZ2;
moves = new Vector[]{new Vector(relX1, relY1, relZ1), new Vector(relX2, relY2, relZ2)};
} else {
sentRelX = Math.round(relX / 128f);
sentRelY = Math.round(relY / 128f);
sentRelZ = Math.round(relZ / 128f);
moves = new Vector[]{new Vector(sentRelX, sentRelY, sentRelZ)};
}
x = x + relX - sentRelX * 128;
y = y + relY - sentRelY * 128;
z = z + relZ - sentRelZ * 128;
tracker.setEntityOffset(entityId, new Vector(x, y, z));
return moves;
}
}
@@ -0,0 +1,128 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.minecraft.math;
import java.util.Objects;
public class Vector3d {
double x, y, z;
public Vector3d(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public Vector3d() {
}
public void set(Vector3d vec) {
this.x = vec.x;
this.y = vec.y;
this.z = vec.z;
}
public Vector3d set(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
return this;
}
public Vector3d multiply(double a) {
this.x *= a;
this.y *= a;
this.z *= a;
return this;
}
public Vector3d add(Vector3d vec) {
this.x += vec.x;
this.y += vec.y;
this.z += vec.z;
return this;
}
public Vector3d substract(Vector3d vec) {
this.x -= vec.x;
this.y -= vec.y;
this.z -= vec.z;
return this;
}
public double length() {
return Math.sqrt(lengthSquared());
}
public double lengthSquared() {
return this.x * this.x + this.y * this.y + this.z * this.z;
}
public Vector3d normalize() {
double length = length();
multiply(1.0 / length);
return this;
}
@Override
public Vector3d clone() {
return new Vector3d(this.x, this.y, this.z);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Vector3d vector3d = (Vector3d) o;
return Double.compare(vector3d.x, x) == 0 && Double.compare(vector3d.y, y) == 0 && Double.compare(vector3d.z, z) == 0;
}
@Override
public int hashCode() {
return Objects.hash(x, y, z);
}
@Override
public String toString() {
return "Vector3d{" + "x=" + x + ", y=" + y + ", z=" + z + '}';
}
public double getX() {
return this.x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return this.y;
}
public void setY(double y) {
this.y = y;
}
public double getZ() {
return this.z;
}
public void setZ(double z) {
this.z = z;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,8 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.netty;
package com.viaversion.viarewind.api.minecraft.netty;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerAdapter;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,8 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.netty;
package com.viaversion.viarewind.api.minecraft.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -24,8 +23,8 @@ import io.netty.handler.codec.MessageToByteEncoder;
public class ForwardMessageToByteEncoder extends MessageToByteEncoder<ByteBuf> {
@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) {
out.writeBytes(msg);
}
@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) {
out.writeBytes(msg);
}
}
@@ -1,86 +0,0 @@
package com.viaversion.viarewind.api.rewriter;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model.MetaIndex1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.metadata.MetaType1_7_6_10;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.ClientEntityIdChangeListener;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.util.Pair;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ReplacementEntityTracker extends StoredObject implements ClientEntityIdChangeListener {
private final Map<EntityTypes1_10.EntityType, Pair<EntityTypes1_10.EntityType, String>> ENTITY_REPLACEMENTS = new HashMap<>();
private final Map<Integer, EntityTypes1_10.EntityType> entityMap = new HashMap<>();
private final Map<Integer, EntityTypes1_10.EntityType> entityReplacementMap = new HashMap<>();
private int playerId = -1;
private final ProtocolVersion version;
public ReplacementEntityTracker(UserConnection user, final ProtocolVersion version) {
super(user);
this.version = version;
}
public void registerEntity(final EntityTypes1_10.EntityType oldType, final EntityTypes1_10.EntityType newType, final String name) {
ENTITY_REPLACEMENTS.put(oldType, new Pair<>(newType, this.version.getName() + " " + name));
}
public void addEntity(final int entityId, final EntityTypes1_10.EntityType type) {
entityMap.put(entityId, type);
}
public int replaceEntity(final int entityId, final EntityTypes1_10.EntityType type) {
entityReplacementMap.put(entityId, type);
return ENTITY_REPLACEMENTS.get(type).key().getId();
}
public void removeEntity(final int entityId) {
entityMap.remove(entityId);
entityReplacementMap.remove(entityId);
}
public void clear() {
entityMap.clear();
entityReplacementMap.clear();
}
public boolean isReplaced(final EntityTypes1_10.EntityType type) {
return ENTITY_REPLACEMENTS.containsKey(type);
}
public void updateMetadata(final int entityId, final List<Metadata> metadata) throws Exception {
final String name = ENTITY_REPLACEMENTS.get(entityMap.get(entityId)).value();
metadata.add(new Metadata(MetaIndex1_7_6_10To1_8.ENTITY_LIVING_NAME_TAG_VISIBILITY.getNewIndex(), MetaType1_7_6_10.Byte, (byte) 1)); // TODO: Make this definable for 1.8 -> 1.9 ?
metadata.add(new Metadata(MetaIndex1_7_6_10To1_8.ENTITY_LIVING_NAME_TAG.getNewIndex(), MetaType1_7_6_10.String, name));
}
@Override
public void setClientEntityId(int entityId) {
removeEntity(this.playerId);
addEntity(entityId, EntityTypes1_10.EntityType.ENTITY_HUMAN);
this.playerId = entityId;
}
public Map<Integer, EntityTypes1_10.EntityType> getEntityMap() {
return entityMap;
}
public Map<Integer, EntityTypes1_10.EntityType> getEntityReplacementMap() {
return entityReplacementMap;
}
public int getPlayerId() {
return playerId;
}
}
@@ -0,0 +1,42 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.rewriter;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.rewriters.LegacyBlockItemRewriter;
import com.viaversion.viarewind.api.data.RewindMappingDataLoader;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.libs.gson.JsonObject;
public class VRBlockItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType, T extends BackwardsProtocol<C, ?, ?, S>> extends LegacyBlockItemRewriter<C, S, T> {
protected VRBlockItemRewriter(T protocol, String name) {
super(protocol, name);
}
@Override
protected JsonObject readMappingsFile(String name) {
return RewindMappingDataLoader.INSTANCE.loadFromDataDir(name);
}
@Override
public String nbtTagName() {
return "VR|" + protocol.getClass().getSimpleName();
}
}
@@ -0,0 +1,66 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.rewriter;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.rewriters.LegacyEntityRewriter;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_8;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
public abstract class VREntityRewriter<C extends ClientboundPacketType, T extends BackwardsProtocol<C, ?, ?, ?>> extends LegacyEntityRewriter<C, T> {
public VREntityRewriter(T protocol) {
super(protocol, EntityDataTypes1_8.STRING, EntityDataTypes1_8.BYTE);
}
public VREntityRewriter(T protocol, EntityDataType displayType, EntityDataType displayVisibilityType) {
super(protocol, displayType, displayVisibilityType);
}
protected void removeEntities(final UserConnection connection, final int[] entities) {
final EntityTrackerBase tracker = tracker(connection);
for (int entityId : entities) {
tracker.removeEntity(entityId);
}
}
protected PacketHandler getDimensionHandler() {
return wrapper -> {
final int dimension = wrapper.get(Types.BYTE, 0);
final ClientWorld clientWorld = wrapper.user().getClientWorld(protocol.getClass());
clientWorld.setEnvironment(dimension);
};
}
@Override
protected Object getDisplayVisibilityDataValue() {
return (byte) 1;
}
@Override
protected boolean alwaysShowOriginalMobName() {
return ViaRewind.getConfig().alwaysShowOriginalMobName();
}
}
@@ -1,106 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.rewriter.item;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.util.ChatColorUtil;
public class Replacement {
private final int id;
private final int data;
private final String name;
private String resetName;
private String bracketName;
public Replacement(final int id) {
this(id, -1);
}
public Replacement(final int id, final int data) {
this(id, data, null);
}
public Replacement(final int id, final String name) {
this(id, -1, name);
}
public Replacement(final int id, final int data, final String name) {
this.id = id;
this.data = data;
this.name = name;
}
public void buildNames(final String protocolVersion) {
if (this.name != null) {
this.resetName = ChatColorUtil.translateAlternateColorCodes("&r" + protocolVersion + " " + this.name);
this.bracketName = ChatColorUtil.translateAlternateColorCodes(" &r&7(" + protocolVersion + " " + this.name + "&r&7)");
}
}
public int getId() {
return id;
}
public int getData() {
return data;
}
public String getName() {
return name;
}
/**
* @param item The item to replace
* @return The replacement for the item or the item if not found
*/
public Item replace(final Item item) {
item.setIdentifier(id); // Set the new id
if (data != -1) {
item.setData((short) data); // Set the new data
}
if (name != null) { // Set the new name
CompoundTag rootTag = item.tag() == null ? new CompoundTag() : item.tag(); // Get root tag or create new one if not exists
if (!rootTag.contains("display")) rootTag.put("display", new CompoundTag()); // Create display tag if not exists
final CompoundTag display = rootTag.get("display");
if (display.contains("Name")) {
final StringTag name = display.get("Name");
if (!name.getValue().equals(resetName) && !name.getValue().endsWith(bracketName)) {
name.setValue(name.getValue() + bracketName); // Append the new name tag
}
} else {
display.put("Name", new StringTag(resetName)); // Set the new name tag
}
item.setTag(rootTag);
}
return item;
}
/**
* @param data The data of the item/block
* @return The replacement data for the item/block
*/
public int replaceData(int data) {
return this.data == -1 ? data : this.data;
}
}
@@ -1,115 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.rewriter.item;
import com.viaversion.viarewind.api.minecraft.IdDataCombine;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
public abstract class ReplacementItemRewriter<T extends AbstractProtocol<?, ?, ?, ?>> implements ItemRewriter<T> {
private final Int2ObjectMap<Replacement> ITEM_REPLACEMENTS = new Int2ObjectOpenHashMap<>();
private final Int2ObjectMap<Replacement> BLOCK_REPLACEMENTS = new Int2ObjectOpenHashMap<>();
private final T protocol;
private final ProtocolVersion protocolVersion;
public ReplacementItemRewriter(final T protocol, final ProtocolVersion protocolVersion) {
this.protocol = protocol;
this.protocolVersion = protocolVersion;
}
public void registerItem(int id, Replacement replacement) {
registerItem(id, -1, replacement);
}
public void registerBlock(int id, Replacement replacement) {
registerBlock(id, -1, replacement);
}
public void registerItemBlock(int id, Replacement replacement) {
registerItemBlock(id, -1, replacement);
}
public void registerItem(int id, int data, Replacement replacement) {
ITEM_REPLACEMENTS.put(generateTrackingId(id, data), replacement);
replacement.buildNames(protocolVersion.getName());
}
public void registerBlock(int id, int data, Replacement replacement) {
BLOCK_REPLACEMENTS.put(generateTrackingId(id, data), replacement);
replacement.buildNames(protocolVersion.getName());
}
public void registerItemBlock(int id, int data, Replacement replacement) {
registerItem(id, data, replacement);
registerBlock(id, data, replacement);
}
/**
* @param item The item to replace
* @return The replacement for the item or the item if not found
*/
public Item replace(Item item) {
Replacement replacement = ITEM_REPLACEMENTS.get(generateTrackingId(item.identifier(), item.data()));
if (replacement == null) replacement = ITEM_REPLACEMENTS.get(generateTrackingId(item.identifier(), -1));
return replacement == null ? item : replacement.replace(item);
}
/**
* @param id The id of the item/block
* @param data The data of the item/block
* @return The replacement for the item/block or null if not found
*/
public Replacement replace(int id, int data) {
Replacement replacement = BLOCK_REPLACEMENTS.get(generateTrackingId(id, data));
if (replacement == null) replacement = BLOCK_REPLACEMENTS.get(generateTrackingId(id, -1));
return replacement;
}
/**
* @param combined The combined id and data
* @return The generated tracking id for the item/block
*/
public int replace(int combined) {
final int data = IdDataCombine.dataFromCombined(combined);
final Replacement replace = replace(IdDataCombine.idFromCombined(combined), data);
return replace != null ? IdDataCombine.toCombined(replace.getId(), replace.replaceData(data)) : combined;
}
/**
* @param id The id of the item/block
* @param data The data of the item/block
* @return The generated tracking id for the item/block
*/
private int generateTrackingId(int id, int data) {
return (id << 16) | (data & 0xFFFF);
}
@Override
public T protocol() {
return this.protocol;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,31 +15,30 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.primitive;
package com.viaversion.viarewind.api.type;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class ByteIntArrayType extends Type<int[]> {
public class IntArrayType extends Type<int[]> {
public ByteIntArrayType() {
super(int[].class);
}
public IntArrayType() {
super(int[].class);
}
@Override
public int[] read(ByteBuf byteBuf) throws Exception {
byte size = byteBuf.readByte();
int[] array = new int[size];
for (byte i = 0; i < size; i++) {
array[i] = byteBuf.readInt();
}
return array;
}
@Override
public int[] read(ByteBuf byteBuf) {
byte size = byteBuf.readByte();
int[] array = new int[size];
for (byte i = 0; i < size; i++) {
array[i] = byteBuf.readInt();
}
return array;
}
@Override
public void write(ByteBuf byteBuf, int[] array) throws Exception {
byteBuf.writeByte(array.length);
for (int i : array) byteBuf.writeInt(i);
}
@Override
public void write(ByteBuf byteBuf, int[] array) {
byteBuf.writeByte(array.length);
for (int i : array) byteBuf.writeInt(i);
}
}
@@ -0,0 +1,52 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import java.util.function.IntFunction;
public class PositionVarYType<T extends Number> extends Type<BlockPosition> {
private final Type<T> yType;
private final IntFunction<T> toY;
public PositionVarYType(final Type<T> yType, final IntFunction<T> toY) {
super(BlockPosition.class);
this.yType = yType;
this.toY = toY;
}
@Override
public BlockPosition read(ByteBuf buffer) {
final int x = buffer.readInt();
final int y = yType.read(buffer).intValue();
final int z = buffer.readInt();
return new BlockPosition(x, y, z);
}
@Override
public void write(ByteBuf buffer, BlockPosition value) {
buffer.writeInt(value.x());
yType.write(buffer, this.toY.apply(value.y()));
buffer.writeInt(value.z());
}
}
@@ -0,0 +1,52 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viarewind.api.type.entitydata.EntityDataListType;
import com.viaversion.viarewind.api.type.entitydata.EntityDataType;
import com.viaversion.viarewind.api.type.item.ItemArrayType;
import com.viaversion.viarewind.api.type.item.ItemType;
import com.viaversion.viarewind.api.type.item.NBTType;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import java.util.List;
/**
* Safe to use before protocol loading
*/
public class RewindTypes {
public static final Type<int[]> INT_ARRAY = new IntArrayType(); // Integer array with byte as length indicator
public static final Type<BlockPosition> SHORT_POSITION = new PositionVarYType<>(Types.SHORT, value -> (short) value);
public static final Type<BlockPosition> INT_POSITION = new PositionVarYType<>(Types.INT, value -> value);
public static final Type<BlockPosition> BYTE_POSITION = new PositionVarYType<>(Types.BYTE, value -> (byte) value);
public static final Type<BlockPosition> U_BYTE_POSITION = new PositionVarYType<>(Types.UNSIGNED_BYTE, value -> (short) value);
public static final Type<CompoundTag> COMPRESSED_NBT = new NBTType();
public static final Type<Item> COMPRESSED_NBT_ITEM = new ItemType();
public static final Type<Item[]> COMPRESSED_NBT_ITEM_ARRAY = new ItemArrayType();
public static final Type<EntityData> ENTITY_DATA1_7 = new EntityDataType();
public static final Type<List<EntityData>> ENTITY_DATA_LIST1_7 = new EntityDataListType(ENTITY_DATA1_7);
}
@@ -0,0 +1,109 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type.chunk;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import java.util.zip.Deflater;
public class BulkChunkType1_7_6 extends Type<Chunk[]> {
public static final BulkChunkType1_7_6 TYPE = new BulkChunkType1_7_6();
public BulkChunkType1_7_6() {
super(Chunk[].class);
}
@Override
public Chunk[] read(ByteBuf byteBuf) {
throw new UnsupportedOperationException(); // Not needed, see https://github.com/ViaVersion/ViaLegacy/blob/main/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/types/ChunkBulk1_7_6Type.java
}
@Override
public void write(ByteBuf buffer, Chunk[] chunks) {
final int chunkCount = chunks.length;
final int[] addBitMasks = new int[chunkCount];
int totalSize = 0;
boolean anySkyLight = false;
for (Chunk chunk : chunks) {
if (ChunkType1_7_6.hasSkyLight(chunk)) {
anySkyLight = true;
break;
}
}
for (int i = 0; i < chunkCount; i++) {
Chunk chunk = chunks[i];
addBitMasks[i] = ChunkType1_7_6.getAddBitMask(chunk);
boolean biomes = chunk.isFullChunk() && chunk.getBiomeData() != null;
totalSize += ChunkType1_7_6.calcSize(
chunk.getBitmask(),
addBitMasks[i],
anySkyLight,
biomes
);
}
final byte[] data = new byte[totalSize];
int offset = 0;
for (int i = 0; i < chunkCount; i++) {
Chunk chunk = chunks[i];
boolean biomes = chunk.isFullChunk() && chunk.getBiomeData() != null;
offset = ChunkType1_7_6.serialize(
chunk,
data,
offset,
addBitMasks[i],
anySkyLight,
biomes
);
}
buffer.writeShort(chunkCount);
final Deflater deflater = new Deflater();
byte[] compressedData;
int compressedSize;
try {
deflater.setInput(data, 0, data.length);
deflater.finish();
compressedData = new byte[data.length];
compressedSize = deflater.deflate(compressedData);
} finally {
deflater.end();
}
buffer.writeInt(compressedSize);
buffer.writeBoolean(anySkyLight);
buffer.writeBytes(compressedData, 0, compressedSize);
for (int i = 0; i < chunkCount; i++) {
Chunk chunk = chunks[i];
buffer.writeInt(chunk.getX());
buffer.writeInt(chunk.getZ());
buffer.writeShort(chunk.getBitmask());
buffer.writeShort(addBitMasks[i]);
}
}
}
@@ -0,0 +1,198 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type.chunk;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import java.util.zip.Deflater;
import static com.viaversion.viaversion.api.minecraft.chunks.ChunkSection.SIZE;
import static com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionLight.LIGHT_LENGTH;
public class ChunkType1_7_6 extends Type<Chunk> {
public static final ChunkType1_7_6 TYPE = new ChunkType1_7_6();
public ChunkType1_7_6() {
super(Chunk.class);
}
@Override
public Chunk read(ByteBuf byteBuf) {
throw new UnsupportedOperationException(); // Not needed, see https://github.com/ViaVersion/ViaLegacy/blob/main/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/types/Chunk1_7_6Type.java
}
@Override
public void write(ByteBuf buffer, Chunk chunk) {
final int bitmask = chunk.getBitmask();
final int addBitmask = getAddBitMask(chunk);
final boolean hasSkyLight = hasSkyLight(chunk);
final boolean biomes = chunk.isFullChunk() && chunk.getBiomeData() != null;
final int size = calcSize(bitmask, addBitmask, hasSkyLight, biomes);
final byte[] data = new byte[size];
serialize(chunk, data, 0, addBitmask, hasSkyLight, biomes);
buffer.writeInt(chunk.getX());
buffer.writeInt(chunk.getZ());
buffer.writeBoolean(chunk.isFullChunk());
buffer.writeShort(bitmask);
buffer.writeShort(addBitmask);
final Deflater deflater = new Deflater();
byte[] compressedData;
int compressedSize;
try {
deflater.setInput(data, 0, data.length);
deflater.finish();
compressedData = new byte[data.length];
compressedSize = deflater.deflate(compressedData);
} finally {
deflater.end();
}
buffer.writeInt(compressedSize);
buffer.writeBytes(compressedData, 0, compressedSize);
}
public static int serialize(Chunk chunk, byte[] output, int offset, int addBitmask, boolean writeSkyLight, boolean biomes) {
final ChunkSection[] sections = chunk.getSections();
final int bitmask = chunk.getBitmask();
for (int i = 0; i < 16; i++) {
if ((bitmask & (1 << i)) != 0) {
final ChunkSection section = sections[i];
final DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int j = 0; j < SIZE; j++) {
final int block = palette.idAt(j);
output[offset++] = (byte) ((block >> 4) & 0xFF);
}
}
}
for (int i = 0; i < 16; i++) {
if ((bitmask & (1 << i)) != 0) {
final ChunkSection section = sections[i];
final DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int j = 0; j < ChunkSection.SIZE; j += 2) {
final int meta1 = palette.idAt(j) & 0xF;
final int meta2 = palette.idAt(j + 1) & 0xF;
output[offset++] = (byte) (meta1 | (meta2 << 4));
}
}
}
for (int i = 0; i < 16; i++) {
if ((bitmask & (1 << i)) != 0) {
final byte[] blockLight = sections[i].getLight().getBlockLight();
System.arraycopy(blockLight, 0, output, offset, LIGHT_LENGTH);
offset += LIGHT_LENGTH;
}
}
if (writeSkyLight) {
for (int i = 0; i < 16; i++) {
if ((bitmask & (1 << i)) != 0) {
if (sections[i].getLight().hasSkyLight()) {
final byte[] skyLight = sections[i].getLight().getSkyLight();
System.arraycopy(skyLight, 0, output, offset, LIGHT_LENGTH);
}
offset += LIGHT_LENGTH;
}
}
}
if (addBitmask != 0) {
for (int i = 0; i < 16; i++) {
if ((bitmask & (1 << i)) != 0 && (addBitmask & (1 << i)) != 0) {
final ChunkSection section = sections[i];
final DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int j = 0; j < SIZE; j += 2) {
final int add1 = (palette.idAt(j) >> 12) & 0xF;
final int add2 = (palette.idAt(j + 1) >> 12) & 0xF;
output[offset++] = (byte) (add1 | (add2 << 4));
}
}
}
}
if (biomes && chunk.getBiomeData() != null) {
final int[] biomeData = chunk.getBiomeData();
for (int biome : biomeData) {
output[offset++] = (byte) biome;
}
}
return offset;
}
public static int calcSize(int bitmask, int addBitmask, boolean hasSkyLight, boolean biomes) {
int size = 0;
int sections = Integer.bitCount(bitmask);
size += sections * SIZE;
size += sections * (SIZE / 2);
size += sections * LIGHT_LENGTH;
if (hasSkyLight) {
size += sections * LIGHT_LENGTH;
}
if (addBitmask != 0) {
size += Integer.bitCount(addBitmask) * (SIZE / 2);
}
if (biomes) {
size += 256;
}
return size;
}
public static int getAddBitMask(Chunk chunk) {
int addBitMask = 0;
for (int i = 0; i < 16; i++) {
if ((chunk.getBitmask() & (1 << i)) != 0) {
final ChunkSection section = chunk.getSections()[i];
final DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int j = 0; j < SIZE; j++) {
final int id = palette.idAt(j);
if ((id >> 12) != 0) {
addBitMask |= (1 << i);
break;
}
}
}
}
return addBitMask;
}
public static boolean hasSkyLight(Chunk chunk) {
for (ChunkSection section : chunk.getSections()) {
if (section != null && section.getLight().hasSkyLight()) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,61 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type.entitydata;
import com.viaversion.viarewind.api.minecraft.entitydata.EntityDataTypes1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataListTypeTemplate;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
public class EntityDataListType extends EntityDataListTypeTemplate {
private final Type<EntityData> type;
public EntityDataListType(Type<EntityData> type) {
this.type = type;
}
@Override
public List<EntityData> read(ByteBuf buffer) {
ArrayList<EntityData> entityData = new ArrayList<>();
EntityData data;
do {
data = type.read(buffer);
if (data != null) {
entityData.add(data);
}
} while (data != null);
return entityData;
}
@Override
public void write(ByteBuf buffer, List<EntityData> entityData) {
for (EntityData meta : entityData) {
type.write(buffer, meta);
}
if (entityData.isEmpty()) {
type.write(buffer, new EntityData(0, EntityDataTypes1_7_6_10.BYTE, (byte) 0));
}
buffer.writeByte(127);
}
}
@@ -0,0 +1,45 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type.entitydata;
import com.viaversion.viarewind.api.minecraft.entitydata.EntityDataTypes1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataTypeTemplate;
import io.netty.buffer.ByteBuf;
public class EntityDataType extends EntityDataTypeTemplate {
@Override
public EntityData read(ByteBuf buffer) {
byte item = buffer.readByte();
if (item == 127) {
return null;
} else {
int typeID = (item & 224) >> 5;
EntityDataTypes1_7_6_10 type = EntityDataTypes1_7_6_10.byId(typeID);
int id = item & 31;
return new EntityData(id, type, type.type().read(buffer));
}
}
@Override
public void write(ByteBuf buffer, EntityData meta) {
int item = (meta.dataType().typeId() << 5 | meta.id() & 31) & 255;
buffer.writeByte(item);
meta.dataType().type().write(buffer, meta.getValue());
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,38 +15,36 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type.item;
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.item;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viarewind.api.type.RewindTypes;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public class ItemArrayType extends Type<Item[]> {
private final boolean compressed;
public ItemArrayType(boolean compressed) {
super(Item[].class);
this.compressed = compressed;
}
public ItemArrayType() {
super(Item[].class);
}
@Override
public Item[] read(ByteBuf buffer) throws Exception {
int amount = Type.SHORT.readPrimitive(buffer);
Item[] items = new Item[amount];
@Override
public Item[] read(ByteBuf buffer) {
int amount = Types.SHORT.readPrimitive(buffer);
Item[] items = new Item[amount];
for (int i = 0; i < amount; ++i) {
items[i] = (compressed ? Types1_7_6_10.COMPRESSED_NBT_ITEM : Types1_7_6_10.ITEM).read(buffer);
}
return items;
}
for (int i = 0; i < amount; ++i) {
items[i] = RewindTypes.COMPRESSED_NBT_ITEM.read(buffer);
}
return items;
}
@Override
public void write(ByteBuf buffer, Item[] items) throws Exception {
Type.SHORT.writePrimitive(buffer, (short) items.length);
for (Item item : items) {
(compressed ? Types1_7_6_10.COMPRESSED_NBT_ITEM : Types1_7_6_10.ITEM).write(buffer, item);
}
}
@Override
public void write(ByteBuf buffer, Item[] items) {
Types.SHORT.writePrimitive(buffer, (short) items.length);
for (Item item : items) {
RewindTypes.COMPRESSED_NBT_ITEM.write(buffer, item);
}
}
}
@@ -0,0 +1,57 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type.item;
import com.viaversion.viarewind.api.type.RewindTypes;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class ItemType extends Type<Item> {
public ItemType() {
super(Item.class);
}
@Override
public Item read(ByteBuf buffer) {
short id = buffer.readShort();
if (id < 0) {
return null;
}
Item item = new DataItem();
item.setIdentifier(id);
item.setAmount(buffer.readByte());
item.setData(buffer.readShort());
item.setTag(RewindTypes.COMPRESSED_NBT.read(buffer));
return item;
}
@Override
public void write(ByteBuf buffer, Item item) {
if (item == null) {
buffer.writeShort(-1);
} else {
buffer.writeShort(item.identifier());
buffer.writeByte(item.amount());
buffer.writeShort(item.data());
RewindTypes.COMPRESSED_NBT.write(buffer, item.tag());
}
}
}
@@ -0,0 +1,72 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type.item;
import com.viaversion.nbt.io.NBTIO;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class NBTType extends Type<CompoundTag> {
public NBTType() {
super(CompoundTag.class);
}
@Override
public CompoundTag read(ByteBuf buffer) {
short length = buffer.readShort();
if (length <= 0) {
return null;
}
ByteBuf compressed = buffer.readSlice(length);
try (GZIPInputStream gzipStream = new GZIPInputStream(new ByteBufInputStream(compressed))) {
return NBTIO.reader(CompoundTag.class).named().read(gzipStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void write(ByteBuf buffer, CompoundTag nbt) {
if (nbt == null) {
buffer.writeShort(-1);
return;
}
ByteBuf compressedBuf = buffer.alloc().buffer();
try {
try (GZIPOutputStream gzipStream = new GZIPOutputStream(new ByteBufOutputStream(compressedBuf))) {
NBTIO.writer().named().write(gzipStream, nbt);
} catch (IOException e) {
throw new RuntimeException(e);
}
buffer.writeShort(compressedBuf.readableBytes());
buffer.writeBytes(compressedBuf);
} finally {
compressedBuf.release();
}
}
}
@@ -1,99 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
public enum ClientboundPackets1_7_2_5 implements ClientboundPacketType {
KEEP_ALIVE, // 0x00
JOIN_GAME, // 0x01
CHAT_MESSAGE, // 0x02
TIME_UPDATE, // 0x03
ENTITY_EQUIPMENT, // 0x04
SPAWN_POSITION, // 0x05
UPDATE_HEALTH, // 0x06
RESPAWN, // 0x07
PLAYER_POSITION, // 0x08
HELD_ITEM_CHANGE, // 0x09
USE_BED, // 0x0A
ENTITY_ANIMATION, // 0x0B
SPAWN_PLAYER, // 0x0C
COLLECT_ITEM, // 0x0D
SPAWN_ENTITY, // 0x0E
SPAWN_MOB, // 0x0F
SPAWN_PAINTING, // 0x10
SPAWN_EXPERIENCE_ORB, // 0x11
ENTITY_VELOCITY, // 0x12
DESTROY_ENTITIES, // 0x13
ENTITY_MOVEMENT, // 0x14
ENTITY_POSITION, // 0x15
ENTITY_ROTATION, // 0x16
ENTITY_POSITION_AND_ROTATION, // 0x17
ENTITY_TELEPORT, // 0x18
ENTITY_HEAD_LOOK, // 0x19
ENTITY_STATUS, // 0x1A
ATTACH_ENTITY, // 0x1B
ENTITY_METADATA, // 0x1C
ENTITY_EFFECT, // 0x1D
REMOVE_ENTITY_EFFECT, // 0x1E
SET_EXPERIENCE, // 0x1F
ENTITY_PROPERTIES, // 0x20
CHUNK_DATA, // 0x21
MULTI_BLOCK_CHANGE, // 0x22
BLOCK_CHANGE, // 0x23
BLOCK_ACTION, // 0x24
BLOCK_BREAK_ANIMATION, // 0x25
MAP_BULK_CHUNK, // 0x26
EXPLOSION, // 0x27
EFFECT, // 0x28
NAMED_SOUND, // 0x29
SPAWN_PARTICLE, // 0x2A
GAME_EVENT, // 0x2B
SPAWN_GLOBAL_ENTITY, // 0x2C
OPEN_WINDOW, // 0x2D
CLOSE_WINDOW, // 0x2E
SET_SLOT, // 0x2F
WINDOW_ITEMS, // 0x30
WINDOW_PROPERTY, // 0x31
WINDOW_CONFIRMATION, // 0x32
UPDATE_SIGN, // 0x33
MAP_DATA, // 0x34
BLOCK_ENTITY_DATA, // 0x35
OPEN_SIGN_EDITOR, // 0x36
STATISTICS, // 0x37
PLAYER_INFO, // 0x38
PLAYER_ABILITIES, // 0x39
TAB_COMPLETE, // 0x3A
SCOREBOARD_OBJECTIVE, // 0x3B
UPDATE_SCORE, // 0x3C
DISPLAY_SCOREBOARD, // 0x3D
TEAMS, // 0x3E
PLUGIN_MESSAGE, // 0x3F
DISCONNECT; // 0x40
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}
@@ -1,114 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Protocol1_7_2_5To1_7_6_10 extends AbstractProtocol<ClientboundPackets1_7_2_5, ClientboundPackets1_7_2_5, ServerboundPackets1_7_2_5, ServerboundPackets1_7_2_5> {
public final static ValueTransformer<String, String> REMOVE_DASHES = new ValueTransformer<String, String>(Type.STRING) {
@Override
public String transform(PacketWrapper packetWrapper, String s) {
return s.replace("-", "");
}
};
public Protocol1_7_2_5To1_7_6_10() {
super(ClientboundPackets1_7_2_5.class, ClientboundPackets1_7_2_5.class, ServerboundPackets1_7_2_5.class, ServerboundPackets1_7_2_5.class);
}
@Override
protected void registerPackets() {
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE.getId(), ClientboundLoginPackets.GAME_PROFILE.getId(), new PacketHandlers() {
@Override
public void register() {
map(Type.STRING, REMOVE_DASHES); // uuid
map(Type.STRING); // name
}
});
this.registerClientbound(ClientboundPackets1_7_2_5.SPAWN_PLAYER, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // entity id
map(Type.STRING, REMOVE_DASHES); // uuid
map(Type.STRING); // name
handler(packetWrapper -> { // delete data introduced in 1.7.6
final int size = packetWrapper.read(Type.VAR_INT); // data count
for (int i = 0; i < size; i++) {
packetWrapper.read(Type.STRING); // data name
packetWrapper.read(Type.STRING); // data value
packetWrapper.read(Type.STRING); // data signature
}
});
map(Type.INT); // x
map(Type.INT); // y
map(Type.INT); // z
map(Type.BYTE); // yaw
map(Type.BYTE); // pitch
map(Type.SHORT); // item in hand
map(Types1_7_6_10.METADATA_LIST); // metadata
}
});
this.registerClientbound(ClientboundPackets1_7_2_5.TEAMS, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING); // team name
map(Type.BYTE); // mode
handler(packetWrapper -> {
byte mode = packetWrapper.get(Type.BYTE, 0);
if (mode == 0 || mode == 2) { // team is created or information is updated
packetWrapper.passthrough(Type.STRING); // team display name
packetWrapper.passthrough(Type.STRING); // team prefix
packetWrapper.passthrough(Type.STRING); // team suffix
packetWrapper.passthrough(Type.BYTE); // friendly fire
}
if (mode == 0 || mode == 3 || mode == 4) { // team is created, player is added or player is removed
List<String> entryList = new ArrayList<>();
final int size = packetWrapper.read(Type.SHORT);
for (int i = 0; i < size; i++) {
entryList.add(packetWrapper.read(Type.STRING));
}
entryList = entryList.stream()
.map(it -> it.length() > 16 ? it.substring(0, 16) : it) // trim to 16 characters
.distinct() // remove duplicates
.collect(Collectors.toList());
packetWrapper.write(Type.SHORT, (short) entryList.size());
for (String entry : entryList) {
packetWrapper.write(Type.STRING, entry);
}
}
});
}
});
}
}
@@ -1,58 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
public enum ServerboundPackets1_7_2_5 implements ServerboundPacketType {
KEEP_ALIVE, // 0x00
CHAT_MESSAGE, // 0x01
INTERACT_ENTITY, // 0x02
PLAYER_MOVEMENT, // 0x03
PLAYER_POSITION, // 0x04
PLAYER_ROTATION, // 0x05
PLAYER_POSITION_AND_ROTATION, // 0x06
PLAYER_DIGGING, // 0x07
PLAYER_BLOCK_PLACEMENT, // 0x08
HELD_ITEM_CHANGE, // 0x09
ANIMATION, // 0x0A
ENTITY_ACTION, // 0x0B
STEER_VEHICLE, // 0x0C
CLOSE_WINDOW, // 0x0D
CLICK_WINDOW, // 0x0E
WINDOW_CONFIRMATION, // 0x0F
CREATIVE_INVENTORY_ACTION, // 0x10
CLICK_WINDOW_BUTTON, // 0x11
UPDATE_SIGN, // 0x12
PLAYER_ABILITIES, // 0x13
TAB_COMPLETE, // 0x14
CLIENT_SETTINGS, // 0x15
CLIENT_STATUS, // 0x16
PLUGIN_MESSAGE; // 0x17
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}
@@ -1,163 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.api.rewriter.item.ReplacementItemRewriter;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.ClientboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.ServerboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.rewriter.MetadataRewriter;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets.*;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider.CompressionHandlerProvider;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider.compression.TrackingCompressionHandlerProvider;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.rewriter.ReplacementItemRewriter1_7_6_10;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.*;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.task.WorldBorderUpdateTask;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import java.util.concurrent.TimeUnit;
public class Protocol1_7_6_10To1_8 extends AbstractProtocol<ClientboundPackets1_8, ClientboundPackets1_7_2_5, ServerboundPackets1_8, ServerboundPackets1_7_2_5> {
private final ReplacementItemRewriter<Protocol1_7_6_10To1_8> itemRewriter = new ReplacementItemRewriter1_7_6_10(this);
private final MetadataRewriter metadataRewriter = new MetadataRewriter(this);
public Protocol1_7_6_10To1_8() {
super(ClientboundPackets1_8.class, ClientboundPackets1_7_2_5.class, ServerboundPackets1_8.class, ServerboundPackets1_7_2_5.class);
}
@Override
protected void registerPackets() {
itemRewriter.register();
EntityPackets.register(this);
InventoryPackets.register(this);
PlayerPackets.register(this);
ScoreboardPackets.register(this);
SpawnPackets.register(this);
WorldPackets.register(this);
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.HELLO.getId(), ClientboundLoginPackets.HELLO.getId(), new PacketHandlers() {
@Override
public void register() {
map(Type.STRING); // server hash
map(Type.BYTE_ARRAY_PRIMITIVE, Type.SHORT_BYTE_ARRAY); // public key
map(Type.BYTE_ARRAY_PRIMITIVE, Type.SHORT_BYTE_ARRAY); // verification token
}
});
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_COMPRESSION.getId(), ClientboundLoginPackets.LOGIN_COMPRESSION.getId(), new PacketHandlers() {
@Override
public void register() {
handler(wrapper -> {
final int threshold = wrapper.read(Type.VAR_INT);
Via.getManager().getProviders().get(CompressionHandlerProvider.class).onHandleLoginCompressionPacket(wrapper.user(), threshold);
wrapper.cancel();
});
}
});
this.cancelClientbound(ClientboundPackets1_8.SET_COMPRESSION); // unused
this.registerClientbound(ClientboundPackets1_8.KEEP_ALIVE, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // id
}
});
this.registerServerbound(State.LOGIN, ServerboundLoginPackets.ENCRYPTION_KEY.getId(), ServerboundLoginPackets.ENCRYPTION_KEY.getId(), new PacketHandlers() {
@Override
public void register() {
map(Type.SHORT_BYTE_ARRAY, Type.BYTE_ARRAY_PRIMITIVE); // shared secret
map(Type.SHORT_BYTE_ARRAY, Type.BYTE_ARRAY_PRIMITIVE); // verification token
}
});
this.registerServerbound(ServerboundPackets1_7_2_5.KEEP_ALIVE, new PacketHandlers() {
@Override
public void register() {
map(Type.INT, Type.VAR_INT); // id
}
});
}
@Override
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception {
Via.getManager().getProviders().get(CompressionHandlerProvider.class).onTransformPacket(packetWrapper.user());
// if (direction == Direction.CLIENTBOUND) {
// System.out.println("Pre: " + direction + " " + state + " " + packetWrapper.getId() + " " + ClientboundPackets1_8.values()[packetWrapper.getId()].getName() + ": " + packetWrapper);
// } else {
// System.out.println("Pre: " + direction + " " + state + " " + packetWrapper.getId() + " " + ServerboundPackets1_7_2_5.values()[packetWrapper.getId()].getName() + ": " + packetWrapper);
// }
super.transform(direction, state, packetWrapper);
// if (direction == Direction.CLIENTBOUND) {
// System.out.println("Post: " + direction + " " + state + " " + packetWrapper.getId() + " " + ClientboundPackets1_7_2_5.values()[packetWrapper.getId()].getName() + ": " + packetWrapper);
// } else {
// System.out.println("Post: " + direction + " " + state + " " + packetWrapper.getId() + " " + ServerboundPackets1_8.values()[packetWrapper.getId()].getName() + ": " + packetWrapper);
// }
}
@Override
public void init(UserConnection userConnection) {
userConnection.put(new InventoryTracker(userConnection));
userConnection.put(new EntityTracker1_7_6_10(userConnection, metadataRewriter));
userConnection.put(new PlayerSessionStorage(userConnection));
userConnection.put(new GameProfileStorage(userConnection));
userConnection.put(new Scoreboard(userConnection));
userConnection.put(new CompressionStatusTracker(userConnection));
userConnection.put(new WorldBorderEmulator(userConnection));
if (!userConnection.has(ClientWorld.class)) {
userConnection.put(new ClientWorld());
}
}
@Override
public void register(ViaProviders providers) {
providers.register(CompressionHandlerProvider.class, new TrackingCompressionHandlerProvider());
if (ViaRewind.getConfig().isEmulateWorldBorder()) {
Via.getManager().getScheduler().scheduleRepeating(new WorldBorderUpdateTask(), 0L, 50L, TimeUnit.MILLISECONDS);
}
}
@Override
public ReplacementItemRewriter<Protocol1_7_6_10To1_8> getItemRewriter() {
return itemRewriter;
}
public MetadataRewriter getMetadataRewriter() {
return metadataRewriter;
}
}
@@ -1,9 +0,0 @@
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model;
public class FurnaceData {
public short fuelLeft = 0;
public short maxFuel = 0;
public short progress = 0;
public short maxProgress = 200;
}
@@ -1,184 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.metadata.MetaType1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_8;
import com.viaversion.viaversion.util.Pair;
import java.util.HashMap;
import java.util.Optional;
public enum MetaIndex1_7_6_10To1_8 {
ENTITY_FLAGS(EntityTypes1_10.EntityType.ENTITY, 0, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ENTITY_AIR(EntityTypes1_10.EntityType.ENTITY, 1, MetaType1_7_6_10.Short, MetaType1_8.Short),
ENTITY_NAME_TAG(EntityTypes1_10.EntityType.ENTITY, -1, MetaType1_7_6_10.NonExistent, 2, MetaType1_8.String),
ENTITY_NAME_TAG_VISIBILITY(EntityTypes1_10.EntityType.ENTITY, -1, MetaType1_7_6_10.NonExistent, 3, MetaType1_8.Byte),
ENTITY_SILENT(EntityTypes1_10.EntityType.ENTITY, -1, MetaType1_7_6_10.NonExistent, 4, MetaType1_8.Byte),
ENTITY_LIVING_HEALTH(EntityTypes1_10.EntityType.ENTITY_LIVING, 6, MetaType1_7_6_10.Float, MetaType1_8.Float),
ENTITY_LIVING_POTION_EFFECT_COLOR(EntityTypes1_10.EntityType.ENTITY_LIVING, 7, MetaType1_7_6_10.Int, MetaType1_8.Int),
ENTITY_LIVING_IS_POTION_EFFECT_AMBIENT(EntityTypes1_10.EntityType.ENTITY_LIVING, 8, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ENTITY_LIVING_ARROWS(EntityTypes1_10.EntityType.ENTITY_LIVING, 9, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ENTITY_LIVING_NAME_TAG(EntityTypes1_10.EntityType.ENTITY_LIVING, 10, MetaType1_7_6_10.String, 2, MetaType1_8.String),
ENTITY_LIVING_NAME_TAG_VISIBILITY(EntityTypes1_10.EntityType.ENTITY_LIVING, 11, MetaType1_7_6_10.Byte, 3, MetaType1_8.Byte),
ENTITY_LIVING_AI(EntityTypes1_10.EntityType.ENTITY_LIVING, -1, MetaType1_7_6_10.NonExistent, 15, MetaType1_8.Byte),
ENTITY_AGEABLE_AGE(EntityTypes1_10.EntityType.ENTITY_AGEABLE, 12, MetaType1_7_6_10.Int, MetaType1_8.Byte),
ARMOR_STAND_FLAGS(EntityTypes1_10.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 10, MetaType1_8.Byte),
ARMOR_STAND_HEAD_POSITION(EntityTypes1_10.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 11, MetaType1_8.Rotation),
ARMOR_STAND_BODY_POSITION(EntityTypes1_10.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 12, MetaType1_8.Rotation),
ARMOR_STAND_LEFT_ARM_POSITION(EntityTypes1_10.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 13, MetaType1_8.Rotation),
ARMOR_STAND_RIGHT_ARM_POSITION(EntityTypes1_10.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 14, MetaType1_8.Rotation),
ARMOR_STAND_LEFT_LEG_POSITION(EntityTypes1_10.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 15, MetaType1_8.Rotation),
ARMOR_STAND_RIGHT_LEG_POSITION(EntityTypes1_10.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 16, MetaType1_8.Rotation),
HUMAN_SKIN_FLAGS(EntityTypes1_10.EntityType.ENTITY_HUMAN, 16, MetaType1_7_6_10.Byte, 10, MetaType1_8.Byte),
HUMAN_UNUSED(EntityTypes1_10.EntityType.ENTITY_HUMAN, -1, MetaType1_7_6_10.NonExistent, 16, MetaType1_8.Byte),
HUMAN_ABSORPTION_HEATS(EntityTypes1_10.EntityType.ENTITY_HUMAN, 17, MetaType1_7_6_10.Float, MetaType1_8.Float),
HUMAN_SCORE(EntityTypes1_10.EntityType.ENTITY_HUMAN, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
HORSE_FLAGS(EntityTypes1_10.EntityType.HORSE, 16, MetaType1_7_6_10.Int, MetaType1_8.Int),
HORSE_TYPE(EntityTypes1_10.EntityType.HORSE, 19, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
HORSE_COLOR(EntityTypes1_10.EntityType.HORSE, 20, MetaType1_7_6_10.Int, MetaType1_8.Int),
HORSE_OWNER(EntityTypes1_10.EntityType.HORSE, 21, MetaType1_7_6_10.String, MetaType1_8.String),
HORSE_ARMOR(EntityTypes1_10.EntityType.HORSE, 22, MetaType1_7_6_10.Int, MetaType1_8.Int),
BAT_HANGING(EntityTypes1_10.EntityType.BAT, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
TAMEABLE_FLAGS(EntityTypes1_10.EntityType.ENTITY_TAMEABLE_ANIMAL, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
TAMEABLE_OWNER(EntityTypes1_10.EntityType.ENTITY_TAMEABLE_ANIMAL, 17, MetaType1_7_6_10.String, MetaType1_8.String),
OCELOT_TYPE(EntityTypes1_10.EntityType.OCELOT, 18, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
WOLF_FLAGS(EntityTypes1_10.EntityType.WOLF, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
WOLF_HEALTH(EntityTypes1_10.EntityType.WOLF, 18, MetaType1_7_6_10.Float, MetaType1_8.Float),
WOLF_BEGGING(EntityTypes1_10.EntityType.WOLF, 19, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
WOLF_COLLAR_COLOR(EntityTypes1_10.EntityType.WOLF, 20, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
PIG_SADDLE(EntityTypes1_10.EntityType.PIG, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
SHEEP_COLOR_OR_SHEARED(EntityTypes1_10.EntityType.SHEEP, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
VILLAGER_TYPE(EntityTypes1_10.EntityType.VILLAGER, 16, MetaType1_7_6_10.Int, MetaType1_8.Int),
ENDERMAN_CARRIED_BLOCK(EntityTypes1_10.EntityType.ENDERMAN, 16, MetaType1_7_6_10.NonExistent, MetaType1_8.Short),
ENDERMAN_CARRIED_BLOCK_DATA(EntityTypes1_10.EntityType.ENDERMAN, 17, MetaType1_7_6_10.NonExistent, MetaType1_8.Byte),
ENDERMAN_IS_SCREAMING(EntityTypes1_10.EntityType.ENDERMAN, 18, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ZOMBIE_CHILD(EntityTypes1_10.EntityType.ZOMBIE, 12, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ZOMBIE_VILLAGER(EntityTypes1_10.EntityType.ZOMBIE, 13, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ZOMBIE_CONVERTING(EntityTypes1_10.EntityType.ZOMBIE, 14, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
BLAZE_ON_FIRE(EntityTypes1_10.EntityType.BLAZE, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
SPIDER_CLIMBING(EntityTypes1_10.EntityType.SPIDER, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
CREEPER_STATE(EntityTypes1_10.EntityType.CREEPER, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
CREEPER_POWERED(EntityTypes1_10.EntityType.CREEPER, 17, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
GHAST_STATE(EntityTypes1_10.EntityType.GHAST, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
GHAST_IS_POWERED(EntityTypes1_10.EntityType.GHAST, 17, MetaType1_7_6_10.NonExistent, MetaType1_8.Byte),
SLIME_SIZE(EntityTypes1_10.EntityType.SLIME, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
SKELETON_TYPE(EntityTypes1_10.EntityType.SKELETON, 13, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
WITCH_AGGRESSIVE(EntityTypes1_10.EntityType.WITCH, 21, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
IRON_GOLEM_IS_PLAYER_CREATED(EntityTypes1_10.EntityType.IRON_GOLEM, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
WITHER_WATCHED_TARGET_1(EntityTypes1_10.EntityType.WITHER, 17, MetaType1_7_6_10.Int, MetaType1_8.Int),
WITHER_WATCHED_TARGET_2(EntityTypes1_10.EntityType.WITHER, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
WITHER_WATCHED_TARGET_3(EntityTypes1_10.EntityType.WITHER, 19, MetaType1_7_6_10.Int, MetaType1_8.Int),
WITHER_INVULNERABLE_TIME(EntityTypes1_10.EntityType.WITHER, 20, MetaType1_7_6_10.Int, MetaType1_8.Int),
GUARDIAN_FLAGS(EntityTypes1_10.EntityType.GUARDIAN, 16, MetaType1_7_6_10.NonExistent, MetaType1_8.Byte),
GUARDIAN_TARGET(EntityTypes1_10.EntityType.GUARDIAN, 17, MetaType1_7_6_10.NonExistent, MetaType1_8.Int),
BOAT_TIME_SINCE_HIT(EntityTypes1_10.EntityType.BOAT, 17, MetaType1_7_6_10.Int, MetaType1_8.Int),
BOAT_FORWARD_DIRECTION(EntityTypes1_10.EntityType.BOAT, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
BOAT_DAMAGE_TAKEN(EntityTypes1_10.EntityType.BOAT, 19, MetaType1_7_6_10.Float, MetaType1_8.Float),
MINECART_SHAKING_POWER(EntityTypes1_10.EntityType.MINECART_ABSTRACT, 17, MetaType1_7_6_10.Int, MetaType1_8.Int),
MINECART_SHAKING_DIRECTION(EntityTypes1_10.EntityType.MINECART_ABSTRACT, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
MINECART_DAMAGE_TAKEN(EntityTypes1_10.EntityType.MINECART_ABSTRACT, 19, MetaType1_7_6_10.Float, MetaType1_8.Float),
MINECART_BLOCK_INSIDE(EntityTypes1_10.EntityType.MINECART_ABSTRACT, 20, MetaType1_7_6_10.Int, MetaType1_8.Int),
MINECART_BLOCK_Y(EntityTypes1_10.EntityType.MINECART_ABSTRACT, 21, MetaType1_7_6_10.Int, MetaType1_8.Int),
MINECART_SHOW_BLOCK(EntityTypes1_10.EntityType.MINECART_ABSTRACT, 22, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
FURNACE_MINECART_IS_POWERED(EntityTypes1_10.EntityType.MINECART_FURNACE, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ITEM_ITEM(EntityTypes1_10.EntityType.DROPPED_ITEM, 10, MetaType1_7_6_10.Slot, MetaType1_8.Slot),
ARROW_IS_CRITICAL(EntityTypes1_10.EntityType.ARROW, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
FIREWORK_INFO(EntityTypes1_10.EntityType.FIREWORK, 8, MetaType1_7_6_10.Slot, MetaType1_8.Slot),
ITEM_FRAME_ITEM(EntityTypes1_10.EntityType.ITEM_FRAME, 2, MetaType1_7_6_10.Slot, 8, MetaType1_8.Slot),
ITEM_FRAME_ROTATION(EntityTypes1_10.EntityType.ITEM_FRAME, 3, MetaType1_7_6_10.Byte, 9, MetaType1_8.Byte),
ENDER_CRYSTAL_HEALTH(EntityTypes1_10.EntityType.ENDER_CRYSTAL, 8, MetaType1_7_6_10.Int, 9, MetaType1_8.Int),
;
private final static HashMap<Pair<EntityTypes1_10.EntityType, Integer>, MetaIndex1_7_6_10To1_8> metadataRewrites = new HashMap<>();
static {
for (MetaIndex1_7_6_10To1_8 index : MetaIndex1_7_6_10To1_8.values()) {
metadataRewrites.put(new Pair<>(index.getClazz(), index.getNewIndex()), index);
}
}
private final EntityTypes1_10.EntityType clazz;
private final int newIndex;
private final MetaType1_8 newType;
private final MetaType1_7_6_10 oldType;
private final int index;
MetaIndex1_7_6_10To1_8(EntityTypes1_10.EntityType type, int index, MetaType1_7_6_10 oldType, MetaType1_8 newType) {
this.clazz = type;
this.index = index;
this.newIndex = index;
this.oldType = oldType;
this.newType = newType;
}
MetaIndex1_7_6_10To1_8(EntityTypes1_10.EntityType type, int index, MetaType1_7_6_10 oldType, int newIndex, MetaType1_8 newType) {
this.clazz = type;
this.index = index;
this.oldType = oldType;
this.newIndex = newIndex;
this.newType = newType;
}
private static Optional<MetaIndex1_7_6_10To1_8> getIndex(EntityTypes1_10.EntityType type, int index) {
Pair<EntityTypes1_10.EntityType, Integer> pair = new Pair<>(type, index);
if (metadataRewrites.containsKey(pair)) {
return Optional.of(metadataRewrites.get(pair));
}
return Optional.empty();
}
public EntityTypes1_10.EntityType getClazz() {
return clazz;
}
public int getNewIndex() {
return newIndex;
}
public MetaType1_8 getNewType() {
return newType;
}
public MetaType1_7_6_10 getOldType() {
return oldType;
}
public int getIndex() {
return index;
}
public static MetaIndex1_7_6_10To1_8 searchIndex(EntityTypes1_10.EntityType type, int index) {
EntityTypes1_10.EntityType currentType = type;
do {
Optional<MetaIndex1_7_6_10To1_8> optMeta = getIndex(currentType, index);
if (optMeta.isPresent()) {
return optMeta.get();
}
currentType = currentType.getParent();
} while (currentType != null);
return null;
}
}
@@ -1,97 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model;
import java.util.HashMap;
public enum ParticleIndex1_7_6_10 {
EXPLOSION_NORMAL("explode"),
EXPLOSION_LARGE("largeexplode"),
EXPLOSION_HUGE("hugeexplosion"),
FIREWORKS_SPARK("fireworksSpark"),
WATER_BUBBLE("bubble"),
WATER_SPLASH("splash"),
WATER_WAKE("wake"),
SUSPENDED("suspended"),
SUSPENDED_DEPTH("depthsuspend"),
CRIT("crit"),
CRIT_MAGIC("magicCrit"),
SMOKE_NORMAL("smoke"),
SMOKE_LARGE("largesmoke"),
SPELL("spell"),
SPELL_INSTANT("instantSpell"),
SPELL_MOB("mobSpell"),
SPELL_MOB_AMBIENT("mobSpellAmbient"),
SPELL_WITCH("witchMagic"),
DRIP_WATER("dripWater"),
DRIP_LAVA("dripLava"),
VILLAGER_ANGRY("angryVillager"),
VILLAGER_HAPPY("happyVillager"),
TOWN_AURA("townaura"),
NOTE("note"),
PORTAL("portal"),
ENCHANTMENT_TABLE("enchantmenttable"),
FLAME("flame"),
LAVA("lava"),
FOOTSTEP("footstep"),
CLOUD("cloud"),
REDSTONE("reddust"),
SNOWBALL("snowballpoof"),
SNOW_SHOVEL("snowshovel"),
SLIME("slime"),
HEART("heart"),
BARRIER("barrier"),
ICON_CRACK("iconcrack", 2),
BLOCK_CRACK("blockcrack", 1),
BLOCK_DUST("blockdust", 1),
WATER_DROP("droplet"),
ITEM_TAKE("take"),
MOB_APPEARANCE("mobappearance");
public final String name;
public final int extra;
private final static HashMap<String, ParticleIndex1_7_6_10> particleMap = new HashMap<>();
ParticleIndex1_7_6_10(String name) {
this(name, 0);
}
ParticleIndex1_7_6_10(String name, int extra) {
this.name = name;
this.extra = extra;
}
public static ParticleIndex1_7_6_10 find(String part) {
return particleMap.get(part);
}
public static ParticleIndex1_7_6_10 find(int id) {
if (id < 0) return null;
ParticleIndex1_7_6_10[] values = ParticleIndex1_7_6_10.values();
return id >= values.length ? null : values[id];
}
static {
ParticleIndex1_7_6_10[] particles = values();
for (ParticleIndex1_7_6_10 particle : particles) {
particleMap.put(particle.name, particle);
}
}
}
@@ -1,318 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.ClientboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.rewriter.MetadataRewriter;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.metadata.MetaType1_7_6_10;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.utils.math.AABB;
import com.viaversion.viarewind.utils.math.Vector3d;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_8;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import java.util.ArrayList;
import java.util.List;
public class VirtualHologramEntity {
private final List<Metadata> metadataTracker = new ArrayList<>();
private double locX, locY, locZ;
private final UserConnection user;
private final MetadataRewriter metadataRewriter;
private final int entityId;
private int[] entityIds = null;
private State currentState = null;
private boolean invisible = false;
private String name = null;
private float yaw, pitch;
private float headYaw;
private boolean small = false;
private boolean marker = false;
public VirtualHologramEntity(final UserConnection user, final MetadataRewriter metadataRewriter, final int entityId) {
this.user = user;
this.metadataRewriter = metadataRewriter;
this.entityId = entityId;
}
public void updateReplacementPosition(double x, double y, double z) {
if (x == this.locX && y == this.locY && z == this.locZ) {
return;
}
this.locX = x;
this.locY = y;
this.locZ = z;
updateLocation(false);
}
public void handleOriginalMovementPacket(double x, double y, double z) {
if (x == 0.0 && y == 0.0 && z == 0.0) {
return;
}
this.locX += x;
this.locY += y;
this.locZ += z;
updateLocation(false);
}
public void setYawPitch(float yaw, float pitch) {
if (this.yaw == yaw || this.headYaw == yaw || this.pitch == pitch) {
return;
}
this.yaw = yaw;
this.headYaw = yaw;
this.pitch = pitch;
updateLocation(false);
}
public void setHeadYaw(float yaw) {
if (this.headYaw == yaw) {
return;
}
this.headYaw = yaw;
updateLocation(false);
}
public void updateMetadata(final List<Metadata> metadataList) {
for (Metadata metadata : metadataList) {
metadataTracker.removeIf(m -> m.id() == metadata.id());
metadataTracker.add(metadata);
}
updateState();
}
public void updateState() {
byte flags = 0;
byte armorStandFlags = 0;
for (Metadata metadata : metadataTracker) {
if (metadata.id() == 0 && metadata.metaType() == MetaType1_8.Byte) {
flags = ((Number) metadata.getValue()).byteValue();
} else if (metadata.id() == 2 && metadata.metaType() == MetaType1_8.String) {
name = metadata.getValue().toString();
if (name != null && name.isEmpty()) name = null;
} else if (metadata.id() == 10 && metadata.metaType() == MetaType1_8.Byte) {
armorStandFlags = ((Number) metadata.getValue()).byteValue();
}
}
invisible = (flags & 0x20) != 0;
small = (armorStandFlags & 0x01) != 0;
marker = (armorStandFlags & 0x10) != 0;
State prevState = currentState;
if (invisible && name != null) {
currentState = State.HOLOGRAM;
} else {
currentState = State.ZOMBIE;
}
if (currentState != prevState) {
deleteEntity();
sendSpawnPacket();
} else {
updateMetadata();
updateLocation(false);
}
}
public void updateLocation(boolean remount) {
if (entityIds == null) return;
if (currentState == State.ZOMBIE) {
teleportEntity(entityId, locX, locY, locZ, yaw, pitch);
final PacketWrapper entityHeadLook = PacketWrapper.create(ClientboundPackets1_7_2_5.ENTITY_HEAD_LOOK, user);
entityHeadLook.write(Type.INT, entityId);
entityHeadLook.write(Type.BYTE, (byte) ((headYaw / 360f) * 256));
PacketUtil.sendPacket(entityHeadLook, Protocol1_7_6_10To1_8.class, true, true);
} else if (currentState == State.HOLOGRAM) {
if (remount) {
PacketWrapper detach = PacketWrapper.create(ClientboundPackets1_7_2_5.ATTACH_ENTITY, null, user);
detach.write(Type.INT, entityIds[1]);
detach.write(Type.INT, -1);
detach.write(Type.BOOLEAN, false);
PacketUtil.sendPacket(detach, Protocol1_7_6_10To1_8.class, true, true);
}
// Don't ask me where this offset is coming from
teleportEntity(entityIds[0], locX, (locY + (marker ? 54.85 : small ? 56 : 57) - 0.16), locZ, 0, 0); // Skull
if (remount) {
teleportEntity(entityIds[1], locX, locY + 56.75, locZ, 0, 0); // Horse
PacketWrapper attach = PacketWrapper.create(ClientboundPackets1_7_2_5.ATTACH_ENTITY, null, user);
attach.write(Type.INT, entityIds[1]);
attach.write(Type.INT, entityIds[0]);
attach.write(Type.BOOLEAN, false);
PacketUtil.sendPacket(attach, Protocol1_7_6_10To1_8.class, true, true);
}
}
}
protected void teleportEntity(final int entityId, final double x, final double y, final double z, final float yaw, final float pitch) {
final PacketWrapper entityTeleport = PacketWrapper.create(ClientboundPackets1_7_2_5.ENTITY_TELEPORT, user);
entityTeleport.write(Type.INT, entityId); // entity id
entityTeleport.write(Type.INT, (int) (x * 32.0)); // x
entityTeleport.write(Type.INT, (int) (y * 32.0)); // y
entityTeleport.write(Type.INT, (int) (z * 32.0)); // z
entityTeleport.write(Type.BYTE, (byte) ((yaw / 360f) * 256)); // yaw
entityTeleport.write(Type.BYTE, (byte) ((pitch / 360f) * 256)); // pitch
PacketUtil.sendPacket(entityTeleport, Protocol1_7_6_10To1_8.class, true, true);
}
protected void spawnEntity(final int entityId, final int type, final double locX, final double locY, final double locZ) {
final PacketWrapper spawnMob = PacketWrapper.create(ClientboundPackets1_7_2_5.SPAWN_MOB, null, user);
spawnMob.write(Type.VAR_INT, entityId); // entity id
spawnMob.write(Type.UNSIGNED_BYTE, (short) type); // type
spawnMob.write(Type.INT, (int) (locX * 32.0)); // x
spawnMob.write(Type.INT, (int) (locY * 32.0)); // y
spawnMob.write(Type.INT, (int) (locZ * 32.0)); // z
spawnMob.write(Type.BYTE, (byte) 0); // yaw
spawnMob.write(Type.BYTE, (byte) 0); // pitch
spawnMob.write(Type.BYTE, (byte) 0); // head pitch
spawnMob.write(Type.SHORT, (short) 0); // velocity x
spawnMob.write(Type.SHORT, (short) 0); // velocity y
spawnMob.write(Type.SHORT, (short) 0); // velocity z
spawnMob.write(Types1_7_6_10.METADATA_LIST, new ArrayList<>()); // metadata
PacketUtil.sendPacket(spawnMob, Protocol1_7_6_10To1_8.class, true, true);
}
public void updateMetadata() {
if (entityIds == null) return;
PacketWrapper metadataPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.ENTITY_METADATA, null, user);
if (currentState == State.ZOMBIE) {
writeZombieMeta(metadataPacket);
} else if (currentState == State.HOLOGRAM) {
writeHologramMeta(metadataPacket);
} else {
return;
}
PacketUtil.sendPacket(metadataPacket, Protocol1_7_6_10To1_8.class, true, true);
}
private void writeZombieMeta(PacketWrapper metadataPacket) {
metadataPacket.write(Type.INT, entityIds[0]);
List<Metadata> metadataList = new ArrayList<>();
for (Metadata metadata : metadataTracker) {
if (metadata.id() < 0 || metadata.id() > 9) continue;
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
}
if (small) metadataList.add(new Metadata(12, MetaType1_8.Byte, (byte) 1));
metadataRewriter.transform(EntityTypes1_10.EntityType.ZOMBIE, metadataList);
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
}
private void writeHologramMeta(PacketWrapper metadataPacket) {
metadataPacket.write(Type.INT, entityIds[1]);
List<Metadata> metadataList = new ArrayList<>();
metadataList.add(new Metadata(MetaIndex1_7_6_10To1_8.ENTITY_AGEABLE_AGE.getIndex(), MetaType1_7_6_10.Int, -1700000));
metadataList.add(new Metadata(MetaIndex1_7_6_10To1_8.ENTITY_LIVING_NAME_TAG.getIndex(), MetaType1_7_6_10.String, name));
metadataList.add(new Metadata(MetaIndex1_7_6_10To1_8.ENTITY_LIVING_NAME_TAG_VISIBILITY.getIndex(), MetaType1_7_6_10.Byte, (byte) 1));
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
}
public void sendSpawnPacket() {
if (entityIds != null) deleteEntity();
if (currentState == State.ZOMBIE) {
spawnEntity(entityId, 54, locX, locY, locZ);
entityIds = new int[]{entityId};
} else if (currentState == State.HOLOGRAM) {
int[] entityIds = {entityId, additionalEntityId()};
PacketWrapper spawnSkull = PacketWrapper.create(ClientboundPackets1_7_2_5.SPAWN_ENTITY, null, user);
spawnSkull.write(Type.VAR_INT, entityIds[0]);
spawnSkull.write(Type.BYTE, (byte) 66);
spawnSkull.write(Type.INT, (int) (locX * 32.0));
spawnSkull.write(Type.INT, (int) (locY * 32.0));
spawnSkull.write(Type.INT, (int) (locZ * 32.0));
spawnSkull.write(Type.BYTE, (byte) 0);
spawnSkull.write(Type.BYTE, (byte) 0);
spawnSkull.write(Type.INT, 0);
PacketUtil.sendPacket(spawnSkull, Protocol1_7_6_10To1_8.class, true, true);
spawnEntity(entityIds[1], 100, locX, locY, locZ); // Horse
this.entityIds = entityIds;
}
updateMetadata();
updateLocation(true);
}
public AABB getBoundingBox() {
final double width = this.small ? 0.25 : 0.5;
final double height = this.small ? 0.9875 : 1.975;
final Vector3d min = new Vector3d(this.locX - width / 2, this.locY, this.locZ - width / 2);
final Vector3d max = new Vector3d(this.locX + width / 2, this.locY + height, this.locZ + width / 2);
return new AABB(min, max);
}
private int additionalEntityId() {
return Integer.MAX_VALUE - 16000 - entityId;
}
public void deleteEntity() {
if (entityIds == null) return;
PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7_2_5.DESTROY_ENTITIES, null, user);
despawn.write(Type.BYTE, (byte) entityIds.length);
for (int id : entityIds) {
despawn.write(Type.INT, id);
}
entityIds = null;
PacketUtil.sendPacket(despawn, Protocol1_7_6_10To1_8.class, true, true);
}
private enum State {
HOLOGRAM, ZOMBIE
}
public int getEntityId() {
return entityId;
}
}
@@ -1,358 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model.VirtualHologramEntity;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.EntityTracker1_7_6_10;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.GameProfileStorage;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.PlayerSessionStorage;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import java.util.List;
import java.util.UUID;
public class EntityPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_EQUIPMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Type.SHORT); // slot
map(Type.ITEM1_8, Types1_7_6_10.COMPRESSED_NBT_ITEM); // item
// remap item
handler(wrapper -> {
final Item item = wrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
protocol.getItemRewriter().handleItemToClient(item);
wrapper.set(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0, item);
});
handler(wrapper -> {
final short slot = wrapper.get(Type.SHORT, 0);
final UUID uuid = wrapper.user().get(EntityTracker1_7_6_10.class).getPlayerUUID(wrapper.get(Type.INT, 0));
if (uuid == null) return;
final Item item = wrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
wrapper.user().get(PlayerSessionStorage.class).setPlayerEquipment(uuid, item, slot);
final GameProfileStorage storage = wrapper.user().get(GameProfileStorage.class);
GameProfileStorage.GameProfile profile = storage.get(uuid);
if (profile != null && profile.gamemode == 3) { // spectator mode didn't exist in 1.7.10
wrapper.cancel();
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.USE_BED, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Type.POSITION1_8, Types1_7_6_10.U_BYTE_POSITION); // position
}
});
protocol.registerClientbound(ClientboundPackets1_8.COLLECT_ITEM, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // collected entity id
map(Type.VAR_INT, Type.INT); // collector entity id
handler(wrapper -> wrapper.user().get(EntityTracker1_7_6_10.class).removeEntity(wrapper.get(Type.INT, 0)));
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_VELOCITY, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Type.SHORT); // velocity x
map(Type.SHORT); // velocity y
map(Type.SHORT); // velocity z
}
});
protocol.registerClientbound(ClientboundPackets1_8.DESTROY_ENTITIES, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT_ARRAY_PRIMITIVE, Types1_7_6_10.BYTE_INT_ARRAY); // entity ids
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
for (int entityId : wrapper.get(Types1_7_6_10.BYTE_INT_ARRAY, 0)) {
tracker.removeEntity(entityId);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_MOVEMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_POSITION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Type.BYTE); // x
map(Type.BYTE); // y
map(Type.BYTE); // z
read(Type.BOOLEAN); // on ground
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
final VirtualHologramEntity hologram = tracker.getVirtualHologramMap().get(wrapper.get(Type.INT, 0));
if (hologram != null) {
wrapper.cancel();
final int x = wrapper.get(Type.BYTE, 0);
final int y = wrapper.get(Type.BYTE, 1);
final int z = wrapper.get(Type.BYTE, 2);
hologram.handleOriginalMovementPacket(x / 32.0, y / 32.0, z / 32.0);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Type.BYTE); // yaw
map(Type.BYTE); // pitch
read(Type.BOOLEAN); // on ground
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
final VirtualHologramEntity hologram = tracker.getVirtualHologramMap().get(wrapper.get(Type.INT, 0));
if (hologram != null) {
wrapper.cancel();
final int yaw = wrapper.get(Type.BYTE, 0);
final int pitch = wrapper.get(Type.BYTE, 1);
hologram.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_POSITION_AND_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Type.BYTE); // x
map(Type.BYTE); // y
map(Type.BYTE); // z
map(Type.BYTE); // yaw
map(Type.BYTE); // pitch
read(Type.BOOLEAN); // on ground
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
final VirtualHologramEntity hologram = tracker.getVirtualHologramMap().get(wrapper.get(Type.INT, 0));
if (hologram != null) {
wrapper.cancel();
final int x = wrapper.get(Type.BYTE, 0);
final int y = wrapper.get(Type.BYTE, 1);
final int z = wrapper.get(Type.BYTE, 2);
final int yaw = wrapper.get(Type.BYTE, 3);
final int pitch = wrapper.get(Type.BYTE, 4);
hologram.handleOriginalMovementPacket(x / 32.0, y / 32.0, z / 32.0);
hologram.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_TELEPORT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Type.INT); // x
map(Type.INT); // y
map(Type.INT); // z
map(Type.BYTE); // yaw
map(Type.BYTE); // pitch
read(Type.BOOLEAN); // on ground
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
final int entityId = wrapper.get(Type.INT, 0);
final EntityTypes1_10.EntityType type = tracker.getEntityMap().get(entityId);
if (type == EntityTypes1_10.EntityType.MINECART_ABSTRACT) { // TODO | Realign all entities?
int y = wrapper.get(Type.INT, 2);
y += 12;
wrapper.set(Type.INT, 2, y);
}
final VirtualHologramEntity hologram = tracker.getVirtualHologramMap().get(entityId);
if (hologram != null) {
wrapper.cancel();
final int x = wrapper.get(Type.INT, 1);
final int y = wrapper.get(Type.INT, 2);
final int z = wrapper.get(Type.INT, 3);
final int yaw = wrapper.get(Type.BYTE, 0);
final int pitch = wrapper.get(Type.BYTE, 1);
hologram.updateReplacementPosition(x / 32.0, y / 32.0, z / 32.0);
hologram.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_HEAD_LOOK, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Type.BYTE); // head yaw
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
final VirtualHologramEntity hologram = tracker.getVirtualHologramMap().get(wrapper.get(Type.INT, 0));
if (hologram != null) {
wrapper.cancel();
final int yaw = wrapper.get(Type.BYTE, 0);
hologram.setHeadYaw(yaw * 360f / 256);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ATTACH_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // riding entity id
map(Type.INT); // vehicle entity id
map(Type.BOOLEAN); // leash state
handler(packetWrapper -> {
final boolean leash = packetWrapper.get(Type.BOOLEAN, 0);
if (!leash) {
final EntityTracker1_7_6_10 tracker = packetWrapper.user().get(EntityTracker1_7_6_10.class);
final int passenger = packetWrapper.get(Type.INT, 0);
final int vehicle = packetWrapper.get(Type.INT, 1);
tracker.setPassenger(vehicle, passenger);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_METADATA, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Types1_8.METADATA_LIST, Types1_7_6_10.METADATA_LIST); // metadata
handler(wrapper -> {
final int entityId = wrapper.get(Type.INT, 0);
final List<Metadata> metadataList = wrapper.get(Types1_7_6_10.METADATA_LIST, 0);
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
if (tracker.getEntityReplacementMap().containsKey(entityId)) {
tracker.updateMetadata(entityId, metadataList);
wrapper.cancel();
return;
}
if (tracker.getEntityMap().containsKey(entityId)) {
protocol.getMetadataRewriter().transform(tracker.getEntityMap().get(entityId), metadataList);
if (metadataList.isEmpty()) {
wrapper.cancel();
}
} else {
wrapper.cancel();
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Type.BYTE); // effect id
map(Type.BYTE); // amplifier
map(Type.VAR_INT, Type.SHORT); // duration
read(Type.BYTE); // hide particles
}
});
protocol.registerClientbound(ClientboundPackets1_8.REMOVE_ENTITY_EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
map(Type.BYTE); // effect id
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_PROPERTIES, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); // entity id
handler(wrapper -> {
final int entityId = wrapper.get(Type.INT, 0);
if (wrapper.user().get(EntityTracker1_7_6_10.class).getEntityReplacementMap().containsKey(entityId)) {
wrapper.cancel();
return;
}
final int amount = wrapper.passthrough(Type.INT);
for (int i = 0; i < amount; i++) {
wrapper.passthrough(Type.STRING); // id
wrapper.passthrough(Type.DOUBLE); // value
int modifierLength = wrapper.read(Type.VAR_INT);
wrapper.write(Type.SHORT, (short) modifierLength);
for (int j = 0; j < modifierLength; j++) {
wrapper.passthrough(Type.UUID); // modifier uuid
wrapper.passthrough(Type.DOUBLE); // modifier amount
wrapper.passthrough(Type.BYTE); // modifier operation
}
}
});
}
});
protocol.cancelClientbound(ClientboundPackets1_8.UPDATE_ENTITY_NBT);
}
}
@@ -1,269 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.ServerboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model.FurnaceData;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.GameProfileStorage;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.InventoryTracker;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.PlayerSessionStorage;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viarewind.utils.ChatUtil;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import java.util.UUID;
public class InventoryPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
protocol.registerClientbound(ClientboundPackets1_8.OPEN_WINDOW, wrapper -> {
final InventoryTracker windowTracker = wrapper.user().get(InventoryTracker.class);
final short windowId = wrapper.passthrough(Type.UNSIGNED_BYTE); // window id
final short windowTypeId = InventoryTracker.getInventoryType(wrapper.read(Type.STRING)); // window type
windowTracker.getWindowTypeMap().put(windowId, windowTypeId);
wrapper.write(Type.UNSIGNED_BYTE, windowTypeId); // window type id
final JsonElement titleComponent = wrapper.read(Type.COMPONENT); // Title
String title = ChatUtil.jsonToLegacy(titleComponent);
title = ChatUtil.removeUnusedColor(title, '8');
if (title.length() > 32) {
title = title.substring(0, 32);
}
wrapper.write(Type.STRING, title); // window title
wrapper.passthrough(Type.UNSIGNED_BYTE); // slots count
wrapper.write(Type.BOOLEAN, true); // use provided window title
if (windowTypeId == 11) { // Horse
wrapper.passthrough(Type.INT); // entity id
}
});
protocol.registerClientbound(ClientboundPackets1_8.CLOSE_WINDOW, wrapper -> {
final short windowId = wrapper.passthrough(Type.UNSIGNED_BYTE); // window id
wrapper.user().get(InventoryTracker.class).remove(windowId);
});
protocol.registerClientbound(ClientboundPackets1_8.SET_SLOT, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE); // window id
map(Type.SHORT); // slot
handler(wrapper -> {
final short windowType = wrapper.user().get(InventoryTracker.class).get(wrapper.get(Type.UNSIGNED_BYTE, 0));
final short slot = wrapper.get(Type.SHORT, 0);
if (windowType == 4) { // Enchantment Table
if (slot == 1) {
wrapper.cancel();
} else if (slot >= 2) {
wrapper.set(Type.SHORT, 0, (short) (slot - 1));
}
}
});
map(Type.ITEM1_8, Types1_7_6_10.COMPRESSED_NBT_ITEM); // item
// remap item
handler(wrapper -> {
final Item item = wrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
protocol.getItemRewriter().handleItemToClient(item);
wrapper.set(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0, item);
});
handler(wrapper -> {
final short windowId = wrapper.get(Type.UNSIGNED_BYTE, 0);
if (windowId != 0) return;
final short slot = wrapper.get(Type.SHORT, 0);
if (slot < 5 || slot > 8) return;
final PlayerSessionStorage playerSession = wrapper.user().get(PlayerSessionStorage.class);
final Item item = wrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
playerSession.setPlayerEquipment(wrapper.user().getProtocolInfo().getUuid(), item, 8 - slot);
if (playerSession.isSpectator()) { // Spectator mode didn't exist in 1.7.10
wrapper.cancel();
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.WINDOW_ITEMS, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE); // window id
// remap enchantment table items
handler(wrapper -> {
final short windowType = wrapper.user().get(InventoryTracker.class).get(wrapper.get(Type.UNSIGNED_BYTE, 0));
Item[] items = wrapper.read(Type.ITEM1_8_SHORT_ARRAY);
if (windowType == 4) { // Enchantment Table
Item[] old = items;
items = new Item[old.length - 1];
items[0] = old[0];
System.arraycopy(old, 2, items, 1, old.length - 3);
}
for (int i = 0; i < items.length; i++) {
items[i] = protocol.getItemRewriter().handleItemToClient(items[i]);
}
wrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM_ARRAY, items); // items
});
handler(wrapper -> {
final short windowId = wrapper.get(Type.UNSIGNED_BYTE, 0);
if (windowId != 0) return;
final UUID userId = wrapper.user().getProtocolInfo().getUuid();
final PlayerSessionStorage playerSession = wrapper.user().get(PlayerSessionStorage.class);
final Item[] items = wrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM_ARRAY, 0);
for (int i = 5; i < 9; i++) {
playerSession.setPlayerEquipment(userId, items[i], 8 - i);
if (playerSession.isSpectator()) {
items[i] = null;
}
}
if (playerSession.isSpectator()) {
final GameProfileStorage.GameProfile profile = wrapper.user().get(GameProfileStorage.class).get(userId);
if (profile != null) {
items[5] = profile.getSkull();
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.WINDOW_PROPERTY, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE); // window id
map(Type.SHORT); // progress bar id
map(Type.SHORT); // progress bar value
handler(wrapper -> {
final InventoryTracker windowTracker = wrapper.user().get(InventoryTracker.class);
final short windowId = wrapper.get(Type.UNSIGNED_BYTE, 0);
final short windowType = windowTracker.get(windowId);
final short progressBarId = wrapper.get(Type.SHORT, 0);
short progress = wrapper.get(Type.SHORT, 1);
if (windowType == 2) { // Furnace
final FurnaceData furnace = windowTracker.getFurnaceData().computeIfAbsent(windowId, x -> new FurnaceData());
if (progressBarId == 0 || progressBarId == 1) {
if (progressBarId == 0) {
furnace.fuelLeft = progress;
} else {
furnace.maxFuel = progress;
}
if (furnace.maxFuel == 0) {
wrapper.cancel();
return;
}
progress = (short) (200 * furnace.fuelLeft / furnace.maxFuel);
wrapper.set(Type.SHORT, 0, (short) 1);
wrapper.set(Type.SHORT, 1, progress);
} else if (progressBarId == 2 || progressBarId == 3) {
if (progressBarId == 2) {
furnace.progress = progress;
} else {
furnace.maxProgress = progress;
}
if (furnace.maxProgress == 0) {
wrapper.cancel();
return;
}
progress = (short) (200 * furnace.progress / furnace.maxProgress);
wrapper.set(Type.SHORT, 0, (short) 0);
wrapper.set(Type.SHORT, 1, progress);
}
} else if (windowType == 4 && progressBarId > 2) { // Enchanting Table
wrapper.cancel();
} else if (windowType == 8) { // Anvil
windowTracker.levelCost = progress;
windowTracker.anvilId = windowId;
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.CLOSE_WINDOW, wrapper -> {
final short windowId = wrapper.passthrough(Type.UNSIGNED_BYTE);
wrapper.user().get(InventoryTracker.class).remove(windowId);
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.CLICK_WINDOW, new PacketHandlers() {
@Override
public void register() {
map(Type.BYTE, Type.UNSIGNED_BYTE); // window id
map(Type.SHORT); // slot
handler(wrapper -> {
final short windowId = wrapper.get(Type.UNSIGNED_BYTE, 0); //Window Id
final short slot = wrapper.get(Type.SHORT, 0);
final short windowType = wrapper.user().get(InventoryTracker.class).get(windowId);
if (windowType == 4) { // Enchantment Table
if (slot > 0) {
wrapper.set(Type.SHORT, 0, (short) (slot + 1));
}
}
});
map(Type.BYTE); // button
map(Type.SHORT); // action number
map(Type.BYTE); // mode
map(Types1_7_6_10.COMPRESSED_NBT_ITEM, Type.ITEM1_8); // clicked item
// remap item
handler(wrapper -> {
final Item item = wrapper.get(Type.ITEM1_8, 0);
protocol.getItemRewriter().handleItemToServer(item);
wrapper.set(Type.ITEM1_8, 0, item);
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.CREATIVE_INVENTORY_ACTION, new PacketHandlers() {
@Override
public void register() {
map(Type.SHORT); // slot
map(Types1_7_6_10.COMPRESSED_NBT_ITEM, Type.ITEM1_8); // item
// remap item
handler(wrapper -> {
final Item item = wrapper.get(Type.ITEM1_8, 0);
protocol.getItemRewriter().handleItemToServer(item);
wrapper.set(Type.ITEM1_8, 0, item);
});
}
});
}
}
@@ -1,917 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.ClientboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.ServerboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider.TitleRenderProvider;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.*;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viarewind.utils.ChatUtil;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.utils.math.AABB;
import com.viaversion.viarewind.utils.math.Ray3d;
import com.viaversion.viarewind.utils.math.RayTracing;
import com.viaversion.viarewind.utils.math.Vector3d;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.Environment;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.libs.gson.JsonParser;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;
public class PlayerPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
protocol.registerClientbound(ClientboundPackets1_8.JOIN_GAME, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // entity id
map(Type.UNSIGNED_BYTE);// game mode
map(Type.BYTE); // dimension
map(Type.UNSIGNED_BYTE); // difficulty
map(Type.UNSIGNED_BYTE); // max players
map(Type.STRING); // level type
read(Type.BOOLEAN); // reduced debug info
handler(wrapper -> {
if (ViaRewind.getConfig().isReplaceAdventureMode()) {
if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 2) { // adventure
wrapper.set(Type.UNSIGNED_BYTE, 0, (short) 0); // survival
}
}
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
tracker.setClientEntityId(wrapper.get(Type.INT, 0));
tracker.addPlayer(wrapper.get(Type.INT, 0), wrapper.user().getProtocolInfo().getUuid());
wrapper.user().get(PlayerSessionStorage.class).gameMode = wrapper.get(Type.UNSIGNED_BYTE, 0);
wrapper.user().get(ClientWorld.class).setEnvironment(wrapper.get(Type.BYTE, 0));
// Reset on Velocity server change
wrapper.user().put(new Scoreboard(wrapper.user()));
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.CHAT_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.COMPONENT); // chat message
handler(wrapper -> {
final int position = wrapper.read(Type.BYTE);
if (position == 2) { // above hotbar
wrapper.cancel();
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_POSITION, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION1_8, Types1_7_6_10.INT_POSITION); // spawn position
}
});
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_HEALTH, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT); // health
map(Type.VAR_INT, Type.SHORT); // food
map(Type.FLOAT); // food saturation
}
});
protocol.registerClientbound(ClientboundPackets1_8.RESPAWN, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // dimension
map(Type.UNSIGNED_BYTE); // difficulty
map(Type.UNSIGNED_BYTE); // game mode
map(Type.STRING); // level type
handler(wrapper -> {
if (ViaRewind.getConfig().isReplaceAdventureMode()) {
if (wrapper.get(Type.UNSIGNED_BYTE, 1) == 2) {
wrapper.set(Type.UNSIGNED_BYTE, 1, (short) 0);
}
}
wrapper.user().get(PlayerSessionStorage.class).gameMode = wrapper.get(Type.UNSIGNED_BYTE, 1);
final ClientWorld world = wrapper.user().get(ClientWorld.class);
final Environment dimension = Environment.getEnvironmentById(wrapper.get(Type.INT, 0));
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
if (world.getEnvironment() != dimension) {
world.setEnvironment(dimension.id());
// Reset on dimension change
tracker.clear();
tracker.getEntityMap().put(tracker.getPlayerId(), EntityTypes1_10.EntityType.ENTITY_HUMAN);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.PLAYER_POSITION, new PacketHandlers() {
@Override
public void register() {
map(Type.DOUBLE); // x
map(Type.DOUBLE); // y
map(Type.DOUBLE); // z
map(Type.FLOAT); // yaw
map(Type.FLOAT); // pitch
handler(wrapper -> {
final double x = wrapper.get(Type.DOUBLE, 0);
double y = wrapper.get(Type.DOUBLE, 1);
final double z = wrapper.get(Type.DOUBLE, 2);
final float yaw = wrapper.get(Type.FLOAT, 0);
final float pitch = wrapper.get(Type.FLOAT, 1);
final PlayerSessionStorage playerSession = wrapper.user().get(PlayerSessionStorage.class);
final int flags = wrapper.read(Type.BYTE);
// x, y, and z
if ((flags & 0x01) == 0x01) wrapper.set(Type.DOUBLE, 0, x + playerSession.getPosX());
if ((flags & 0x02) == 0x02) y += playerSession.getPosY();
playerSession.receivedPosY = y;
wrapper.set(Type.DOUBLE, 1, y + 1.62F);
if ((flags & 0x04) == 0x04) wrapper.set(Type.DOUBLE, 2, z + playerSession.getPosZ());
// yaw and pitch
if ((flags & 0x08) == 0x08) wrapper.set(Type.FLOAT, 0, yaw + playerSession.yaw);
if ((flags & 0x10) == 0x10) wrapper.set(Type.FLOAT, 1, pitch + playerSession.pitch);
wrapper.write(Type.BOOLEAN, playerSession.onGround);
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
if (tracker.spectatingPlayerId != tracker.getPlayerId()) {
wrapper.cancel();
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SET_EXPERIENCE, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT); // experience bar
map(Type.VAR_INT, Type.SHORT); // level
map(Type.VAR_INT, Type.SHORT); // total experience
}
});
protocol.registerClientbound(ClientboundPackets1_8.GAME_EVENT, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE); // reason
map(Type.FLOAT); // value
handler(wrapper -> {
if (wrapper.get(Type.UNSIGNED_BYTE, 0) != 3) return; // Change game mode
int gameMode = wrapper.get(Type.FLOAT, 0).intValue();
final PlayerSessionStorage playerSession = wrapper.user().get(PlayerSessionStorage.class);
if (gameMode == 3 || playerSession.gameMode == 3) {
UUID myId = wrapper.user().getProtocolInfo().getUuid();
Item[] equipment = new Item[4];
if (gameMode == 3) {
GameProfileStorage.GameProfile profile = wrapper.user().get(GameProfileStorage.class).get(myId);
equipment[3] = profile == null ? null : profile.getSkull();
} else {
for (int i = 0; i < equipment.length; i++) {
equipment[i] = playerSession.getPlayerEquipment(myId, i);
}
}
for (int i = 0; i < equipment.length; i++) {
PacketWrapper setSlot = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_SLOT, wrapper.user());
setSlot.write(Type.BYTE, (byte) 0);
setSlot.write(Type.SHORT, (short) (8 - i));
setSlot.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, equipment[i]);
PacketUtil.sendPacket(setSlot, Protocol1_7_6_10To1_8.class);
}
}
if (gameMode == 2 && ViaRewind.getConfig().isReplaceAdventureMode()) {
gameMode = 0;
wrapper.set(Type.FLOAT, 0, 0.0f);
}
wrapper.user().get(PlayerSessionStorage.class).gameMode = gameMode;
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.OPEN_SIGN_EDITOR, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION1_8, Types1_7_6_10.INT_POSITION); // position
}
});
protocol.registerClientbound(ClientboundPackets1_8.PLAYER_INFO, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
int action = packetWrapper.read(Type.VAR_INT);
int count = packetWrapper.read(Type.VAR_INT);
GameProfileStorage gameProfileStorage = packetWrapper.user().get(GameProfileStorage.class);
for (int i = 0; i < count; i++) {
UUID uuid = packetWrapper.read(Type.UUID);
if (action == 0) {
String name = packetWrapper.read(Type.STRING);
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null) gameProfile = gameProfileStorage.put(uuid, name);
int propertyCount = packetWrapper.read(Type.VAR_INT);
while (propertyCount-- > 0) {
String propertyName = packetWrapper.read(Type.STRING);
String propertyValue = packetWrapper.read(Type.STRING);
String propertySignature = packetWrapper.read(Type.OPTIONAL_STRING);
gameProfile.properties.add(new GameProfileStorage.Property(propertyName, propertyValue, propertySignature));
}
int gamemode = packetWrapper.read(Type.VAR_INT);
int ping = packetWrapper.read(Type.VAR_INT);
gameProfile.ping = ping;
gameProfile.gamemode = gamemode;
JsonElement displayName = packetWrapper.read(Type.OPTIONAL_COMPONENT);
if (displayName != null) {
gameProfile.setDisplayName(ChatUtil.jsonToLegacy(displayName));
}
PacketWrapper packet = PacketWrapper.create(ClientboundPackets1_7_2_5.PLAYER_INFO, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, true);
packet.write(Type.SHORT, (short) ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
} else if (action == 1) {
int gamemode = packetWrapper.read(Type.VAR_INT);
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null || gameProfile.gamemode == gamemode) continue;
if (gamemode == 3 || gameProfile.gamemode == 3) {
EntityTracker1_7_6_10 tracker = packetWrapper.user().get(EntityTracker1_7_6_10.class);
int entityId = tracker.getPlayerEntityId(uuid);
boolean isOwnPlayer = entityId == tracker.getPlayerId();
if (entityId != -1) {
// Weirdly, PlayerEntity has only 4 slots instead of 5
Item[] equipment = new Item[isOwnPlayer ? 4 : 5];
if (gamemode == 3) {
equipment[isOwnPlayer ? 3 : 4] = gameProfile.getSkull();
} else {
for (int j = 0; j < equipment.length; j++) {
equipment[j] = packetWrapper.user().get(PlayerSessionStorage.class).getPlayerEquipment(uuid, j);
}
}
for (short slot = 0; slot < equipment.length; slot++) {
PacketWrapper equipmentPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.ENTITY_EQUIPMENT, packetWrapper.user());
equipmentPacket.write(Type.INT, entityId);
equipmentPacket.write(Type.SHORT, slot);
equipmentPacket.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, equipment[slot]);
PacketUtil.sendPacket(equipmentPacket, Protocol1_7_6_10To1_8.class);
}
}
}
gameProfile.gamemode = gamemode;
} else if (action == 2) {
int ping = packetWrapper.read(Type.VAR_INT);
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null) continue;
PacketWrapper packet = PacketWrapper.create(ClientboundPackets1_7_2_5.PLAYER_INFO, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, false);
packet.write(Type.SHORT, (short) gameProfile.ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
gameProfile.ping = ping;
packet = PacketWrapper.create(ClientboundPackets1_7_2_5.PLAYER_INFO, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, true);
packet.write(Type.SHORT, (short) ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
} else if (action == 3) {
JsonElement displayNameComponent = packetWrapper.read(Type.OPTIONAL_COMPONENT);
String displayName = displayNameComponent != null ? ChatUtil.jsonToLegacy(displayNameComponent) : null;
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null || gameProfile.displayName == null && displayName == null) continue;
PacketWrapper packet = PacketWrapper.create(ClientboundPackets1_7_2_5.PLAYER_INFO, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, false);
packet.write(Type.SHORT, (short) gameProfile.ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
if (gameProfile.displayName == null && displayName != null || gameProfile.displayName != null && displayName == null || !gameProfile.displayName.equals(displayName)) {
gameProfile.setDisplayName(displayName);
}
packet = PacketWrapper.create(ClientboundPackets1_7_2_5.PLAYER_INFO, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, true);
packet.write(Type.SHORT, (short) gameProfile.ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
} else if (action == 4) {
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.remove(uuid);
if (gameProfile == null) continue;
PacketWrapper packet = PacketWrapper.create(ClientboundPackets1_7_2_5.PLAYER_INFO, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, false);
packet.write(Type.SHORT, (short) gameProfile.ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.PLAYER_ABILITIES, new PacketHandlers() {
@Override
public void register() {
map(Type.BYTE);
map(Type.FLOAT);
map(Type.FLOAT);
handler(packetWrapper -> {
byte flags = packetWrapper.get(Type.BYTE, 0);
float flySpeed = packetWrapper.get(Type.FLOAT, 0);
float walkSpeed = packetWrapper.get(Type.FLOAT, 1);
PlayerSessionStorage abilities = packetWrapper.user().get(PlayerSessionStorage.class);
abilities.invincible = (flags & 8) == 8;
abilities.allowFly = (flags & 4) == 4;
abilities.flying = (flags & 2) == 2;
abilities.creative = (flags & 1) == 1;
abilities.flySpeed = flySpeed;
abilities.walkSpeed = walkSpeed;
if (abilities.sprinting && abilities.flying) {
packetWrapper.set(Type.FLOAT, 0, abilities.flySpeed * 2.0f);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> {
String channel = packetWrapper.get(Type.STRING, 0);
if (channel.equalsIgnoreCase("MC|TrList")) {
packetWrapper.passthrough(Type.INT); //Window Id
int size;
if (packetWrapper.isReadable(Type.BYTE, 0)) {
size = packetWrapper.passthrough(Type.BYTE);
} else {
size = packetWrapper.passthrough(Type.UNSIGNED_BYTE);
}
for (int i = 0; i < size; i++) {
Item item = protocol.getItemRewriter().handleItemToClient(packetWrapper.read(Type.ITEM1_8));
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, item); //Buy Item 1
item = protocol.getItemRewriter().handleItemToClient(packetWrapper.read(Type.ITEM1_8));
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, item); //Buy Item 3
boolean has3Items = packetWrapper.passthrough(Type.BOOLEAN);
if (has3Items) {
item = protocol.getItemRewriter().handleItemToClient(packetWrapper.read(Type.ITEM1_8));
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, item); //Buy Item 2
}
packetWrapper.passthrough(Type.BOOLEAN); //Unavailable
packetWrapper.read(Type.INT); //Uses
packetWrapper.read(Type.INT); //Max Uses
}
} else if (channel.equalsIgnoreCase("MC|Brand")) {
packetWrapper.write(Type.REMAINING_BYTES, packetWrapper.read(Type.STRING).getBytes(StandardCharsets.UTF_8));
}
packetWrapper.cancel();
packetWrapper.setPacketType(null);
ByteBuf newPacketBuf = Unpooled.buffer();
packetWrapper.writeToBuffer(newPacketBuf);
PacketWrapper newWrapper = PacketWrapper.create(ClientboundPackets1_7_2_5.PLUGIN_MESSAGE, newPacketBuf, packetWrapper.user());
newWrapper.passthrough(Type.STRING);
if (newPacketBuf.readableBytes() <= Short.MAX_VALUE) {
newWrapper.write(Type.SHORT, (short) newPacketBuf.readableBytes());
newWrapper.send(Protocol1_7_6_10To1_8.class);
}
});
}
});
//Camera
protocol.registerClientbound(ClientboundPackets1_8.CAMERA, null, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
EntityTracker1_7_6_10 tracker = packetWrapper.user().get(EntityTracker1_7_6_10.class);
int entityId = packetWrapper.read(Type.VAR_INT);
int spectating = tracker.spectatingPlayerId;
if (spectating != entityId) {
tracker.setSpectating(entityId);
}
});
}
});
//Title
protocol.registerClientbound(ClientboundPackets1_8.TITLE, null, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
TitleRenderProvider titleRenderProvider = Via.getManager().getProviders().get(TitleRenderProvider.class);
if (titleRenderProvider == null) return;
int action = packetWrapper.read(Type.VAR_INT);
UUID uuid = packetWrapper.user().getProtocolInfo().getUuid();
switch (action) {
case 0:
titleRenderProvider.setTitle(uuid, packetWrapper.read(Type.STRING));
break;
case 1:
titleRenderProvider.setSubTitle(uuid, packetWrapper.read(Type.STRING));
break;
case 2:
titleRenderProvider.setTimings(uuid, packetWrapper.read(Type.INT), packetWrapper.read(Type.INT), packetWrapper.read(Type.INT));
break;
case 3:
titleRenderProvider.clear(uuid);
break;
case 4:
titleRenderProvider.reset(uuid);
break;
}
});
}
});
//Player List Header And Footer
protocol.cancelClientbound(ClientboundPackets1_8.TAB_LIST);
//Resource Pack Send
protocol.registerClientbound(ClientboundPackets1_8.RESOURCE_PACK, ClientboundPackets1_7_2_5.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
create(Type.STRING, "MC|RPack");
handler(packetWrapper -> {
ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
try {
// Url
Type.STRING.write(buf, packetWrapper.read(Type.STRING));
packetWrapper.write(Type.SHORT_BYTE_ARRAY, Type.REMAINING_BYTES.read(buf));
} finally {
buf.release();
}
});
read(Type.STRING); // Hash
}
});
/* INCOMING */
protocol.registerServerbound(ServerboundPackets1_7_2_5.CHAT_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> {
String msg = packetWrapper.get(Type.STRING, 0);
int gamemode = packetWrapper.user().get(PlayerSessionStorage.class).gameMode;
if (gamemode == 3 && msg.toLowerCase().startsWith("/stp ")) {
String username = msg.split(" ")[1];
GameProfileStorage storage = packetWrapper.user().get(GameProfileStorage.class);
GameProfileStorage.GameProfile profile = storage.get(username, true);
if (profile != null && profile.uuid != null) {
packetWrapper.cancel();
PacketWrapper teleportPacket = PacketWrapper.create(0x18, null, packetWrapper.user());
teleportPacket.write(Type.UUID, profile.uuid);
PacketUtil.sendToServer(teleportPacket, Protocol1_7_6_10To1_8.class, true, true);
}
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.INTERACT_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.INT, Type.VAR_INT);
map(Type.BYTE, Type.VAR_INT);
handler(wrapper -> {
int mode = wrapper.get(Type.VAR_INT, 1);
if (mode != 0) {
return;
}
final int entityId = wrapper.get(Type.VAR_INT, 0);
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
final PlayerSessionStorage position = wrapper.user().get(PlayerSessionStorage.class);
if (tracker.getVirtualHologramMap().containsKey(entityId)) {
final AABB boundingBox = tracker.getVirtualHologramMap().get(entityId).getBoundingBox();
Vector3d pos = new Vector3d(position.getPosX(), position.getPosY() + 1.8, position.getPosZ());
double yaw = Math.toRadians(position.yaw);
double pitch = Math.toRadians(position.pitch);
Vector3d dir = new Vector3d(-Math.cos(pitch) * Math.sin(yaw), -Math.sin(pitch), Math.cos(pitch) * Math.cos(yaw));
Ray3d ray = new Ray3d(pos, dir);
Vector3d intersection = RayTracing.trace(ray, boundingBox, 5.0);
if (intersection == null) {
return;
}
intersection.substract(boundingBox.getMin());
mode = 2;
wrapper.set(Type.VAR_INT, 1, mode);
wrapper.write(Type.FLOAT, (float) intersection.getX());
wrapper.write(Type.FLOAT, (float) intersection.getY());
wrapper.write(Type.FLOAT, (float) intersection.getZ());
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.PLAYER_MOVEMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.BOOLEAN);
handler(packetWrapper -> {
PlayerSessionStorage playerSession = packetWrapper.user().get(PlayerSessionStorage.class);
playerSession.onGround = packetWrapper.get(Type.BOOLEAN, 0);
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.PLAYER_POSITION, new PacketHandlers() {
@Override
public void register() {
map(Type.DOUBLE); //X
map(Type.DOUBLE); //Y
read(Type.DOUBLE);
map(Type.DOUBLE); //Z
map(Type.BOOLEAN); //OnGround
handler(packetWrapper -> {
double x = packetWrapper.get(Type.DOUBLE, 0);
double feetY = packetWrapper.get(Type.DOUBLE, 1);
double z = packetWrapper.get(Type.DOUBLE, 2);
PlayerSessionStorage playerSession = packetWrapper.user().get(PlayerSessionStorage.class);
playerSession.onGround = packetWrapper.get(Type.BOOLEAN, 0);
playerSession.setPos(x, feetY, z);
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.PLAYER_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.BOOLEAN);
handler(packetWrapper -> {
PlayerSessionStorage playerSession = packetWrapper.user().get(PlayerSessionStorage.class);
playerSession.yaw = packetWrapper.get(Type.FLOAT, 0);
playerSession.pitch = packetWrapper.get(Type.FLOAT, 1);
playerSession.onGround = packetWrapper.get(Type.BOOLEAN, 0);
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.PLAYER_POSITION_AND_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.DOUBLE); //X
map(Type.DOUBLE); //Y
read(Type.DOUBLE);
map(Type.DOUBLE); //Z
map(Type.FLOAT); //Yaw
map(Type.FLOAT); //Pitch
map(Type.BOOLEAN); //OnGround
handler(packetWrapper -> {
double x = packetWrapper.get(Type.DOUBLE, 0);
double feetY = packetWrapper.get(Type.DOUBLE, 1);
double z = packetWrapper.get(Type.DOUBLE, 2);
float yaw = packetWrapper.get(Type.FLOAT, 0);
float pitch = packetWrapper.get(Type.FLOAT, 1);
PlayerSessionStorage playerSession = packetWrapper.user().get(PlayerSessionStorage.class);
playerSession.onGround = packetWrapper.get(Type.BOOLEAN, 0);
playerSession.setPos(x, feetY, z);
playerSession.yaw = yaw;
playerSession.pitch = pitch;
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.PLAYER_DIGGING, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); //Status
handler(packetWrapper -> {
int x = packetWrapper.read(Type.INT);
int y = packetWrapper.read(Type.UNSIGNED_BYTE);
int z = packetWrapper.read(Type.INT);
packetWrapper.write(Type.POSITION1_8, new Position(x, y, z));
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.PLAYER_BLOCK_PLACEMENT, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int x = packetWrapper.read(Type.INT);
int y = packetWrapper.read(Type.UNSIGNED_BYTE);
int z = packetWrapper.read(Type.INT);
packetWrapper.write(Type.POSITION1_8, new Position(x, y, z));
packetWrapper.passthrough(Type.BYTE); //Direction
Item item = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM);
item = protocol.getItemRewriter().handleItemToServer(item);
packetWrapper.write(Type.ITEM1_8, item);
for (int i = 0; i < 3; i++) {
packetWrapper.passthrough(Type.BYTE);
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.ANIMATION, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int entityId = packetWrapper.read(Type.INT);
int animation = packetWrapper.read(Type.BYTE); //Animation
if (animation == 1) return;
packetWrapper.cancel();
//1.7 vanilla client is not sending this packet with animation!=1
switch (animation) {
case 104:
animation = 0;
break;
case 105:
animation = 1;
break;
case 3:
animation = 2;
break;
default:
return;
}
PacketWrapper entityAction = PacketWrapper.create(0x0B, null, packetWrapper.user());
entityAction.write(Type.VAR_INT, entityId);
entityAction.write(Type.VAR_INT, animation);
entityAction.write(Type.VAR_INT, 0);
PacketUtil.sendPacket(entityAction, Protocol1_7_6_10To1_8.class, true, true);
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.ENTITY_ACTION, new PacketHandlers() {
@Override
public void register() {
map(Type.INT, Type.VAR_INT); //Entity Id
handler(packetWrapper -> packetWrapper.write(Type.VAR_INT, packetWrapper.read(Type.BYTE) - 1)); //Action Id
map(Type.INT, Type.VAR_INT); //Action Parameter
handler(packetWrapper -> {
int action = packetWrapper.get(Type.VAR_INT, 1);
if (action == 3 || action == 4) {
PlayerSessionStorage playerSession = packetWrapper.user().get(PlayerSessionStorage.class);
playerSession.sprinting = action == 3;
PacketWrapper abilitiesPacket = PacketWrapper.create(0x39, null, packetWrapper.user());
abilitiesPacket.write(Type.BYTE, playerSession.combineAbilities());
abilitiesPacket.write(Type.FLOAT, playerSession.sprinting ? playerSession.flySpeed * 2.0f : playerSession.flySpeed);
abilitiesPacket.write(Type.FLOAT, playerSession.walkSpeed);
PacketUtil.sendPacket(abilitiesPacket, Protocol1_7_6_10To1_8.class);
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.STEER_VEHICLE, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT); //Sideways
map(Type.FLOAT); //Forwards
handler(packetWrapper -> {
boolean jump = packetWrapper.read(Type.BOOLEAN);
boolean unmount = packetWrapper.read(Type.BOOLEAN);
short flags = 0;
if (jump) flags += 0x01;
if (unmount) flags += 0x02;
packetWrapper.write(Type.UNSIGNED_BYTE, flags);
if (unmount) {
EntityTracker1_7_6_10 tracker = packetWrapper.user().get(EntityTracker1_7_6_10.class);
if (tracker.spectatingPlayerId != tracker.getPlayerId()) {
PacketWrapper sneakPacket = PacketWrapper.create(0x0B, null, packetWrapper.user());
sneakPacket.write(Type.VAR_INT, tracker.getPlayerId());
sneakPacket.write(Type.VAR_INT, 0); //Start sneaking
sneakPacket.write(Type.VAR_INT, 0); //Action Parameter
PacketWrapper unsneakPacket = PacketWrapper.create(0x0B, null, packetWrapper.user());
unsneakPacket.write(Type.VAR_INT, tracker.getPlayerId());
unsneakPacket.write(Type.VAR_INT, 1); //Stop sneaking
unsneakPacket.write(Type.VAR_INT, 0); //Action Parameter
PacketUtil.sendToServer(sneakPacket, Protocol1_7_6_10To1_8.class);
}
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.UPDATE_SIGN, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int x = packetWrapper.read(Type.INT);
int y = packetWrapper.read(Type.SHORT);
int z = packetWrapper.read(Type.INT);
packetWrapper.write(Type.POSITION1_8, new Position(x, y, z));
for (int i = 0; i < 4; i++) {
String line = packetWrapper.read(Type.STRING);
line = ChatUtil.legacyToJson(line);
packetWrapper.write(Type.COMPONENT, JsonParser.parseString(line));
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.PLAYER_ABILITIES, new PacketHandlers() {
@Override
public void register() {
map(Type.BYTE);
map(Type.FLOAT);
map(Type.FLOAT);
handler(packetWrapper -> {
PlayerSessionStorage playerSession = packetWrapper.user().get(PlayerSessionStorage.class);
if (playerSession.allowFly) {
byte flags = packetWrapper.get(Type.BYTE, 0);
playerSession.flying = (flags & 2) == 2;
}
packetWrapper.set(Type.FLOAT, 0, playerSession.flySpeed);
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.TAB_COMPLETE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
create(Type.OPTIONAL_POSITION1_8, null);
handler(packetWrapper -> {
String msg = packetWrapper.get(Type.STRING, 0);
if (msg.toLowerCase().startsWith("/stp ")) {
packetWrapper.cancel();
String[] args = msg.split(" ");
if (args.length <= 2) {
String prefix = args.length == 1 ? "" : args[1];
GameProfileStorage storage = packetWrapper.user().get(GameProfileStorage.class);
List<GameProfileStorage.GameProfile> profiles = storage.getAllWithPrefix(prefix, true);
PacketWrapper tabComplete = PacketWrapper.create(0x3A, null, packetWrapper.user());
tabComplete.write(Type.VAR_INT, profiles.size());
for (GameProfileStorage.GameProfile profile : profiles) {
tabComplete.write(Type.STRING, profile.name);
}
PacketUtil.sendPacket(tabComplete, Protocol1_7_6_10To1_8.class);
}
}
});
}
});
//Client Settings
protocol.registerServerbound(ServerboundPackets1_7_2_5.CLIENT_SETTINGS, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
map(Type.BYTE);
map(Type.BYTE);
map(Type.BOOLEAN);
read(Type.BYTE);
handler(packetWrapper -> {
boolean cape = packetWrapper.read(Type.BOOLEAN);
packetWrapper.write(Type.UNSIGNED_BYTE, (short) (cape ? 127 : 126));
});
}
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
read(Type.SHORT); // Length
handler(packetWrapper -> {
String channel = packetWrapper.get(Type.STRING, 0);
switch (channel) {
case "MC|TrSel": {
packetWrapper.passthrough(Type.INT);
packetWrapper.read(Type.REMAINING_BYTES); // unused data ???
break;
}
case "MC|ItemName": {
byte[] data = packetWrapper.read(Type.REMAINING_BYTES);
String name = new String(data, StandardCharsets.UTF_8);
packetWrapper.write(Type.STRING, name);
InventoryTracker windowTracker = packetWrapper.user().get(InventoryTracker.class);
PacketWrapper updateCost = PacketWrapper.create(0x31, null, packetWrapper.user());
updateCost.write(Type.UNSIGNED_BYTE, windowTracker.anvilId);
updateCost.write(Type.SHORT, (short) 0);
updateCost.write(Type.SHORT, windowTracker.levelCost);
PacketUtil.sendPacket(updateCost, Protocol1_7_6_10To1_8.class, true, true);
break;
}
case "MC|BEdit":
case "MC|BSign": {
Item book = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM);
CompoundTag tag = book.tag();
if (tag != null && tag.contains("pages")) {
ListTag pages = tag.get("pages");
for (int i = 0; i < pages.size(); i++) {
StringTag page = pages.get(i);
String value = page.getValue();
value = ChatUtil.legacyToJson(value);
page.setValue(value);
}
}
packetWrapper.write(Type.ITEM1_8, book);
break;
}
case "MC|Brand": {
packetWrapper.write(Type.STRING, new String(packetWrapper.read(Type.REMAINING_BYTES), StandardCharsets.UTF_8));
break;
}
}
});
}
});
}
}
@@ -1,262 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.Scoreboard;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.util.ChatColorUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class ScoreboardPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
/* OUTGOING */
//Scoreboard Objective
protocol.registerClientbound(ClientboundPackets1_8.SCOREBOARD_OBJECTIVE, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
String name = packetWrapper.passthrough(Type.STRING);
if (name.length() > 16) {
packetWrapper.set(Type.STRING, 0, name = name.substring(0, 16));
}
byte mode = packetWrapper.read(Type.BYTE);
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
if (mode == 0) {
if (scoreboard.objectiveExists(name)) {
packetWrapper.cancel();
return;
}
scoreboard.addObjective(name);
} else if (mode == 1) {
if (!scoreboard.objectiveExists(name)) {
packetWrapper.cancel();
return;
}
if (scoreboard.getColorIndependentSidebar() != null) {
String username = packetWrapper.user().getProtocolInfo().getUsername();
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
if (color.isPresent()) {
String sidebar = scoreboard.getColorDependentSidebar().get(color.get());
if (name.equals(sidebar)) {
PacketWrapper sidebarPacket = PacketWrapper.create(0x3D, null, packetWrapper.user());
sidebarPacket.write(Type.BYTE, (byte) 1);
sidebarPacket.write(Type.STRING, scoreboard.getColorIndependentSidebar());
PacketUtil.sendPacket(sidebarPacket, Protocol1_7_6_10To1_8.class);
}
}
}
scoreboard.removeObjective(name);
} else if (mode == 2) {
if (!scoreboard.objectiveExists(name)) {
packetWrapper.cancel();
return;
}
}
if (mode == 0 || mode == 2) {
String displayName = packetWrapper.passthrough(Type.STRING);
if (displayName.length() > 32) {
packetWrapper.set(Type.STRING, 1, displayName.substring(0, 32));
}
packetWrapper.read(Type.STRING);
} else {
packetWrapper.write(Type.STRING, "");
}
packetWrapper.write(Type.BYTE, mode);
});
}
});
//Update Score
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_SCORE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING); // Name
map(Type.VAR_INT, Type.BYTE); // Mode
handler(packetWrapper -> {
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
String name = packetWrapper.get(Type.STRING, 0);
byte mode = packetWrapper.get(Type.BYTE, 0);
if (mode == 1) {
name = scoreboard.removeTeamForScore(name);
} else {
name = scoreboard.sendTeamForScore(name);
}
if (name.length() > 16) {
name = ChatColorUtil.stripColor(name);
if (name.length() > 16) {
name = name.substring(0, 16);
}
}
packetWrapper.set(Type.STRING, 0, name);
String objective = packetWrapper.read(Type.STRING);
if (objective.length() > 16) {
objective = objective.substring(0, 16);
}
if (mode != 1) {
int score = packetWrapper.read(Type.VAR_INT);
packetWrapper.write(Type.STRING, objective);
packetWrapper.write(Type.INT, score);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.DISPLAY_SCOREBOARD, new PacketHandlers() {
@Override
public void register() {
map(Type.BYTE); // Position
map(Type.STRING); // Score name
handler(packetWrapper -> {
byte position = packetWrapper.get(Type.BYTE, 0);
String name = packetWrapper.get(Type.STRING, 0);
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
if (position > 2) { // team specific sidebar
byte receiverTeamColor = (byte) (position - 3);
scoreboard.getColorDependentSidebar().put(receiverTeamColor, name);
String username = packetWrapper.user().getProtocolInfo().getUsername();
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
if (color.isPresent() && color.get() == receiverTeamColor) {
position = 1;
} else {
position = -1;
}
} else if (position == 1) { // team independent sidebar
scoreboard.setColorIndependentSidebar(name);
String username = packetWrapper.user().getProtocolInfo().getUsername();
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
if (color.isPresent() && scoreboard.getColorDependentSidebar().containsKey(color.get())) {
position = -1;
}
}
if (position == -1) {
packetWrapper.cancel();
return;
}
packetWrapper.set(Type.BYTE, 0, position);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.TEAMS, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> {
String team = packetWrapper.get(Type.STRING, 0);
if (team == null) {
packetWrapper.cancel();
return;
}
byte mode = packetWrapper.passthrough(Type.BYTE);
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
if (mode != 0 && !scoreboard.teamExists(team)) {
packetWrapper.cancel();
return;
} else if (mode == 0 && scoreboard.teamExists(team)) {
scoreboard.removeTeam(team);
PacketWrapper remove = PacketWrapper.create(0x3E, null, packetWrapper.user());
remove.write(Type.STRING, team);
remove.write(Type.BYTE, (byte) 1);
PacketUtil.sendPacket(remove, Protocol1_7_6_10To1_8.class, true, true);
}
if (mode == 0) {
scoreboard.addTeam(team);
} else if (mode == 1) {
scoreboard.removeTeam(team);
}
if (mode == 0 || mode == 2) {
packetWrapper.passthrough(Type.STRING); // Display name
packetWrapper.passthrough(Type.STRING); // prefix
packetWrapper.passthrough(Type.STRING); // suffix
packetWrapper.passthrough(Type.BYTE); // friendly fire
packetWrapper.read(Type.STRING); // name tag visibility
byte color = packetWrapper.read(Type.BYTE);
if (mode == 2 && scoreboard.getTeamColor(team).get() != color) {
String username = packetWrapper.user().getProtocolInfo().getUsername();
String sidebar = scoreboard.getColorDependentSidebar().get(color);
PacketWrapper sidebarPacket = packetWrapper.create(0x3D);
sidebarPacket.write(Type.BYTE, (byte) 1);
sidebarPacket.write(Type.STRING, sidebar == null ? "" : sidebar);
PacketUtil.sendPacket(sidebarPacket, Protocol1_7_6_10To1_8.class);
}
scoreboard.setTeamColor(team, color);
}
if (mode == 0 || mode == 3 || mode == 4) {
byte color = scoreboard.getTeamColor(team).get();
String[] entries = packetWrapper.read(Type.STRING_ARRAY);
List<String> entryList = new ArrayList<>();
for (int i = 0; i < entries.length; i++) {
String entry = entries[i];
String username = packetWrapper.user().getProtocolInfo().getUsername();
if (mode == 4) {
if (!scoreboard.isPlayerInTeam(entry, team)) continue;
scoreboard.removePlayerFromTeam(entry, team);
if (entry.equals(username)) {
PacketWrapper sidebarPacket = packetWrapper.create(0x3D);
sidebarPacket.write(Type.BYTE, (byte) 1);
sidebarPacket.write(Type.STRING, scoreboard.getColorIndependentSidebar() == null ? "" : scoreboard.getColorIndependentSidebar());
PacketUtil.sendPacket(sidebarPacket, Protocol1_7_6_10To1_8.class);
}
} else {
scoreboard.addPlayerToTeam(entry, team);
if (entry.equals(username) && scoreboard.getColorDependentSidebar().containsKey(color)) {
PacketWrapper displayObjective = packetWrapper.create(0x3D);
displayObjective.write(Type.BYTE, (byte) 1);
displayObjective.write(Type.STRING, scoreboard.getColorDependentSidebar().get(color));
PacketUtil.sendPacket(displayObjective, Protocol1_7_6_10To1_8.class);
}
}
entryList.add(entry);
}
packetWrapper.write(Type.SHORT, (short) entryList.size());
for (String entry : entryList) {
packetWrapper.write(Type.STRING, entry);
}
}
});
}
});
}
}
@@ -1,301 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.ClientboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model.VirtualHologramEntity;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.GameProfileStorage;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.EntityTracker1_7_6_10;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viarewind.api.rewriter.item.Replacement;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import java.util.List;
import java.util.UUID;
public class SpawnPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PLAYER, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // entity id
handler(wrapper -> {
final UUID uuid = wrapper.read(Type.UUID);
wrapper.write(Type.STRING, uuid.toString()); // map to string
final GameProfileStorage gameProfileStorage = wrapper.user().get(GameProfileStorage.class);
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null) {
wrapper.write(Type.STRING, ""); // name
wrapper.write(Type.VAR_INT, 0); // properties count
} else {
wrapper.write(Type.STRING, gameProfile.name.length() > 16 ? gameProfile.name.substring(0, 16) : gameProfile.name); // name
wrapper.write(Type.VAR_INT, gameProfile.properties.size()); // properties count
for (GameProfileStorage.Property property : gameProfile.properties) {
wrapper.write(Type.STRING, property.name); // property name
wrapper.write(Type.STRING, property.value); // property value
wrapper.write(Type.STRING, property.signature == null ? "" : property.signature); // property signature
}
}
final int entityId = wrapper.get(Type.VAR_INT, 0);
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
if (gameProfile != null && gameProfile.gamemode == 3) { // Spectator mode
for (short i = 0; i < 5; i++) {
final PacketWrapper entityEquipment = PacketWrapper.create(ClientboundPackets1_7_2_5.ENTITY_EQUIPMENT, wrapper.user());
entityEquipment.write(Type.INT, entityId);
entityEquipment.write(Type.SHORT, i);
entityEquipment.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, i == 4 ? gameProfile.getSkull() : null);
entityEquipment.scheduleSend(Protocol1_7_6_10To1_8.class, true);
}
}
tracker.addPlayer(entityId, uuid);
});
map(Type.INT); // x
map(Type.INT); // y
map(Type.INT); // z
map(Type.BYTE); // yaw
map(Type.BYTE); // pitch
map(Type.SHORT); // item in hand id
map(Types1_8.METADATA_LIST, Types1_7_6_10.METADATA_LIST); // metadata
handler(wrapper -> {
final List<Metadata> metadata = wrapper.get(Types1_7_6_10.METADATA_LIST, 0);
protocol.getMetadataRewriter().transform(EntityTypes1_10.EntityType.PLAYER, metadata);
wrapper.set(Types1_7_6_10.METADATA_LIST, 0, metadata);
});
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
tracker.addEntity(wrapper.get(Type.VAR_INT, 0), EntityTypes1_10.EntityType.PLAYER);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // entity id
map(Type.BYTE); // type id
map(Type.INT); // x
map(Type.INT); // y
map(Type.INT); // z
map(Type.BYTE); // pitch
map(Type.BYTE); // yaw
map(Type.INT); // data
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
final EntityTypes1_10.EntityType type = EntityTypes1_10.getTypeFromId(wrapper.get(Type.BYTE, 0), true);
final int entityId = wrapper.get(Type.VAR_INT, 0);
int x = wrapper.get(Type.INT, 0);
int y = wrapper.get(Type.INT, 1);
int z = wrapper.get(Type.INT, 2);
byte pitch = wrapper.get(Type.BYTE, 1);
byte yaw = wrapper.get(Type.BYTE, 2);
int data = wrapper.get(Type.INT, 3);
if (type == EntityTypes1_10.ObjectType.ITEM_FRAME.getType()) {
switch (yaw) {
case -128:
z += 32;
yaw = 0;
break;
case -64:
x -= 32;
yaw = -64;
break;
case 0:
z -= 32;
yaw = -128;
break;
case 64:
x += 32;
yaw = 64;
break;
}
} else if (type == EntityTypes1_10.ObjectType.ARMOR_STAND.getType()) {
wrapper.cancel();
final VirtualHologramEntity hologram = new VirtualHologramEntity(wrapper.user(), protocol.getMetadataRewriter(), entityId);
hologram.updateReplacementPosition(x / 32.0, y / 32.0, z / 32.0);
hologram.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
hologram.setHeadYaw(yaw * 360f / 256);
tracker.trackHologram(entityId, hologram);
}
// TODO | Realign all entities
wrapper.set(Type.INT, 0, x);
wrapper.set(Type.INT, 1, y);
wrapper.set(Type.INT, 2, z);
wrapper.set(Type.BYTE, 2, yaw);
tracker.addEntity(entityId, type);
if (type != null && type.isOrHasParent(EntityTypes1_10.EntityType.FALLING_BLOCK)) {
int blockId = data & 0xFFF;
int blockData = data >> 12 & 0xF;
final Replacement replace = protocol.getItemRewriter().replace(blockId, blockData);
if (replace != null) {
blockId = replace.getId();
blockData = replace.replaceData(blockData);
}
wrapper.set(Type.INT, 3, data = (blockId | blockData << 16));
}
if (data > 0) {
wrapper.passthrough(Type.SHORT); // velocity x
wrapper.passthrough(Type.SHORT); // velocity y
wrapper.passthrough(Type.SHORT); // velocity z
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_MOB, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // entity id
map(Type.UNSIGNED_BYTE); // type id
map(Type.INT); // x
map(Type.INT); // y
map(Type.INT); // z
map(Type.BYTE); // yaw
map(Type.BYTE); // pitch
map(Type.BYTE); // head yaw
map(Type.SHORT); // velocity x
map(Type.SHORT); // velocity y
map(Type.SHORT); // velocity z
map(Types1_8.METADATA_LIST, Types1_7_6_10.METADATA_LIST); // metadata
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
final short typeId = wrapper.get(Type.UNSIGNED_BYTE, 0);
if (typeId == 255 || typeId == -1) {
wrapper.cancel();
}
final EntityTypes1_10.EntityType type = EntityTypes1_10.getTypeFromId(typeId, false);
final int entityId = wrapper.get(Type.VAR_INT, 0);
final int x = wrapper.get(Type.INT, 0);
final int y = wrapper.get(Type.INT, 1);
final int z = wrapper.get(Type.INT, 2);
final byte pitch = wrapper.get(Type.BYTE, 1);
final byte yaw = wrapper.get(Type.BYTE, 0);
final byte headYaw = wrapper.get(Type.BYTE, 2);
final List<Metadata> metadataList = wrapper.get(Types1_7_6_10.METADATA_LIST, 0);
if (type == EntityTypes1_10.EntityType.ARMOR_STAND) {
final VirtualHologramEntity hologram = new VirtualHologramEntity(wrapper.user(), protocol.getMetadataRewriter(), entityId);
hologram.updateReplacementPosition(x / 32.0, y / 32.0, z / 32.0);
hologram.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
hologram.setHeadYaw(headYaw * 360f / 256);
tracker.trackHologram(entityId, hologram);
tracker.updateMetadata(entityId, metadataList); // Track and remap hologram <-> zombie metadata
wrapper.cancel();
} else {
protocol.getMetadataRewriter().transform(type, metadataList);
tracker.addEntity(entityId, type);
if (tracker.isReplaced(type)) {
final int newTypeId = tracker.replaceEntity(entityId, type);
wrapper.set(Type.UNSIGNED_BYTE, 0, (short) newTypeId);
tracker.updateMetadata(entityId, metadataList);
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PAINTING, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // entity id
map(Type.STRING); // title
handler(wrapper -> {
final Position position = wrapper.read(Type.POSITION1_8);
wrapper.write(Type.INT, position.x());
wrapper.write(Type.INT, position.y());
wrapper.write(Type.INT, position.z());
});
map(Type.UNSIGNED_BYTE, Type.INT); // rotation
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
tracker.addEntity(wrapper.get(Type.VAR_INT, 0), EntityTypes1_10.EntityType.PAINTING);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_EXPERIENCE_ORB, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // entity id
map(Type.INT); // x
map(Type.INT); // y
map(Type.INT); // z
map(Type.SHORT); // count
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
tracker.addEntity(wrapper.get(Type.VAR_INT, 0), EntityTypes1_10.EntityType.EXPERIENCE_ORB);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_GLOBAL_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // entity id
map(Type.BYTE); // type id
map(Type.INT); // x
map(Type.INT); // y
map(Type.INT); // z
handler(wrapper -> {
final EntityTracker1_7_6_10 tracker = wrapper.user().get(EntityTracker1_7_6_10.class);
tracker.addEntity(wrapper.get(Type.VAR_INT, 0), EntityTypes1_10.EntityType.LIGHTNING);
});
}
});
}
}
@@ -1,304 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.WorldBorderEmulator;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.chunk.ChunkType1_7_6;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.chunk.BulkChunkType1_7_6;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model.ParticleIndex1_7_6_10;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viarewind.utils.ChatUtil;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.FixedByteArrayType;
import com.viaversion.viaversion.api.type.types.chunk.BulkChunkType1_8;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.util.ChatColorUtil;
public class WorldPackets {
private static void rewriteBlockIds(final Protocol1_7_6_10To1_8 protocol, final Chunk chunk) {
for (ChunkSection section : chunk.getSections()) {
if (section == null) continue;
final DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int i = 0; i < palette.size(); i++) {
palette.setIdByIndex(i, protocol.getItemRewriter().replace(palette.idByIndex(i)));
}
}
}
public static void register(Protocol1_7_6_10To1_8 protocol) {
protocol.registerClientbound(ClientboundPackets1_8.CHUNK_DATA, wrapper -> {
final ClientWorld world = wrapper.user().get(ClientWorld.class);
final Chunk chunk = wrapper.read(ChunkType1_8.forEnvironment(world.getEnvironment()));
rewriteBlockIds(protocol, chunk);
wrapper.write(ChunkType1_7_6.TYPE, chunk);
});
protocol.registerClientbound(ClientboundPackets1_8.MULTI_BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // chunk x
map(Type.INT); // chunk z
handler(wrapper -> {
final BlockChangeRecord[] records = wrapper.read(Type.BLOCK_CHANGE_RECORD_ARRAY);
wrapper.write(Type.SHORT, (short) records.length); // record count
wrapper.write(Type.INT, records.length * 4); // data array length (position + block id)
for (BlockChangeRecord record : records) {
wrapper.write(Type.SHORT, (short) (record.getSectionX() << 12 | record.getSectionZ() << 8 | record.getY())); // position
wrapper.write(Type.SHORT, (short) protocol.getItemRewriter().replace(record.getBlockId())); // block id
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_CHANGE, new PacketHandlers() {
@Override
protected void register() {
map(Type.POSITION1_8, Types1_7_6_10.U_BYTE_POSITION); // position
handler(wrapper -> {
int data = wrapper.read(Type.VAR_INT); // block data
data = protocol.getItemRewriter().replace(data);
wrapper.write(Type.VAR_INT, data >> 4); // block id
wrapper.write(Type.UNSIGNED_BYTE, (short) (data & 0xF)); // block data
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_ACTION, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION1_8, Types1_7_6_10.SHORT_POSITION); // position
map(Type.UNSIGNED_BYTE); // type
map(Type.UNSIGNED_BYTE); // data
map(Type.VAR_INT); // block id
}
});
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_BREAK_ANIMATION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // entity id
map(Type.POSITION1_8, Types1_7_6_10.INT_POSITION); // position
map(Type.BYTE); // progress
}
});
protocol.registerClientbound(ClientboundPackets1_8.MAP_BULK_CHUNK, wrapper -> {
final Chunk[] chunks = wrapper.read(BulkChunkType1_8.TYPE);
for (Chunk chunk : chunks) {
rewriteBlockIds(protocol, chunk);
}
wrapper.write(BulkChunkType1_7_6.TYPE, chunks);
});
protocol.registerClientbound(ClientboundPackets1_8.EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // effect id
map(Type.POSITION1_8, Types1_7_6_10.BYTE_POSITION); // position
map(Type.INT); // data
map(Type.BOOLEAN); // disable relative volume
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PARTICLE, new PacketHandlers() {
@Override
public void register() {
handler(wrapper -> {
final int particleId = wrapper.read(Type.INT); // particle id
ParticleIndex1_7_6_10 particle = ParticleIndex1_7_6_10.find(particleId);
if (particle == null) particle = ParticleIndex1_7_6_10.CRIT;
wrapper.write(Type.STRING, particle.name); // particle name
});
read(Type.BOOLEAN); // long distance
map(Type.FLOAT); // x
map(Type.FLOAT); // y
map(Type.FLOAT); // z
map(Type.FLOAT); // offset x
map(Type.FLOAT); // offset y
map(Type.FLOAT); // offset z
map(Type.FLOAT); // particle data
map(Type.INT); // particle count
handler(wrapper -> {
String name = wrapper.get(Type.STRING, 0);
ParticleIndex1_7_6_10 particle = ParticleIndex1_7_6_10.find(name);
if (particle == ParticleIndex1_7_6_10.ICON_CRACK || particle == ParticleIndex1_7_6_10.BLOCK_CRACK || particle == ParticleIndex1_7_6_10.BLOCK_DUST) {
int id = wrapper.read(Type.VAR_INT);
int data = particle == ParticleIndex1_7_6_10.ICON_CRACK ? wrapper.read(Type.VAR_INT) : id / 4096;
id %= 4096;
if (id >= 256 && id <= 422 || id >= 2256 && id <= 2267) { //item
particle = ParticleIndex1_7_6_10.ICON_CRACK;
} else if (id >= 0 && id <= 164 || id >= 170 && id <= 175) {
if (particle == ParticleIndex1_7_6_10.ICON_CRACK) particle = ParticleIndex1_7_6_10.BLOCK_CRACK;
} else {
wrapper.cancel();
return;
}
name = particle.name + "_" + id + "_" + data;
}
wrapper.set(Type.STRING, 0, name);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_SIGN, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION1_8, Types1_7_6_10.SHORT_POSITION); // position
handler(wrapper -> {
for (int i = 0; i < 4; i++) {
String line = wrapper.read(Type.STRING);
line = ChatUtil.jsonToLegacy(line);
line = ChatUtil.removeUnusedColor(line, '0');
if (line.length() > 15) {
line = ChatColorUtil.stripColor(line);
if (line.length() > 15) line = line.substring(0, 15);
}
wrapper.write(Type.STRING, line);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.MAP_DATA, new PacketHandlers() {
@Override
public void register() {
handler(wrapper -> {
wrapper.cancel();
final int id = wrapper.read(Type.VAR_INT);
final byte scale = wrapper.read(Type.BYTE);
final int iconCount = wrapper.read(Type.VAR_INT);
byte[] icons = new byte[iconCount * 4];
for (int i = 0; i < iconCount; i++) {
final int directionAndType = wrapper.read(Type.BYTE);
icons[i * 4] = (byte) (directionAndType >> 4 & 0xF);
icons[i * 4 + 1] = wrapper.read(Type.BYTE); // x
icons[i * 4 + 2] = wrapper.read(Type.BYTE); // z
icons[i * 4 + 3] = (byte) (directionAndType & 0xF);
}
final short columns = wrapper.read(Type.UNSIGNED_BYTE);
if (columns > 0) {
final short rows = wrapper.read(Type.UNSIGNED_BYTE);
final short x = wrapper.read(Type.UNSIGNED_BYTE);
final short z = wrapper.read(Type.UNSIGNED_BYTE);
final byte[] data = wrapper.read(Type.BYTE_ARRAY_PRIMITIVE);
for (int column = 0; column < columns; column++) {
byte[] columnData = new byte[rows + 3];
columnData[0] = 0;
columnData[1] = (byte) (x + column);
columnData[2] = (byte) z;
for (int i = 0; i < rows; i++) {
columnData[i + 3] = data[column + i * columns];
}
final PacketWrapper mapData = PacketWrapper.create(ClientboundPackets1_8.MAP_DATA, wrapper.user());
mapData.write(Type.VAR_INT, id); // map id
mapData.write(Type.SHORT, (short) columnData.length); // data length
mapData.write(new FixedByteArrayType(columnData.length), columnData); // data
mapData.send(Protocol1_7_6_10To1_8.class, true);
}
}
if (iconCount > 0) {
final byte[] iconData = new byte[iconCount * 3 + 1];
iconData[0] = 1;
for (int i = 0; i < iconCount; i++) {
iconData[i * 3 + 1] = (byte) (icons[i * 4] << 4 | icons[i * 4 + 3] & 0xF);
iconData[i * 3 + 2] = icons[i * 4 + 1];
iconData[i * 3 + 3] = icons[i * 4 + 2];
}
final PacketWrapper mapData = PacketWrapper.create(ClientboundPackets1_8.MAP_DATA, wrapper.user());
mapData.write(Type.VAR_INT, id); // map id
mapData.write(Type.SHORT, (short) iconData.length); // data length
mapData.write(new FixedByteArrayType(iconData.length), iconData); // data
mapData.send(Protocol1_7_6_10To1_8.class, true);
}
// Update scale
final PacketWrapper mapData = PacketWrapper.create(ClientboundPackets1_8.MAP_DATA, wrapper.user());
mapData.write(Type.VAR_INT, id); // map id
mapData.write(Type.SHORT, (short) 2); // data length
mapData.write(new FixedByteArrayType(2), new byte[]{ 2, scale }); // data
mapData.send(Protocol1_7_6_10To1_8.class, true);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_ENTITY_DATA, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION1_8, Types1_7_6_10.SHORT_POSITION); // position
map(Type.UNSIGNED_BYTE); // action
map(Type.NAMED_COMPOUND_TAG, Types1_7_6_10.COMPRESSED_NBT); // nbt
}
});
protocol.cancelClientbound(ClientboundPackets1_8.SERVER_DIFFICULTY);
protocol.cancelClientbound(ClientboundPackets1_8.COMBAT_EVENT);
protocol.registerClientbound(ClientboundPackets1_8.WORLD_BORDER, null, wrapper -> {
final WorldBorderEmulator emulator = wrapper.user().get(WorldBorderEmulator.class);
wrapper.cancel();
final int action = wrapper.read(Type.VAR_INT);
if (action == 0) { // set size
emulator.setSize(wrapper.read(Type.DOUBLE)); // radius
} else if (action == 1) { // lerp size
emulator.lerpSize(wrapper.read(Type.DOUBLE), wrapper.read(Type.DOUBLE), wrapper.read(Type.VAR_LONG)); // old radius, new radius, speed
} else if (action == 2) { // set center
emulator.setCenter(wrapper.read(Type.DOUBLE), wrapper.read(Type.DOUBLE)); // x, z
} else if (action == 3) { // initialize
emulator.init(
wrapper.read(Type.DOUBLE), wrapper.read(Type.DOUBLE), // x, z
wrapper.read(Type.DOUBLE), wrapper.read(Type.DOUBLE), // old radius, new radius
wrapper.read(Type.VAR_LONG) // speed
);
}
});
}
}
@@ -1,41 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.CompressionStatusTracker;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.platform.providers.Provider;
import io.netty.channel.ChannelHandler;
public abstract class CompressionHandlerProvider implements Provider {
public abstract void onHandleLoginCompressionPacket(UserConnection user, int threshold);
public abstract void onTransformPacket(UserConnection user);
public abstract ChannelHandler getEncoder(int threshold);
public abstract ChannelHandler getDecoder(int threshold);
public boolean isCompressionEnabled(UserConnection user) {
return user.get(CompressionStatusTracker.class).removeCompression;
}
public void setCompressionEnabled(UserConnection user, boolean enabled) {
user.get(CompressionStatusTracker.class).removeCompression = enabled;
}
}
@@ -1,99 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider;
import com.viaversion.viaversion.api.platform.providers.Provider;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class TitleRenderProvider implements Provider {
protected Map<UUID, Integer> fadeIn = new HashMap<>();
protected Map<UUID, Integer> stay = new HashMap<>();
protected Map<UUID, Integer> fadeOut = new HashMap<>();
protected Map<UUID, String> titles = new HashMap<>();
protected Map<UUID, String> subTitles = new HashMap<>();
protected Map<UUID, AtomicInteger> times = new HashMap<>();
public void setTimings(UUID uuid, int fadeIn, int stay, int fadeOut) {
setFadeIn(uuid, fadeIn);
setStay(uuid, stay);
setFadeOut(uuid, fadeOut);
AtomicInteger time = getTime(uuid);
if (time.get() > 0) time.set(getFadeIn(uuid) + getStay(uuid) + getFadeOut(uuid));
}
public void reset(UUID uuid) {
this.titles.remove(uuid);
this.subTitles.remove(uuid);
getTime(uuid).set(0);
fadeIn.remove(uuid);
stay.remove(uuid);
fadeOut.remove(uuid);
}
public void setTitle(UUID uuid, String title) {
this.titles.put(uuid, title);
getTime(uuid).set(getFadeIn(uuid) + getStay(uuid) + getFadeOut(uuid));
}
public void setSubTitle(UUID uuid, String subTitle) {
this.subTitles.put(uuid, subTitle);
}
public void clear(UUID uuid) {
this.titles.remove(uuid);
this.subTitles.remove(uuid);
getTime(uuid).set(0);
}
public AtomicInteger getTime(UUID uuid) {
return times.computeIfAbsent(uuid, key -> new AtomicInteger(0));
}
public int getFadeIn(UUID uuid) {
return fadeIn.getOrDefault(uuid, 10);
}
public int getStay(UUID uuid) {
return stay.getOrDefault(uuid, 70);
}
public int getFadeOut(UUID uuid) {
return fadeOut.getOrDefault(uuid, 20);
}
public void setFadeIn(UUID uuid, int fadeIn) {
if (fadeIn >= 0) this.fadeIn.put(uuid, fadeIn);
else this.fadeIn.remove(uuid);
}
public void setStay(UUID uuid, int stay) {
if (stay >= 0) this.stay.put(uuid, stay);
else this.stay.remove(uuid);
}
public void setFadeOut(UUID uuid, int fadeOut) {
if (fadeOut >= 0) this.fadeOut.put(uuid, fadeOut);
else this.fadeOut.remove(uuid);
}
}
@@ -1,56 +0,0 @@
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider.compression;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List;
import java.util.zip.Inflater;
// https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/netty/CompressionDecoder.java
public class CompressionDecoder extends MessageToMessageDecoder<ByteBuf> {
private final Inflater inflater = new Inflater();
private final int threshold;
public CompressionDecoder(final int threshold) {
this.threshold = threshold;
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (!in.isReadable()) return;
int outLength = Type.VAR_INT.readPrimitive(in);
if (outLength == 0) {
out.add(in.readBytes(in.readableBytes()));
return;
}
if (outLength < this.threshold) {
throw new DecoderException("Badly compressed packet - size of " + outLength + " is below server threshold of " + this.threshold);
} else if (outLength > 2097152) {
throw new DecoderException("Badly compressed packet - size of " + outLength + " is larger than protocol maximum of " + 2097152);
}
ByteBuf temp = in;
if (!in.hasArray()) {
temp = ByteBufAllocator.DEFAULT.heapBuffer().writeBytes(in);
} else {
in.retain();
}
ByteBuf output = ByteBufAllocator.DEFAULT.heapBuffer(outLength, outLength);
try {
this.inflater.setInput(temp.array(), temp.arrayOffset() + temp.readerIndex(), temp.readableBytes());
output.writerIndex(output.writerIndex() + this.inflater.inflate(output.array(), output.arrayOffset(), outLength));
out.add(output.retain());
} finally {
output.release();
temp.release();
this.inflater.reset();
}
}
}
@@ -1,54 +0,0 @@
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider.compression;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import java.util.zip.Deflater;
// https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/netty/CompressionEncoder.java
public class CompressionEncoder extends MessageToByteEncoder<ByteBuf> {
private final Deflater deflater = new Deflater();
private final int threshold;
public CompressionEncoder(final int threshold) {
this.threshold = threshold;
}
@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception {
int frameLength = in.readableBytes();
if (frameLength < this.threshold) {
out.writeByte(0); // VarInt
out.writeBytes(in);
return;
}
Type.VAR_INT.writePrimitive(out, frameLength);
ByteBuf temp = in;
if (!in.hasArray()) {
temp = ByteBufAllocator.DEFAULT.heapBuffer().writeBytes(in);
} else {
in.retain();
}
ByteBuf output = ByteBufAllocator.DEFAULT.heapBuffer();
try {
this.deflater.setInput(temp.array(), temp.arrayOffset() + temp.readerIndex(), temp.readableBytes());
deflater.finish();
while (!deflater.finished()) {
output.ensureWritable(4096);
output.writerIndex(output.writerIndex() + this.deflater.deflate(output.array(), output.arrayOffset() + output.writerIndex(), output.writableBytes()));
}
out.writeBytes(output);
} finally {
output.release();
temp.release();
this.deflater.reset();
}
}
}
@@ -1,61 +0,0 @@
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider.compression;
import com.viaversion.viarewind.api.netty.EmptyChannelHandler;
import com.viaversion.viarewind.api.netty.ForwardMessageToByteEncoder;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider.CompressionHandlerProvider;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelPipeline;
public class TrackingCompressionHandlerProvider extends CompressionHandlerProvider {
public final static String COMPRESS_HANDLER_NAME = "compress";
public final static String DECOMPRESS_HANDLER_NAME = "decompress";
@Override
public void onHandleLoginCompressionPacket(UserConnection user, int threshold) {
final ChannelPipeline pipeline = user.getChannel().pipeline();
if (user.isClientSide()) {
pipeline.addBefore(Via.getManager().getInjector().getEncoderName(), COMPRESS_HANDLER_NAME, getEncoder(threshold));
pipeline.addBefore(Via.getManager().getInjector().getDecoderName(), DECOMPRESS_HANDLER_NAME, getDecoder(threshold));
} else {
setCompressionEnabled(user, true); // We need to remove compression for 1.7 clients
}
}
@Override
public void onTransformPacket(UserConnection user) {
if (isCompressionEnabled(user)) {
final ChannelPipeline pipeline = user.getChannel().pipeline();
String compressor = null;
String decompressor = null;
if (pipeline.get(COMPRESS_HANDLER_NAME) != null) { // ViaVersion
compressor = COMPRESS_HANDLER_NAME;
decompressor = DECOMPRESS_HANDLER_NAME;
} else if (pipeline.get("compression-encoder") != null) { // Velocity
compressor = "compression-encoder";
decompressor = "compression-decoder";
}
if (compressor != null) { // We can neutralize the effect of compressor to the client
pipeline.replace(decompressor, decompressor, new EmptyChannelHandler());
pipeline.replace(compressor, compressor, new ForwardMessageToByteEncoder());
} else {
throw new IllegalStateException("Couldn't remove compression for 1.7!");
}
setCompressionEnabled(user, false);
}
}
@Override
public ChannelHandler getEncoder(int threshold) {
return new CompressionEncoder(threshold);
}
@Override
public ChannelHandler getDecoder(int threshold) {
return new CompressionDecoder(threshold);
}
}
@@ -1,115 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.rewriter;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model.MetaIndex1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.metadata.MetaType1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_8;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
@SuppressWarnings({"deprecation"})
public class MetadataRewriter {
private final Protocol1_7_6_10To1_8 protocol;
public MetadataRewriter(Protocol1_7_6_10To1_8 protocol) {
this.protocol = protocol;
}
public void transform(EntityTypes1_10.EntityType type, List<Metadata> list) {
for (Metadata entry : new ArrayList<>(list)) {
final MetaIndex1_7_6_10To1_8 metaIndex = MetaIndex1_7_6_10To1_8.searchIndex(type, entry.id());
try {
if (metaIndex == null) {
ViaRewind.getPlatform().getLogger().warning("Could not find 1.8 metadata for " + type + " with index " + entry.id());
list.remove(entry);
continue;
}
if (metaIndex.getOldType() == MetaType1_7_6_10.NonExistent) {
list.remove(entry);
continue;
}
final Object value = entry.getValue();
entry.setTypeAndValue(metaIndex.getNewType(), value);
entry.setMetaTypeUnsafe(metaIndex.getOldType());
entry.setId(metaIndex.getIndex());
switch (metaIndex.getOldType()) {
case Int:
if (metaIndex.getNewType() == MetaType1_8.Byte) {
entry.setValue(((Byte) value).intValue());
if (metaIndex == MetaIndex1_7_6_10To1_8.ENTITY_AGEABLE_AGE) {
if ((Integer) entry.getValue() < 0) {
entry.setValue(-25000);
}
}
}
if (metaIndex.getNewType() == MetaType1_8.Short) {
entry.setValue(((Short) value).intValue());
}
if (metaIndex.getNewType() == MetaType1_8.Int) {
entry.setValue(value);
}
break;
case Byte:
if (metaIndex.getNewType() == MetaType1_8.Int) {
entry.setValue(((Integer) value).byteValue());
}
if (metaIndex.getNewType() == MetaType1_8.Byte) {
if (metaIndex == MetaIndex1_7_6_10To1_8.ITEM_FRAME_ROTATION) {
entry.setValue(Integer.valueOf((Byte) value % 4).byteValue());
} else {
entry.setValue(value);
}
}
if (metaIndex == MetaIndex1_7_6_10To1_8.HUMAN_SKIN_FLAGS) {
byte flags = (byte) value;
boolean cape = (flags & 0x01) != 0;
flags = (byte) (cape ? 0x00 : 0x02);
entry.setValue(flags);
}
break;
case Slot:
entry.setValue(protocol.getItemRewriter().handleItemToClient((Item) value));
break;
case Float:
case String:
case Short:
case Position:
break;
default:
ViaRewind.getPlatform().getLogger().warning("Could not transform metadata for " + type + " with index " + entry.id() + " and type " + metaIndex.getOldType());
list.remove(entry);
break;
}
} catch (Exception e) {
ViaRewind.getPlatform().getLogger().log(Level.WARNING, "Unable to transform metadata", e);
list.remove(entry);
}
}
}
}
@@ -1,230 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.rewriter;
import com.viaversion.viarewind.api.rewriter.item.ReplacementItemRewriter;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.api.rewriter.item.Replacement;
import com.viaversion.viarewind.utils.ChatUtil;
import com.viaversion.viarewind.utils.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.*;
import java.util.ArrayList;
import java.util.List;
public class ReplacementItemRewriter1_7_6_10 extends ReplacementItemRewriter<Protocol1_7_6_10To1_8> {
private final static String VIA_REWIND_TAG_KEY = "ViaRewind1_7_6_10to1_8";
public ReplacementItemRewriter1_7_6_10(Protocol1_7_6_10To1_8 protocol) {
super(protocol, ProtocolVersion.v1_8);
}
@Override
public void register() {
registerBlock(176, new Replacement(63));
registerBlock(177, new Replacement(68));
registerBlock(193, new Replacement(64));
registerBlock(194, new Replacement(64));
registerBlock(195, new Replacement(64));
registerBlock(196, new Replacement(64));
registerBlock(197, new Replacement(64));
registerBlock(77, 5, new Replacement(69, 6));
registerBlock(77, 13, new Replacement(69, 14));
registerBlock(77, 0, new Replacement(69, 0));
registerBlock(77, 8, new Replacement(69, 8));
registerBlock(143, 5, new Replacement(69, 6));
registerBlock(143, 13, new Replacement(69, 14));
registerBlock(143, 0, new Replacement(69, 0));
registerBlock(143, 8, new Replacement(69, 8));
registerBlock(178, new Replacement(151));
registerBlock(182, 0, new Replacement(44, 1));
registerBlock(182, 8, new Replacement(44, 9));
registerItem(425, new Replacement(323, "Banner"));
registerItem(409, new Replacement(406, "Prismarine Shard"));
registerItem(410, new Replacement(406, "Prismarine Crystal"));
registerItem(416, new Replacement(280, "Armor Stand"));
registerItem(423, new Replacement(363, "Raw Mutton"));
registerItem(424, new Replacement(364, "Cooked Mutton"));
registerItem(411, new Replacement(365, "Raw Rabbit"));
registerItem(412, new Replacement(366, "Cooked Rabbit"));
registerItem(413, new Replacement(282, "Rabbit Stew"));
registerItem(414, new Replacement(375, "Rabbit's Foot"));
registerItem(415, new Replacement(334, "Rabbit Hide"));
registerItem(373, 8203, new Replacement(373, 0, "Potion of Leaping"));
registerItem(373, 8235, new Replacement(373, 0, "Potion of Leaping"));
registerItem(373, 8267, new Replacement(373, 0, "Potion of Leaping"));
registerItem(373, 16395, new Replacement(373, 0, "Splash Potion of Leaping"));
registerItem(373, 16427, new Replacement(373, 0, "Splash Potion of Leaping"));
registerItem(373, 16459, new Replacement(373, 0, "Splash Potion of Leaping"));
registerItem(383, 30, new Replacement(383, "Spawn ArmorStand"));
registerItem(383, 67, new Replacement(383, "Spawn Endermite"));
registerItem(383, 68, new Replacement(383, "Spawn Guardian"));
registerItem(383, 101, new Replacement(383, "Spawn Rabbit"));
registerItem(19, 1, new Replacement(19, 0, "Wet Sponge"));
registerItem(182, new Replacement(44, 1, "Red Sandstone Slab"));
registerItemBlock(166, new Replacement(20, "Barrier"));
registerItemBlock(167, new Replacement(96, "Iron Trapdoor"));
registerItemBlock(1, 1, new Replacement(1, 0, "Granite"));
registerItemBlock(1, 2, new Replacement(1, 0, "Polished Granite"));
registerItemBlock(1, 3, new Replacement(1, 0, "Diorite"));
registerItemBlock(1, 4, new Replacement(1, 0, "Polished Diorite"));
registerItemBlock(1, 5, new Replacement(1, 0, "Andesite"));
registerItemBlock(1, 6, new Replacement(1, 0, "Polished Andesite"));
registerItemBlock(168, 0, new Replacement(1, 0, "Prismarine"));
registerItemBlock(168, 1, new Replacement(98, 0, "Prismarine Bricks"));
registerItemBlock(168, 2, new Replacement(98, 1, "Dark Prismarine"));
registerItemBlock(169, new Replacement(89, "Sea Lantern"));
registerItemBlock(165, new Replacement(95, 5, "Slime Block"));
registerItemBlock(179, 0, new Replacement(24, "Red Sandstone"));
registerItemBlock(179, 1, new Replacement(24, "Chiseled Red Sandstone"));
registerItemBlock(179, 2, new Replacement(24, "Smooth Sandstone"));
registerItemBlock(181, new Replacement(43, 1, "Double Red Sandstone Slab"));
registerItemBlock(180, new Replacement(128, "Red Sandstone Stairs"));
registerItemBlock(188, new Replacement(85, "Spruce Fence"));
registerItemBlock(189, new Replacement(85, "Birch Fence"));
registerItemBlock(190, new Replacement(85, "Jungle Fence"));
registerItemBlock(191, new Replacement(85, "Dark Oak Fence"));
registerItemBlock(192, new Replacement(85, "Acacia Fence"));
registerItemBlock(183, new Replacement(107, "Spruce Fence Gate"));
registerItemBlock(184, new Replacement(107, "Birch Fence Gate"));
registerItemBlock(185, new Replacement(107, "Jungle Fence Gate"));
registerItemBlock(186, new Replacement(107, "Dark Oak Fence Gate"));
registerItemBlock(187, new Replacement(107, "Acacia Fence Gate"));
registerItemBlock(427, new Replacement(324, "Spruce Door"));
registerItemBlock(428, new Replacement(324, "Birch Door"));
registerItemBlock(429, new Replacement(324, "Jungle Door"));
registerItemBlock(430, new Replacement(324, "Dark Oak Door"));
registerItemBlock(431, new Replacement(324, "Acacia Door"));
registerItemBlock(157, new Replacement(28, "Activator Rail"));
}
@Override
public Item handleItemToClient(Item item) {
if (item == null) return null;
CompoundTag tag = item.tag();
if (tag == null) {
item.setTag(tag = new CompoundTag());
}
CompoundTag viaRewindTag = new CompoundTag();
tag.put(VIA_REWIND_TAG_KEY, viaRewindTag);
viaRewindTag.put("id", new ShortTag((short) item.identifier()));
viaRewindTag.put("data", new ShortTag(item.data()));
CompoundTag display = tag.get("display");
if (display != null && display.contains("Name")) {
viaRewindTag.put("displayName", new StringTag((String) display.get("Name").getValue()));
}
if (display != null && display.contains("Lore")) {
viaRewindTag.put("lore", new ListTag(((ListTag) display.get("Lore")).getValue()));
}
if (tag.contains("ench") || tag.contains("StoredEnchantments")) {
ListTag enchTag = tag.contains("ench") ? tag.get("ench") : tag.get("StoredEnchantments");
List<Tag> lore = new ArrayList<>();
for (Tag ench : new ArrayList<>(enchTag.getValue())) {
short id = ((NumberTag) ((CompoundTag) ench).get("id")).asShort();
short lvl = ((NumberTag) ((CompoundTag) ench).get("lvl")).asShort();
String s;
if (id == 8) {
s = "§r§7Depth Strider ";
} else {
continue;
}
enchTag.remove(ench);
s += Enchantments.ENCHANTMENTS.getOrDefault(lvl, "enchantment.level." + lvl);
lore.add(new StringTag(s));
}
if (!lore.isEmpty()) {
if (display == null) {
tag.put("display", display = new CompoundTag());
viaRewindTag.put("noDisplay", new ByteTag());
}
ListTag loreTag = display.get("Lore");
if (loreTag == null) display.put("Lore", loreTag = new ListTag(StringTag.class));
lore.addAll(loreTag.getValue());
loreTag.setValue(lore);
}
}
if (item.identifier() == 387 && tag.contains("pages")) {
ListTag pages = tag.get("pages");
ListTag oldPages = new ListTag(StringTag.class);
viaRewindTag.put("pages", oldPages);
for (int i = 0; i < pages.size(); i++) {
StringTag page = pages.get(i);
String value = page.getValue();
oldPages.add(new StringTag(value));
value = ChatUtil.jsonToLegacy(value);
page.setValue(value);
}
}
replace(item);
if (viaRewindTag.size() == 2 && (short) viaRewindTag.get("id").getValue() == item.identifier() && (short) viaRewindTag.get("data").getValue() == item.data()) {
item.tag().remove(VIA_REWIND_TAG_KEY);
if (item.tag().isEmpty()) item.setTag(null);
}
return item;
}
@Override
public Item handleItemToServer(Item item) {
if (item == null) return null;
CompoundTag tag = item.tag();
if (tag == null || !item.tag().contains(VIA_REWIND_TAG_KEY)) return item;
CompoundTag viaVersionTag = tag.remove(VIA_REWIND_TAG_KEY);
item.setIdentifier((short) viaVersionTag.get("id").getValue());
item.setData((Short) viaVersionTag.get("data").getValue());
if (viaVersionTag.contains("noDisplay")) tag.remove("display");
if (viaVersionTag.contains("displayName")) {
CompoundTag display = tag.get("display");
if (display == null) tag.put("display", display = new CompoundTag());
StringTag name = display.get("Name");
if (name == null) display.put("Name", new StringTag((String) viaVersionTag.get("displayName").getValue()));
else name.setValue((String) viaVersionTag.get("displayName").getValue());
} else if (tag.contains("display")) {
((CompoundTag) tag.get("display")).remove("Name");
}
if (item.identifier() == 387) {
ListTag oldPages = viaVersionTag.get("pages");
tag.remove("pages");
tag.put("pages", oldPages);
}
return item;
}
}
@@ -1,174 +0,0 @@
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.api.rewriter.ReplacementEntityTracker;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.ServerboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model.VirtualHologramEntity;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.rewriter.MetadataRewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
public class EntityTracker1_7_6_10 extends ReplacementEntityTracker {
protected final MetadataRewriter metadataRewriter;
private final Map<Integer, Integer> vehicleMap = new ConcurrentHashMap<>();
private final Map<Integer, VirtualHologramEntity> virtualHologramMap = new HashMap<>();
private final Map<Integer, UUID> playersByEntityId = new HashMap<>();
private final Map<UUID, Integer> playersByUniqueId = new HashMap<>();
public int spectatingPlayerId = -1;
public EntityTracker1_7_6_10(UserConnection user, final MetadataRewriter metadataRewriter) {
super(user, ProtocolVersion.v1_8);
this.metadataRewriter = metadataRewriter;
registerEntity(EntityTypes1_10.EntityType.GUARDIAN, EntityTypes1_10.EntityType.SQUID, "Guardian");
registerEntity(EntityTypes1_10.EntityType.ENDERMITE, EntityTypes1_10.EntityType.SQUID, "Endermite");
registerEntity(EntityTypes1_10.EntityType.RABBIT, EntityTypes1_10.EntityType.CHICKEN, "Rabbit");
}
public void trackHologram(final int entityId, final VirtualHologramEntity hologram) {
addEntity(entityId, EntityTypes1_10.EntityType.ARMOR_STAND);
getEntityReplacementMap().put(entityId, EntityTypes1_10.EntityType.ARMOR_STAND);
virtualHologramMap.put(entityId, hologram);
}
@Override
public void updateMetadata(int entityId, List<Metadata> metadata) throws Exception {
if (virtualHologramMap.containsKey(entityId)) {
virtualHologramMap.get(entityId).updateMetadata(metadata);
return;
}
super.updateMetadata(entityId, metadata);
}
@Override
public void removeEntity(int entityId) {
super.removeEntity(entityId);
if (playersByEntityId.containsKey(entityId)) {
final UUID playerId = playersByEntityId.remove(entityId);
playersByUniqueId.remove(playerId);
getUser().get(PlayerSessionStorage.class).getPlayerEquipment().remove(playerId);
}
}
@Override
public void clear() {
super.clear();
vehicleMap.clear();
}
@Override
public void setClientEntityId(int entityId) {
if (this.spectatingPlayerId == this.getPlayerId()) {
this.spectatingPlayerId = entityId;
}
super.setClientEntityId(entityId);
}
public void addPlayer(final Integer entityId, final UUID uuid) {
playersByUniqueId.put(uuid, entityId);
playersByEntityId.put(entityId, uuid);
}
public UUID getPlayerUUID(final int entityId) {
return playersByEntityId.get(entityId);
}
public int getPlayerEntityId(final UUID uuid) {
return playersByUniqueId.getOrDefault(uuid, -1);
}
public int getVehicle(final int passengerId) {
for (Map.Entry<Integer, Integer> vehicle : vehicleMap.entrySet()) {
if (vehicle.getValue() == passengerId) {
return vehicle.getValue();
}
}
return -1;
}
public int getPassenger(int vehicleId) {
return vehicleMap.getOrDefault(vehicleId, -1);
}
protected void startSneaking() {
try {
final PacketWrapper entityAction = PacketWrapper.create(ServerboundPackets1_7_2_5.ENTITY_ACTION, getUser());
entityAction.write(Type.VAR_INT, this.getPlayerId()); // entity id
entityAction.write(Type.VAR_INT, 0); // action id, start sneaking
entityAction.write(Type.VAR_INT, 0); // jump boost
entityAction.sendToServer(Protocol1_7_6_10To1_8.class, true);
} catch (Exception e) {
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send sneak packet", e);
}
}
public void setPassenger(int vehicleId, int passengerId) {
if (vehicleId == this.spectatingPlayerId && this.spectatingPlayerId != this.getPlayerId()) {
startSneaking();
setSpectating(this.getPlayerId());
}
if (vehicleId == -1) {
vehicleMap.remove(getVehicle(passengerId));
} else if (passengerId == -1) {
vehicleMap.remove(vehicleId);
} else {
vehicleMap.put(vehicleId, passengerId);
}
}
protected void attachEntity(final int target) {
try {
final PacketWrapper attachEntity = PacketWrapper.create(ClientboundPackets1_8.ATTACH_ENTITY, getUser());
attachEntity.write(Type.INT, this.getPlayerId()); // vehicle id
attachEntity.write(Type.INT, target); // passenger id
attachEntity.write(Type.BOOLEAN, false); // leash
attachEntity.scheduleSend(Protocol1_7_6_10To1_8.class, true);
} catch (Exception e) {
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send attach packet", e);
}
}
public void setSpectating(int spectating) {
if (spectating != this.getPlayerId() && getPassenger(spectating) != -1) {
startSneaking();
setSpectating(this.getPlayerId());
return;
}
if (this.spectatingPlayerId != spectating && this.spectatingPlayerId != this.getPlayerId()) {
attachEntity(-1);
}
this.spectatingPlayerId = spectating;
if (spectating != this.getPlayerId()) {
attachEntity(this.spectatingPlayerId);
}
}
public Map<Integer, VirtualHologramEntity> getVirtualHologramMap() {
return virtualHologramMap;
}
}
@@ -1,146 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage;
import com.viaversion.viarewind.utils.ChatUtil;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.util.ChatColorUtil;
import java.util.*;
public class GameProfileStorage extends StoredObject {
private final Map<UUID, GameProfile> properties = new HashMap<>();
public GameProfileStorage(UserConnection user) {
super(user);
}
public GameProfile put(UUID uuid, String name) {
GameProfile gameProfile = new GameProfile(uuid, name);
properties.put(uuid, gameProfile);
return gameProfile;
}
public GameProfile get(UUID uuid) {
return properties.get(uuid);
}
public GameProfile get(String name, boolean ignoreCase) {
if (ignoreCase) name = name.toLowerCase();
for (GameProfile profile : properties.values()) {
if (profile.name == null) continue;
String n = ignoreCase ? profile.name.toLowerCase() : profile.name;
if (n.equals(name)) {
return profile;
}
}
return null;
}
public List<GameProfile> getAllWithPrefix(String prefix, boolean ignoreCase) {
if (ignoreCase) prefix = prefix.toLowerCase();
ArrayList<GameProfile> profiles = new ArrayList<>();
for (GameProfile profile : properties.values()) {
if (profile.name == null) continue;
String n = ignoreCase ? profile.name.toLowerCase() : profile.name;
if (n.startsWith(prefix)) profiles.add(profile);
}
return profiles;
}
public GameProfile remove(UUID uuid) {
return properties.remove(uuid);
}
public static class GameProfile {
public final String name;
public final UUID uuid;
public String displayName;
public int ping;
public List<Property> properties = new ArrayList<>();
public int gamemode = 0;
public GameProfile(UUID uuid, String name) {
this.name = name;
this.uuid = uuid;
}
public Item getSkull() {
CompoundTag tag = new CompoundTag();
CompoundTag ownerTag = new CompoundTag();
tag.put("SkullOwner", ownerTag);
ownerTag.put("Id", new StringTag(uuid.toString()));
CompoundTag properties = new CompoundTag();
ownerTag.put("Properties", properties);
ListTag textures = new ListTag(CompoundTag.class);
properties.put("textures", textures);
for (Property property : this.properties) {
if (property.name.equals("textures")) {
CompoundTag textureTag = new CompoundTag();
textureTag.put("Value", new StringTag(property.value));
if (property.signature != null) {
textureTag.put("Signature", new StringTag(property.signature));
}
textures.add(textureTag);
}
}
return new DataItem(397, (byte) 1, (short) 3, tag);
}
public String getDisplayName() {
String displayName = this.displayName == null ? name : this.displayName;
if (displayName.length() > 16) displayName = ChatUtil.removeUnusedColor(displayName, 'f');
if (displayName.length() > 16) displayName = ChatColorUtil.stripColor(displayName);
if (displayName.length() > 16) displayName = displayName.substring(0, 16);
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
}
public static class Property {
public final String name;
public final String value;
public final String signature;
public Property(String name, String value, String signature) {
this.name = name;
this.value = value;
this.signature = signature;
}
}
}
@@ -1,79 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.model.FurnaceData;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.Item;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class InventoryTracker extends StoredObject {
public final static Map<String, Integer> WINDOW_TYPE_REGISTRY = new HashMap<>();
static {
WINDOW_TYPE_REGISTRY.put("minecraft:container", 0);
WINDOW_TYPE_REGISTRY.put("minecraft:chest", 0);
WINDOW_TYPE_REGISTRY.put("minecraft:crafting_table", 1);
WINDOW_TYPE_REGISTRY.put("minecraft:furnace", 2);
WINDOW_TYPE_REGISTRY.put("minecraft:dispenser", 3);
WINDOW_TYPE_REGISTRY.put("minecraft:enchanting_table", 4);
WINDOW_TYPE_REGISTRY.put("minecraft:brewing_stand", 5);
WINDOW_TYPE_REGISTRY.put("minecraft:villager", 6);
WINDOW_TYPE_REGISTRY.put("minecraft:beacon", 7);
WINDOW_TYPE_REGISTRY.put("minecraft:anvil", 8);
WINDOW_TYPE_REGISTRY.put("minecraft:hopper", 9);
WINDOW_TYPE_REGISTRY.put("minecraft:dropper", 10);
WINDOW_TYPE_REGISTRY.put("EntityHorse", 11);
}
private final HashMap<Short, Short> windowTypeMap = new HashMap<>();
private final HashMap<Short, FurnaceData> furnaceData = new HashMap<>();
public short levelCost = 0;
public short anvilId = -1;
public InventoryTracker(UserConnection user) {
super(user);
}
public short get(short windowId) {
return windowTypeMap.getOrDefault(windowId, (short) -1);
}
public void remove(short windowId) {
windowTypeMap.remove(windowId);
furnaceData.remove(windowId);
}
public static short getInventoryType(String name) {
return WINDOW_TYPE_REGISTRY.getOrDefault(name, -1).shortValue();
}
public HashMap<Short, Short> getWindowTypeMap() {
return windowTypeMap;
}
public HashMap<Short, FurnaceData> getFurnaceData() {
return furnaceData;
}
}
@@ -1,87 +0,0 @@
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.Item;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class PlayerSessionStorage extends StoredObject {
// Player info
public int gameMode;
// Player abilities
public boolean sprinting, allowFly, flying, invincible, creative;
public float flySpeed, walkSpeed;
// Player position, rotation and data
private double posX, posY, posZ;
public double receivedPosY;
public float yaw, pitch;
public boolean onGround;
// Player inventory
private final Map<UUID, Item[]> playerEquipment = new HashMap<>();
public PlayerSessionStorage(UserConnection user) {
super(user);
}
public byte combineAbilities() {
byte flags = 0;
if (invincible) flags |= 8;
if (allowFly) flags |= 4;
if (flying) flags |= 2;
if (creative) flags |= 1;
return flags;
}
public double getPosX() {
return posX;
}
public double getPosY() {
return posY;
}
public double getPosZ() {
return posZ;
}
public void setPos(double x, double y, double z) {
posX = x;
posY = y;
posZ = z;
}
public Item getPlayerEquipment(final UUID uuid, final int slot) {
final Item[] items = playerEquipment.get(uuid);
if (items == null || slot < 0 || slot >= items.length) {
return null;
}
return items[slot];
}
public void setPlayerEquipment(final UUID uuid, final Item equipment, final int slot) {
final Item[] items = playerEquipment.computeIfAbsent(uuid, it -> new Item[5]);
if (slot < 0 || slot >= items.length) {
return;
}
items[slot] = equipment;
}
public boolean isSpectator() {
return gameMode == 3;
}
public Map<UUID, Item[]> getPlayerEquipment() {
return playerEquipment;
}
}
@@ -1,187 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.ClientboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import java.util.*;
public class Scoreboard extends StoredObject {
private final HashMap<String, List<String>> teams = new HashMap<>();
private final HashSet<String> objectives = new HashSet<>();
private final HashMap<String, ScoreTeam> scoreTeams = new HashMap<>();
private final HashMap<String, Byte> teamColors = new HashMap<>();
private final HashSet<String> scoreTeamNames = new HashSet<>();
private String colorIndependentSidebar;
private final HashMap<Byte, String> colorDependentSidebar = new HashMap<>();
public Scoreboard(UserConnection user) {
super(user);
}
public void addPlayerToTeam(String player, String team) {
teams.computeIfAbsent(team, key -> new ArrayList<>()).add(player);
}
public void setTeamColor(String team, Byte color) {
teamColors.put(team, color);
}
public Optional<Byte> getTeamColor(String team) {
return Optional.ofNullable(teamColors.get(team));
}
public void addTeam(String team) {
teams.computeIfAbsent(team, key -> new ArrayList<>());
}
public void removeTeam(String team) {
teams.remove(team);
scoreTeams.remove(team);
teamColors.remove(team);
}
public boolean teamExists(String team) {
return teams.containsKey(team);
}
public void removePlayerFromTeam(String player, String team) {
List<String> teamPlayers = teams.get(team);
if (teamPlayers != null) teamPlayers.remove(player);
}
public boolean isPlayerInTeam(String player, String team) {
List<String> teamPlayers = teams.get(team);
return teamPlayers != null && teamPlayers.contains(player);
}
public boolean isPlayerInTeam(String player) {
for (List<String> teamPlayers : teams.values()) {
if (teamPlayers.contains(player)) return true;
}
return false;
}
public Optional<Byte> getPlayerTeamColor(String player) {
Optional<String> team = getTeam(player);
return team.isPresent() ? getTeamColor(team.get()) : Optional.empty();
}
public Optional<String> getTeam(String player) {
for (Map.Entry<String, List<String>> entry : teams.entrySet())
if (entry.getValue().contains(player))
return Optional.of(entry.getKey());
return Optional.empty();
}
public void addObjective(String name) {
objectives.add(name);
}
public void removeObjective(String name) {
objectives.remove(name);
colorDependentSidebar.values().remove(name);
if (name.equals(colorIndependentSidebar)) {
colorIndependentSidebar = null;
}
}
public boolean objectiveExists(String name) {
return objectives.contains(name);
}
public String sendTeamForScore(String score) {
if (score.length() <= 16) return score;
if (scoreTeams.containsKey(score)) return scoreTeams.get(score).name;
int l = 16;
int i = Math.min(16, score.length() - 16);
String name = score.substring(i, i + l);
while (scoreTeamNames.contains(name) || teams.containsKey(name)) {
i--;
while (score.length() - l - i > 16) {
l--;
if (l < 1) return score;
i = Math.min(16, score.length() - l);
}
name = score.substring(i, i + l);
}
String prefix = score.substring(0, i);
String suffix = i + l >= score.length() ? "" : score.substring(i + l);
ScoreTeam scoreTeam = new ScoreTeam(name, prefix, suffix);
scoreTeams.put(score, scoreTeam);
scoreTeamNames.add(name);
PacketWrapper teamPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.TEAMS, getUser());
teamPacket.write(Type.STRING, name);
teamPacket.write(Type.BYTE, (byte) 0);
teamPacket.write(Type.STRING, "ViaRewind");
teamPacket.write(Type.STRING, prefix);
teamPacket.write(Type.STRING, suffix);
teamPacket.write(Type.BYTE, (byte) 0);
teamPacket.write(Type.SHORT, (short) 1);
teamPacket.write(Type.STRING, name);
PacketUtil.sendPacket(teamPacket, Protocol1_7_6_10To1_8.class, true, true);
return name;
}
public String removeTeamForScore(String score) {
ScoreTeam scoreTeam = scoreTeams.remove(score);
if (scoreTeam == null) return score;
scoreTeamNames.remove(scoreTeam.name);
PacketWrapper teamPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.TEAMS, getUser());
teamPacket.write(Type.STRING, scoreTeam.name);
teamPacket.write(Type.BYTE, (byte) 1);
PacketUtil.sendPacket(teamPacket, Protocol1_7_6_10To1_8.class, true, true);
return scoreTeam.name;
}
public String getColorIndependentSidebar() {
return this.colorIndependentSidebar;
}
public HashMap<Byte, String> getColorDependentSidebar() {
return this.colorDependentSidebar;
}
public void setColorIndependentSidebar(String colorIndependentSidebar) {
this.colorIndependentSidebar = colorIndependentSidebar;
}
private static class ScoreTeam {
private final String prefix;
private final String suffix;
private final String name;
public ScoreTeam(String name, String prefix, String suffix) {
this.prefix = prefix;
this.suffix = suffix;
this.name = name;
}
}
}
@@ -1,108 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
public class WorldBorderEmulator extends StoredObject {
private double x, z;
private double oldDiameter, newDiameter;
private long lerpTime;
private long lerpStartTime;
private boolean init = false;
public WorldBorderEmulator(UserConnection user) {
super(user);
}
public void init(double x, double z, double oldDiameter, double newDiameter, long lerpTime) {
this.x = x;
this.z = z;
this.oldDiameter = oldDiameter;
this.newDiameter = newDiameter;
this.lerpTime = lerpTime;
init = true;
}
public void setCenter(double x, double z) {
this.x = x;
this.z = z;
}
public void lerpSize(double oldDiameter, double newDiameter, long lerpTime) {
this.oldDiameter = oldDiameter;
this.newDiameter = newDiameter;
this.lerpTime = lerpTime;
this.lerpStartTime = System.currentTimeMillis();
}
public void setSize(double size) {
this.oldDiameter = size;
this.newDiameter = size;
this.lerpTime = 0;
}
public double getSize() {
if (lerpTime == 0) {
return newDiameter;
}
double percent = ((double) (System.currentTimeMillis() - lerpStartTime) / (double) (lerpTime));
// Clamp value
if (percent > 1.0D) percent = 1.0d;
else if (percent < 0.0D) percent = 0.0d;
return oldDiameter + (newDiameter - oldDiameter) * percent;
}
public double getX() {
return x;
}
public double getZ() {
return z;
}
public boolean isInit() {
return init;
}
public enum Side {
NORTH(0, -1),
EAST(1, 0),
SOUTH(0, 1),
WEST(-1, 0);
public final int modX;
public final int modZ;
Side(int modX, int modZ) {
this.modX = modX;
this.modZ = modZ;
}
}
}
@@ -1,78 +0,0 @@
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.task;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.PlayerSessionStorage;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.WorldBorderEmulator;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import java.util.logging.Level;
public class WorldBorderUpdateTask implements Runnable {
public final static int VIEW_DISTANCE = 16;
@Override
public void run() {
for (UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
final WorldBorderEmulator worldBorderEmulatorTracker = connection.get(WorldBorderEmulator.class);
if (!worldBorderEmulatorTracker.isInit()) continue;
final PlayerSessionStorage playerSession = connection.get(PlayerSessionStorage.class);
double radius = worldBorderEmulatorTracker.getSize() / 2.0;
for (WorldBorderEmulator.Side side : WorldBorderEmulator.Side.values()) {
double d;
double pos;
double center;
if (side.modX != 0) {
pos = playerSession.getPosZ();
center = worldBorderEmulatorTracker.getZ();
d = Math.abs(worldBorderEmulatorTracker.getX() + radius * side.modX - playerSession.getPosX());
} else {
center = worldBorderEmulatorTracker.getX();
pos = playerSession.getPosX();
d = Math.abs(worldBorderEmulatorTracker.getZ() + radius * side.modZ - playerSession.getPosZ());
}
if (d >= VIEW_DISTANCE) continue;
double r = Math.sqrt(VIEW_DISTANCE * VIEW_DISTANCE - d * d);
double minH = Math.ceil(pos - r);
double maxH = Math.floor(pos + r);
double minV = Math.ceil(playerSession.getPosY() - r);
double maxV = Math.floor(playerSession.getPosY() + r);
if (minH < center - radius) minH = Math.ceil(center - radius);
if (maxH > center + radius) maxH = Math.floor(center + radius);
if (minV < 0.0) minV = 0.0;
double centerH = (minH + maxH) / 2.0;
double centerV = (minV + maxV) / 2.0;
double particleOffset = 2.5;
final PacketWrapper spawnParticle = PacketWrapper.create(ClientboundPackets1_8.SPAWN_PARTICLE, connection);
spawnParticle.write(Type.STRING, ViaRewind.getConfig().getWorldBorderParticle()); // particle name
spawnParticle.write(Type.FLOAT, (float) (side.modX != 0 ? worldBorderEmulatorTracker.getX() + (radius * side.modX) : centerH)); // x
spawnParticle.write(Type.FLOAT, (float) centerV); // y
spawnParticle.write(Type.FLOAT, (float) (side.modX == 0 ? worldBorderEmulatorTracker.getZ() + (radius * side.modZ) : centerH)); // z
spawnParticle.write(Type.FLOAT, (float) (side.modX != 0 ? 0f : (maxH - minH) / particleOffset)); // offset x
spawnParticle.write(Type.FLOAT, (float) ((maxV - minV) / particleOffset)); // offset y
spawnParticle.write(Type.FLOAT, (float) (side.modX == 0 ? 0f : (maxH - minH) / particleOffset)); // offset z
spawnParticle.write(Type.FLOAT, 0F); // particle data
spawnParticle.write(Type.INT, (int) Math.floor((maxH - minH) * (maxV - minV) * 0.5));
try {
spawnParticle.send(Protocol1_7_6_10To1_8.class, true);
} catch (Exception e) {
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send world border particle", e);
}
}
}
}
}
@@ -1,60 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.item.CompressedNBTType;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.item.ItemArrayType;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.item.ItemType;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.item.NBTType;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.metadata.MetadataListType;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.metadata.MetadataType;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.primitive.ByteIntArrayType;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.primitive.PositionUYType;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import java.util.List;
public class Types1_7_6_10 {
// Primitives
public final static Type<int[]> BYTE_INT_ARRAY = new ByteIntArrayType(); // Integer array with byte as length indicator
// Positions /shrug
public final static Type<Position> SHORT_POSITION = new PositionUYType<>(Type.SHORT, value -> (short) value);
public final static Type<Position> INT_POSITION = new PositionUYType<>(Type.INT, value -> value);
public final static Type<Position> BYTE_POSITION = new PositionUYType<>(Type.BYTE, value -> (byte) value);
public final static Type<Position> U_BYTE_POSITION = new PositionUYType<>(Type.UNSIGNED_BYTE, value -> (short) value);
// Uncompressed Items
public final static Type<CompoundTag> NBT = new NBTType();
public final static Type<Item> ITEM = new ItemType(false);
// Compressed Items
public final static Type<CompoundTag> COMPRESSED_NBT = new CompressedNBTType();
public final static Type<Item> COMPRESSED_NBT_ITEM = new ItemType(true);
public final static Type<Item[]> COMPRESSED_NBT_ITEM_ARRAY = new ItemArrayType(true);
// Metadata
public final static Type<Metadata> METADATA = new MetadataType();
public final static Type<List<Metadata>> METADATA_LIST = new MetadataListType();
}
@@ -1,80 +0,0 @@
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.chunk;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.Pair;
import io.netty.buffer.ByteBuf;
import java.io.ByteArrayOutputStream;
import java.util.zip.Deflater;
public class BulkChunkType1_7_6 extends Type<Chunk[]> {
public final static BulkChunkType1_7_6 TYPE = new BulkChunkType1_7_6();
public BulkChunkType1_7_6() {
super(Chunk[].class);
}
@Override
public Chunk[] read(ByteBuf byteBuf) throws Exception {
throw new UnsupportedOperationException(); // Not needed, see https://github.com/ViaVersion/ViaLegacy/blob/main/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/types/ChunkBulk1_7_6Type.java
}
@Override
public void write(ByteBuf byteBuf, Chunk[] chunks) throws Exception {
final int chunkCount = chunks.length;
final ByteArrayOutputStream output = new ByteArrayOutputStream();
final int[] chunkX = new int[chunkCount];
final int[] chunkZ = new int[chunkCount];
final short[] primaryBitMask = new short[chunkCount];
final short[] additionalBitMask = new short[chunkCount];
for (int i = 0; i < chunkCount; i++) {
final Chunk chunk = chunks[i];
final Pair<byte[], Short> chunkData = ChunkType1_7_6.serialize(chunk);
output.write(chunkData.key());
chunkX[i] = chunk.getX();
chunkZ[i] = chunk.getZ();
primaryBitMask[i] = (short) chunk.getBitmask();
additionalBitMask[i] = chunkData.value();
}
final byte[] data = output.toByteArray();
final Deflater deflater = new Deflater();
byte[] compressedData;
int compressedSize;
try {
deflater.setInput(data, 0, data.length);
deflater.finish();
compressedData = new byte[data.length];
compressedSize = deflater.deflate(compressedData);
} finally {
deflater.end();
}
byteBuf.writeShort(chunkCount);
byteBuf.writeInt(compressedSize);
boolean skyLight = false;
for (Chunk chunk : chunks) {
for (ChunkSection section : chunk.getSections()) {
if (section != null && section.getLight().hasSkyLight()) {
skyLight = true;
break;
}
}
}
byteBuf.writeBoolean(skyLight); // hasSkyLight
byteBuf.writeBytes(compressedData, 0, compressedSize);
for (int i = 0; i < chunkCount; i++) {
byteBuf.writeInt(chunkX[i]);
byteBuf.writeInt(chunkZ[i]);
byteBuf.writeShort(primaryBitMask[i]);
byteBuf.writeShort(additionalBitMask[i]);
}
}
}
@@ -1,135 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.chunk;
import com.viaversion.viarewind.api.minecraft.ExtendedBlockStorage;
import com.viaversion.viaversion.api.minecraft.chunks.*;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.Pair;
import io.netty.buffer.ByteBuf;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
public class ChunkType1_7_6 extends Type<Chunk> {
public final static ChunkType1_7_6 TYPE = new ChunkType1_7_6();
public ChunkType1_7_6() {
super(Chunk.class);
}
@Override
public Chunk read(ByteBuf byteBuf) throws Exception {
throw new UnsupportedOperationException(); // Not needed, see https://github.com/ViaVersion/ViaLegacy/blob/main/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/types/Chunk1_7_6Type.java
}
@Override
public void write(ByteBuf output, Chunk chunk) throws Exception {
final Pair<byte[], Short> chunkData = serialize(chunk);
final byte[] data = chunkData.key();
final short additionalBitMask = chunkData.value();
final Deflater deflater = new Deflater();
byte[] compressedData;
int compressedSize;
try {
deflater.setInput(data, 0, data.length);
deflater.finish();
compressedData = new byte[data.length];
compressedSize = deflater.deflate(compressedData);
} finally {
deflater.end();
}
output.writeInt(chunk.getX());
output.writeInt(chunk.getZ());
output.writeBoolean(chunk.isFullChunk());
output.writeShort(chunk.getBitmask());
output.writeShort(additionalBitMask);
output.writeInt(compressedSize);
output.writeBytes(compressedData, 0, compressedSize);
}
public static Pair<byte[], Short> serialize(final Chunk chunk) throws IOException {
final ExtendedBlockStorage[] storageArrays = new ExtendedBlockStorage[16];
for (int i = 0; i < storageArrays.length; i++) {
final ChunkSection section = chunk.getSections()[i];
if (section != null) {
final ExtendedBlockStorage storage = storageArrays[i] = new ExtendedBlockStorage(section.getLight().hasSkyLight());
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = 0; y < 16; y++) {
final int flatBlock = section.palette(PaletteType.BLOCKS).idAt(x, y, z);
storage.setBlockId(x, y, z, flatBlock >> 4);
storage.setBlockMetadata(x, y, z, flatBlock & 15);
}
}
}
storage.getBlockLightArray().setHandle(section.getLight().getBlockLight());
if (section.getLight().hasSkyLight()) {
storage.getSkyLightArray().setHandle(section.getLight().getSkyLight());
}
}
}
final ByteArrayOutputStream output = new ByteArrayOutputStream();
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0) {
output.write(storageArrays[i].getBlockLSBArray());
}
}
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0) {
output.write(storageArrays[i].getBlockMetadataArray().getHandle());
}
}
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0) {
output.write(storageArrays[i].getBlockLightArray().getHandle());
}
}
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0 && storageArrays[i].getSkyLightArray() != null) {
output.write(storageArrays[i].getSkyLightArray().getHandle());
}
}
short additionalBitMask = 0;
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0 && storageArrays[i].hasBlockMSBArray()) {
additionalBitMask |= (short) (1 << i);
output.write(storageArrays[i].getOrCreateBlockMSBArray().getHandle());
}
}
if (chunk.isFullChunk() && chunk.getBiomeData() != null) {
for (int biome : chunk.getBiomeData()) {
output.write(biome);
}
}
return new Pair<>(output.toByteArray(), additionalBitMask);
}
}
@@ -1,70 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.opennbt.NBTIO;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class CompressedNBTType extends Type<CompoundTag> {
public CompressedNBTType() {
super(CompoundTag.class);
}
@Override
public CompoundTag read(ByteBuf buffer) throws IOException {
short length = buffer.readShort();
if (length <= 0) {
return null;
}
ByteBuf compressed = buffer.readSlice(length);
try (GZIPInputStream gzipStream = new GZIPInputStream(new ByteBufInputStream(compressed))) {
return NBTIO.readTag(gzipStream);
}
}
@Override
public void write(ByteBuf buffer, CompoundTag nbt) throws Exception {
if (nbt == null) {
buffer.writeShort(-1);
return;
}
ByteBuf compressedBuf = buffer.alloc().buffer();
try {
try (GZIPOutputStream gzipStream = new GZIPOutputStream(new ByteBufOutputStream(compressedBuf))) {
NBTIO.writeTag(gzipStream, nbt);
}
buffer.writeShort(compressedBuf.readableBytes());
buffer.writeBytes(compressedBuf);
} finally {
compressedBuf.release();
}
}
}
@@ -1,60 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.item;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class ItemType extends Type<Item> {
private final boolean compressed;
public ItemType(boolean compressed) {
super(Item.class);
this.compressed = compressed;
}
@Override
public Item read(ByteBuf buffer) throws Exception {
short id = buffer.readShort();
if (id < 0) {
return null;
}
Item item = new DataItem();
item.setIdentifier(id);
item.setAmount(buffer.readByte());
item.setData(buffer.readShort());
item.setTag((compressed ? Types1_7_6_10.COMPRESSED_NBT : Types1_7_6_10.NBT).read(buffer));
return item;
}
@Override
public void write(ByteBuf buffer, Item item) throws Exception {
if (item == null) {
buffer.writeShort(-1);
} else {
buffer.writeShort(item.identifier());
buffer.writeByte(item.amount());
buffer.writeShort(item.data());
(compressed ? Types1_7_6_10.COMPRESSED_NBT : Types1_7_6_10.NBT).write(buffer, item.tag());
}
}
}
@@ -1,72 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.opennbt.NBTIO;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import java.io.*;
public class NBTType extends Type<CompoundTag> {
public NBTType() {
super(CompoundTag.class);
}
@Override
public CompoundTag read(ByteBuf buffer) {
short length = buffer.readShort();
if (length < 0) {
return null;
}
ByteBufInputStream byteBufInputStream = new ByteBufInputStream(buffer);
DataInputStream dataInputStream = new DataInputStream(byteBufInputStream);
try {
return NBTIO.readTag((DataInput) dataInputStream);
} catch (Throwable throwable) {
throwable.printStackTrace();
} finally {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public void write(ByteBuf buffer, CompoundTag nbt) throws Exception {
if (nbt == null) {
buffer.writeShort(-1);
} else {
ByteBuf buf = buffer.alloc().buffer();
ByteBufOutputStream byteBufStream = new ByteBufOutputStream(buf);
DataOutputStream dataOutputStream = new DataOutputStream(byteBufStream);
NBTIO.writeTag((DataOutput) dataOutputStream, nbt);
dataOutputStream.close();
buffer.writeShort(buf.readableBytes());
buffer.writeBytes(buf);
buf.release();
}
}
}
@@ -1,57 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.metadata;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.VoidType;
public enum MetaType1_7_6_10 implements MetaType {
Byte(0, Type.BYTE),
Short(1, Type.SHORT),
Int(2, Type.INT),
Float(3, Type.FLOAT),
String(4, Type.STRING),
Slot(5, Types1_7_6_10.COMPRESSED_NBT_ITEM),
Position(6, Type.VECTOR),
NonExistent(-1, new VoidType());
private final int typeID;
private final Type<?> type;
MetaType1_7_6_10(int typeID, Type<?> type) {
this.typeID = typeID;
this.type = type;
}
public static MetaType1_7_6_10 byId(int id) {
return values()[id];
}
@Override
public int typeId() {
return this.typeID;
}
@Override
public Type<?> type() {
return this.type;
}
}
@@ -1,55 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.metadata;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.types.metadata.MetaListTypeTemplate;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
public class MetadataListType extends MetaListTypeTemplate {
@Override
public List<Metadata> read(ByteBuf buffer) throws Exception {
ArrayList<Metadata> list = new ArrayList<>();
Metadata m;
do {
m = Types1_7_6_10.METADATA.read(buffer);
if (m != null) {
list.add(m);
}
} while (m != null);
return list;
}
@Override
public void write(ByteBuf buffer, List<Metadata> metadata) throws Exception {
for (Metadata meta : metadata) {
Types1_7_6_10.METADATA.write(buffer, meta);
}
if (metadata.isEmpty()) {
Types1_7_6_10.METADATA.write(buffer, new Metadata(0, MetaType1_7_6_10.Byte, (byte) 0));
}
buffer.writeByte(127);
}
}
@@ -1,45 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.metadata;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.types.metadata.MetaTypeTemplate;
import io.netty.buffer.ByteBuf;
public class MetadataType extends MetaTypeTemplate {
@Override
public Metadata read(ByteBuf buffer) throws Exception {
byte item = buffer.readByte();
if (item == 127) {
return null;
} else {
int typeID = (item & 224) >> 5;
MetaType1_7_6_10 type = MetaType1_7_6_10.byId(typeID);
int id = item & 31;
return new Metadata(id, type, type.type().read(buffer));
}
}
@Override
public void write(ByteBuf buffer, Metadata meta) throws Exception {
int item = (meta.metaType().typeId() << 5 | meta.id() & 31) & 255;
buffer.writeByte(item);
meta.metaType().type().write(buffer, meta.getValue());
}
}
@@ -1,36 +0,0 @@
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.primitive;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import java.util.function.IntFunction;
public class PositionUYType<T extends Number> extends Type<Position> {
private final Type<T> yType;
private final IntFunction<T> toY;
public PositionUYType(final Type<T> yType, final IntFunction<T> toY) {
super(Position.class);
this.yType = yType;
this.toY = toY;
}
@Override
public Position read(ByteBuf buffer) throws Exception {
final int x = buffer.readInt();
final int y = yType.read(buffer).intValue();
final int z = buffer.readInt();
return new Position(x, y, z);
}
@Override
public void write(ByteBuf buffer, Position value) throws Exception {
buffer.writeInt(value.x());
yType.write(buffer, this.toY.apply(value.y()));
buffer.writeInt(value.z());
}
}
@@ -1,111 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_8to1_9;
import com.viaversion.viarewind.api.rewriter.item.ReplacementItemRewriter;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.metadata.MetadataRewriter;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.rewriter.ReplacementItemRewriter1_8;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.packets.*;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.*;
import com.viaversion.viarewind.utils.Ticker;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
import java.util.HashSet;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
public class Protocol1_8To1_9 extends AbstractProtocol<ClientboundPackets1_9, ClientboundPackets1_8, ServerboundPackets1_9, ServerboundPackets1_8> {
private final ReplacementItemRewriter<Protocol1_8To1_9> itemRewriter = new ReplacementItemRewriter1_8(this);
private final MetadataRewriter metadataRewriter = new MetadataRewriter(this);
public Queue<PacketWrapper> animationsToSend = new ConcurrentLinkedQueue<>();
public final static Set<String> VALID_ATTRIBUTES = new HashSet<>();
public final static ValueTransformer<Double, Integer> TO_OLD_INT = new ValueTransformer<Double, Integer>(Type.INT) {
@Override
public Integer transform(PacketWrapper wrapper, Double inputValue) {
return (int) (inputValue * 32.0D);
}
};
public final static ValueTransformer<Float, Byte> DEGREES_TO_ANGLE = new ValueTransformer<Float, Byte>(Type.BYTE) {
@Override
public Byte transform(PacketWrapper packetWrapper, Float degrees) throws Exception {
return (byte) ((degrees / 360F) * 256);
}
};
static {
VALID_ATTRIBUTES.add("generic.maxHealth");
VALID_ATTRIBUTES.add("generic.followRange");
VALID_ATTRIBUTES.add("generic.knockbackResistance");
VALID_ATTRIBUTES.add("generic.movementSpeed");
VALID_ATTRIBUTES.add("generic.attackDamage");
VALID_ATTRIBUTES.add("horse.jumpStrength");
VALID_ATTRIBUTES.add("zombie.spawnReinforcements");
}
public Protocol1_8To1_9() {
super(ClientboundPackets1_9.class, ClientboundPackets1_8.class, ServerboundPackets1_9.class, ServerboundPackets1_8.class);
}
@Override
protected void registerPackets() {
itemRewriter.register();
EntityPackets.register(this);
InventoryPackets.register(this);
PlayerPackets.register(this);
ScoreboardPackets.register(this);
SpawnPackets.register(this);
WorldPackets.register(this);
}
@Override
public void init(UserConnection userConnection) {
Ticker.init();
userConnection.put(new Windows(userConnection));
userConnection.put(new EntityTracker(userConnection, this));
userConnection.put(new Levitation(userConnection));
userConnection.put(new PlayerPosition(userConnection));
userConnection.put(new Cooldown(userConnection));
userConnection.put(new BlockPlaceDestroyTracker(userConnection));
userConnection.put(new BossBarStorage(userConnection));
userConnection.put(new ClientWorld(userConnection));
}
@Override
public ReplacementItemRewriter<Protocol1_8To1_9> getItemRewriter() {
return itemRewriter;
}
public MetadataRewriter getMetadataRewriter() {
return metadataRewriter;
}
}
Loaded 100 of 216 files, more files were not shown because too many files have changed in this diff. Show more