Compare commits

...

420 Commits

Author SHA1 Message Date
TheBrokenRail cf6989bed2 I need to sleep, here be dragons
CI / Build (AMD64, Server) (push) Failing after 6m39s Details
CI / Build (AMD64, Client) (push) Successful in 10m47s Details
CI / Build (ARM64, Client) (push) Successful in 10m26s Details
CI / Build (ARM64, Server) (push) Failing after 6m43s Details
CI / Build (ARMHF, Server) (push) Failing after 6m13s Details
CI / Build (ARMHF, Client) (push) Successful in 11m13s Details
CI / Release (push) Has been skipped Details
CI / Test (Client) (push) Failing after 5m45s Details
CI / Test (Server) (push) Failing after 5m1s Details
CI / Build Example Mods (push) Failing after 8m54s Details
2024-04-03 03:19:12 -04:00
TheBrokenRail b2a7fe3eaf C++-Ification! 2024-04-02 19:22:01 -04:00
TheBrokenRail 7739fb6b9b Update Dependency
CI / Build (AMD64, Server) (push) Successful in 12m36s Details
CI / Build (AMD64, Client) (push) Successful in 12m54s Details
CI / Build (ARM64, Server) (push) Successful in 12m14s Details
CI / Build (ARM64, Client) (push) Successful in 13m19s Details
CI / Build (ARMHF, Server) (push) Successful in 8m54s Details
CI / Build (ARMHF, Client) (push) Successful in 11m59s Details
CI / Test (Server) (push) Successful in 12m52s Details
CI / Test (Client) (push) Successful in 15m10s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m32s Details
2024-04-02 15:21:35 -04:00
TheBrokenRail f3755387e8 Improve Mouse Sensitivity On Wayland
CI / Build (AMD64, Server) (push) Successful in 12m9s Details
CI / Build (AMD64, Client) (push) Successful in 12m20s Details
CI / Build (ARM64, Server) (push) Successful in 12m35s Details
CI / Build (ARM64, Client) (push) Successful in 13m4s Details
CI / Build (ARMHF, Server) (push) Successful in 8m47s Details
CI / Build (ARMHF, Client) (push) Successful in 12m6s Details
CI / Test (Client) (push) Successful in 14m25s Details
CI / Test (Server) (push) Successful in 12m22s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m31s Details
2024-03-19 00:25:50 -04:00
TheBrokenRail b1b28defd5 Small Change 2024-03-19 00:12:26 -04:00
TheBrokenRail 18c5d34974 Ignore CLion Files 2024-03-19 00:12:26 -04:00
Bigjango13 76a66a0ba5 Sneak in Level_setTileEntity
CI / Build (AMD64, Server) (push) Successful in 12m25s Details
CI / Build (AMD64, Client) (push) Successful in 12m41s Details
CI / Build (ARM64, Server) (push) Successful in 12m25s Details
CI / Build (ARM64, Client) (push) Successful in 12m56s Details
CI / Build (ARMHF, Server) (push) Successful in 8m51s Details
CI / Build (ARMHF, Client) (push) Successful in 11m57s Details
CI / Test (Client) (push) Successful in 14m36s Details
CI / Test (Server) (push) Successful in 12m32s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Failing after 7m21s Details
2024-03-18 21:02:01 -04:00
Bigjango13 a6ad1994de Remove left over check 2024-03-18 19:58:38 -04:00
Bigjango13 8de638eb1a Make chat history edits saved temporarily 2024-03-18 19:44:17 -04:00
Bigjango13 5e5088e3ef Move chat history into chat
- `get_death_message` is no longer static
- Fix ItemInHandRenderer_instance symbol
2024-03-10 22:46:34 -04:00
Bigjango13 a6e0cd8f13 Fix history editing bug
- Use the `get_<var>` pattern for chat's `history`.
- Make the Biome_map comment clearer
2024-03-09 13:01:52 -05:00
Bigjango13 3ff24c2a92 Add chat history
- More symbols too
- Made CUSTOM_VTABLE not static, for modders
2024-03-08 18:03:19 -05:00
TheBrokenRail d74d1501ce Update Sound Warning
CI / Build (AMD64, Server) (push) Successful in 12m33s Details
CI / Build (AMD64, Client) (push) Successful in 12m47s Details
CI / Build (ARM64, Server) (push) Successful in 12m35s Details
CI / Build (ARM64, Client) (push) Successful in 13m5s Details
CI / Build (ARMHF, Server) (push) Successful in 8m52s Details
CI / Build (ARMHF, Client) (push) Successful in 12m2s Details
CI / Test (Client) (push) Successful in 15m14s Details
CI / Test (Server) (push) Successful in 12m27s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m27s Details
2024-03-02 17:16:16 -05:00
TheBrokenRail fb84bcc06b GLFW 3.4!
CI / Build (AMD64, Server) (push) Successful in 12m58s Details
CI / Build (AMD64, Client) (push) Successful in 13m20s Details
CI / Build (ARM64, Server) (push) Successful in 15m3s Details
CI / Build (ARM64, Client) (push) Successful in 15m32s Details
CI / Build (ARMHF, Server) (push) Successful in 8m59s Details
CI / Build (ARMHF, Client) (push) Successful in 12m16s Details
CI / Test (Client) (push) Successful in 15m10s Details
CI / Test (Server) (push) Successful in 13m15s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m49s Details
2024-02-23 20:54:07 -05:00
TheBrokenRail 117c5d2702 Better HiDPI Support
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
CI / Build (AMD64, Client) (push) Has been cancelled Details
2024-02-23 20:50:56 -05:00
TheBrokenRail 9556d13791 Minor Tweaks
CI / Build (AMD64, Server) (push) Successful in 12m42s Details
CI / Build (AMD64, Client) (push) Successful in 12m59s Details
CI / Build (ARM64, Server) (push) Successful in 12m49s Details
CI / Build (ARM64, Client) (push) Successful in 13m21s Details
CI / Build (ARMHF, Server) (push) Successful in 9m2s Details
CI / Build (ARMHF, Client) (push) Successful in 12m23s Details
CI / Test (Client) (push) Successful in 15m37s Details
CI / Test (Server) (push) Successful in 13m6s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m43s Details
2024-02-15 23:02:44 -05:00
Bigjango13 f8bd6d380b Fix invalid ItemInHandRenderer texture cache 2024-02-15 01:59:35 -05:00
Bigjango13 5d57253d56 More symbols and better patch error message 2024-02-15 01:59:34 -05:00
Bigjango13 6ac808919f More symbols! Mostly tile entity stuff 2024-02-15 01:58:38 -05:00
Bigjango13 5353bc188d Rename Entity::aabb to Entity::hitbox 2024-02-15 01:58:38 -05:00
Bigjango13 f57c0a6190 More symbols and clean up "Disable Hostile AI In Creative Mode" 2024-02-15 01:58:38 -05:00
TheBrokenRail b033912633 Also Scan .data.rel.ro
CI / Build (AMD64, Server) (push) Successful in 12m2s Details
CI / Build (AMD64, Client) (push) Successful in 12m22s Details
CI / Build (ARM64, Server) (push) Successful in 13m4s Details
CI / Build (ARM64, Client) (push) Successful in 13m36s Details
CI / Build (ARMHF, Server) (push) Successful in 8m37s Details
CI / Build (ARMHF, Client) (push) Successful in 11m27s Details
CI / Test (Server) (push) Successful in 12m26s Details
CI / Test (Client) (push) Successful in 15m7s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m22s Details
2024-02-12 00:55:50 -05:00
TheBrokenRail a2b3bb128b Bug Fixes & Low-Level Improvements
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
CI / Build (AMD64, Client) (push) Has been cancelled Details
2024-02-12 00:44:38 -05:00
TheBrokenRail 180ba9dcaf Small Changes 2024-02-11 20:35:41 -05:00
TheBrokenRail 71cc24104c Add More Splashes
CI / Build (AMD64, Server) (push) Successful in 11m14s Details
CI / Build (AMD64, Client) (push) Successful in 11m30s Details
CI / Build (ARM64, Server) (push) Successful in 11m31s Details
CI / Build (ARM64, Client) (push) Successful in 11m51s Details
CI / Build (ARMHF, Server) (push) Successful in 7m54s Details
CI / Build (ARMHF, Client) (push) Successful in 11m11s Details
CI / Test (Client) (push) Successful in 14m25s Details
CI / Test (Server) (push) Successful in 11m49s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m54s Details
2024-02-08 00:59:57 -05:00
TheBrokenRail 6951ebe620 Improve Performance
CI / Build (AMD64, Server) (push) Successful in 11m15s Details
CI / Build (AMD64, Client) (push) Successful in 11m33s Details
CI / Build (ARM64, Client) (push) Successful in 11m49s Details
CI / Build (ARM64, Server) (push) Successful in 11m35s Details
CI / Build (ARMHF, Server) (push) Successful in 7m50s Details
CI / Build (ARMHF, Client) (push) Successful in 11m3s Details
CI / Test (Client) (push) Successful in 14m43s Details
CI / Test (Server) (push) Successful in 11m40s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m48s Details
2024-02-08 00:34:43 -05:00
TheBrokenRail 28dbb2eacd Some CMake Cleanup
CI / Build (AMD64, Server) (push) Successful in 12m44s Details
CI / Build (AMD64, Client) (push) Successful in 12m56s Details
CI / Build (ARM64, Server) (push) Successful in 11m40s Details
CI / Build (ARM64, Client) (push) Successful in 12m1s Details
CI / Build (ARMHF, Server) (push) Successful in 8m1s Details
CI / Build (ARMHF, Client) (push) Successful in 10m59s Details
CI / Test (Client) (push) Successful in 14m15s Details
CI / Test (Server) (push) Successful in 11m53s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m49s Details
2024-02-07 22:12:02 -05:00
TheBrokenRail d86018717e Split Splash Loading Into Own Function 2024-02-07 21:40:26 -05:00
TheBrokenRail db22caa50f Add Splash Text From MCPIL
CI / Build (AMD64, Server) (push) Successful in 11m15s Details
CI / Build (AMD64, Client) (push) Successful in 11m28s Details
CI / Build (ARM64, Client) (push) Successful in 11m48s Details
CI / Build (ARM64, Server) (push) Successful in 11m47s Details
CI / Build (ARMHF, Server) (push) Successful in 7m55s Details
CI / Build (ARMHF, Client) (push) Successful in 11m14s Details
CI / Test (Client) (push) Successful in 14m39s Details
CI / Test (Server) (push) Successful in 11m42s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m49s Details
2024-02-07 21:15:48 -05:00
TheBrokenRail ecbcfb2922 Split Up Animated Textures Into Three Flags
CI / Build (AMD64, Server) (push) Successful in 11m25s Details
CI / Build (AMD64, Client) (push) Successful in 11m46s Details
CI / Build (ARM64, Client) (push) Successful in 11m50s Details
CI / Build (ARM64, Server) (push) Successful in 11m40s Details
CI / Build (ARMHF, Server) (push) Successful in 7m56s Details
CI / Build (ARMHF, Client) (push) Successful in 11m14s Details
CI / Test (Client) (push) Successful in 14m25s Details
CI / Test (Server) (push) Successful in 11m29s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m51s Details
2024-02-07 19:00:55 -05:00
TheBrokenRail 781377005e Update Dependencies
CI / Build (AMD64, Server) (push) Successful in 11m17s Details
CI / Build (AMD64, Client) (push) Successful in 11m30s Details
CI / Build (ARM64, Server) (push) Successful in 11m36s Details
CI / Build (ARM64, Client) (push) Successful in 12m0s Details
CI / Build (ARMHF, Server) (push) Successful in 7m57s Details
CI / Build (ARMHF, Client) (push) Successful in 11m18s Details
CI / Test (Client) (push) Successful in 14m21s Details
CI / Test (Server) (push) Successful in 11m49s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Has been cancelled Details
2024-02-07 18:04:53 -05:00
TheBrokenRail 6e306e500d I Have Made This Typo Countless Times
CI / Build (AMD64, Server) (push) Successful in 10m4s Details
CI / Build (AMD64, Client) (push) Successful in 10m14s Details
CI / Build (ARM64, Server) (push) Successful in 10m12s Details
CI / Build (ARM64, Client) (push) Successful in 10m22s Details
CI / Build (ARMHF, Server) (push) Successful in 7m0s Details
CI / Build (ARMHF, Client) (push) Successful in 9m26s Details
CI / Test (Client) (push) Successful in 13m20s Details
CI / Test (Server) (push) Successful in 10m55s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m6s Details
2024-02-07 02:01:43 -05:00
TheBrokenRail 7e300a6e1b Update Changelog
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Client) (push) Has been cancelled Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
2024-02-07 01:58:21 -05:00
bigjango13 f5a680af7b Add Cake (#81)
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Server) (push) Successful in 10m3s Details
CI / Build (AMD64, Client) (push) Successful in 10m16s Details
CI / Build (ARM64, Client) (push) Has been cancelled Details
CI / Build (ARM64, Server) (push) Has been cancelled Details
Adds cake, crafting remainders, milk buckets, death messages, `misc_run_on_language_setup`, and a lot more symbols.

Co-authored-by: Bigjango13 <bigjango13@gmail.com>
Reviewed-on: minecraft-pi-reborn/minecraft-pi-reborn#81
Co-authored-by: bigjango13 <bigjango13@noreply.thebrokenrail.org>
Co-committed-by: bigjango13 <bigjango13@noreply.thebrokenrail.org>
2024-02-07 06:47:46 +00:00
Bigjango13 c62d5264a8 More consistent lookup for sounds
CI / Build (AMD64, Client) (push) Has started running Details
CI / Build (ARM64, Client) (push) Has been cancelled Details
CI / Build (ARM64, Server) (push) Has been cancelled Details
CI / Build (ARMHF, Client) (push) Has been cancelled Details
CI / Build (ARMHF, Server) (push) Has been cancelled Details
CI / Test (Client) (push) Has been cancelled Details
CI / Test (Server) (push) Has been cancelled Details
CI / Build Example Mods (push) Has been cancelled Details
CI / Release (push) Has been cancelled Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
2024-02-07 02:16:34 +00:00
Bigjango13 93498ce9c0 Fix load_symbol ignoring source when a previous source has already been loaded 2024-02-07 02:16:34 +00:00
TheBrokenRail 90a2b0ac85 Call Ninja Directly
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
CI / Build (AMD64, Client) (push) Has been cancelled Details
2024-02-06 19:35:44 -05:00
Bigjango13 2d9d4a638a Move food overlay to after classic HUD
CI / Build (AMD64, Server) (push) Successful in 10m14s Details
CI / Build (AMD64, Client) (push) Successful in 10m26s Details
CI / Build (ARM64, Server) (push) Successful in 10m28s Details
CI / Build (ARM64, Client) (push) Successful in 10m38s Details
CI / Build (ARMHF, Server) (push) Successful in 7m6s Details
CI / Build (ARMHF, Client) (push) Successful in 9m47s Details
CI / Test (Client) (push) Successful in 13m41s Details
CI / Test (Server) (push) Successful in 11m12s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m15s Details
2024-02-06 18:16:21 -05:00
Bigjango13 8c265a69d9 Add Food Overlay 2024-02-06 17:53:21 -05:00
TheBrokenRail b5e9486460 Fix Script Bug
CI / Build (AMD64, Client) (push) Successful in 5m45s Details
CI / Build (AMD64, Server) (push) Successful in 5m22s Details
CI / Build (ARM64, Client) (push) Successful in 5m39s Details
CI / Build (ARM64, Server) (push) Successful in 5m24s Details
CI / Build (ARMHF, Client) (push) Successful in 5m48s Details
CI / Build (ARMHF, Server) (push) Successful in 4m0s Details
CI / Test (Client) (push) Successful in 9m6s Details
CI / Test (Server) (push) Successful in 5m53s Details
CI / Build Example Mods (push) Successful in 5m58s Details
CI / Release (push) Has been skipped Details
2024-02-04 03:40:59 -05:00
TheBrokenRail 7fc5638143 Fix CI (Again)
CI / Build (AMD64, Server) (push) Successful in 9m45s Details
CI / Build (AMD64, Client) (push) Successful in 9m55s Details
CI / Build (ARM64, Server) (push) Successful in 9m57s Details
CI / Build (ARM64, Client) (push) Successful in 10m10s Details
CI / Build (ARMHF, Server) (push) Successful in 7m14s Details
CI / Build (ARMHF, Client) (push) Successful in 9m33s Details
CI / Test (Server) (push) Successful in 10m23s Details
CI / Test (Client) (push) Successful in 13m14s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m0s Details
2024-02-04 02:33:35 -05:00
TheBrokenRail 7ba9daa84e Fix CI
CI / Build (AMD64, Server) (push) Successful in 9m47s Details
CI / Build (AMD64, Client) (push) Successful in 9m58s Details
CI / Build (ARM64, Server) (push) Successful in 9m50s Details
CI / Build (ARM64, Client) (push) Successful in 10m11s Details
CI / Build (ARMHF, Server) (push) Successful in 7m1s Details
CI / Build (ARMHF, Client) (push) Successful in 9m6s Details
CI / Test (Server) (push) Successful in 10m45s Details
CI / Test (Client) (push) Successful in 13m11s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Failing after 5m56s Details
2024-02-04 01:31:41 -05:00
TheBrokenRail 930d0120f3 More CI Improvements
CI / Build (AMD64, Server) (push) Successful in 9m46s Details
CI / Build (AMD64, Client) (push) Successful in 9m57s Details
CI / Build (ARM64, Client) (push) Successful in 10m0s Details
CI / Build (ARM64, Server) (push) Successful in 10m3s Details
CI / Build (ARMHF, Server) (push) Successful in 6m53s Details
CI / Build (ARMHF, Client) (push) Successful in 9m8s Details
CI / Test (Server) (push) Successful in 10m50s Details
CI / Test (Client) (push) Successful in 13m14s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Failing after 5m55s Details
2024-02-04 00:43:25 -05:00
TheBrokenRail 31fcff13e9 CI Improvements 2024-02-04 00:36:58 -05:00
TheBrokenRail 41fcc942fa JS-Based Build Script
Build / Build (AMD64, Server) (push) Successful in 10m4s Details
Build / Build (AMD64, Client) (push) Successful in 10m19s Details
Build / Build (ARM64, Client) (push) Successful in 10m11s Details
Build / Build (ARM64, Server) (push) Successful in 10m0s Details
Build / Build (ARMHF, Server) (push) Successful in 6m57s Details
Build / Build (ARMHF, Client) (push) Successful in 9m20s Details
Build / Test (Server) (push) Successful in 10m42s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 13m41s Details
2024-02-03 21:07:53 -05:00
TheBrokenRail ddd9226e9e Fix Button Hover 2024-02-02 22:28:57 -05:00
TheBrokenRail a336cd1c7b Improve Key Handling 2024-02-02 22:25:22 -05:00
TheBrokenRail eaf6dd2fe2 Add Peaceful Mode To Options Screen 2024-02-02 14:49:47 -05:00
TheBrokenRail 99b43ddb5a Create World Screen + Scrolling Text Boxes!
Build / Build (AMD64, Server) (push) Successful in 9m42s Details
Build / Build (AMD64, Client) (push) Successful in 9m52s Details
Build / Build (ARM64, Server) (push) Successful in 9m55s Details
Build / Build (ARM64, Client) (push) Successful in 10m20s Details
Build / Build (ARMHF, Server) (push) Successful in 6m59s Details
Build / Build (ARMHF, Client) (push) Successful in 9m9s Details
Build / Test (Client) (push) Failing after 10m13s Details
Build / Release (push) Has been skipped Details
Build / Test (Server) (push) Successful in 10m4s Details
2024-02-02 04:20:34 -05:00
TheBrokenRail 4f32cfab45 Send Button In Chat
Build / Build (AMD64, Server) (push) Successful in 9m38s Details
Build / Build (AMD64, Client) (push) Successful in 10m0s Details
Build / Build (ARM64, Server) (push) Successful in 7m58s Details
Build / Build (ARM64, Client) (push) Successful in 10m35s Details
Build / Build (ARMHF, Client) (push) Successful in 8m50s Details
Build / Build (ARMHF, Server) (push) Successful in 6m45s Details
Build / Test (Server) (push) Successful in 10m54s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m7s Details
2024-02-01 14:56:16 -05:00
TheBrokenRail 69211eb31d Improve Markdown Formatting 2024-02-01 03:18:47 -05:00
TheBrokenRail 58713976d4 In-Game Chat
Build / Build (AMD64, Server) (push) Successful in 9m49s Details
Build / Build (AMD64, Client) (push) Successful in 10m10s Details
Build / Build (ARM64, Client) (push) Successful in 9m53s Details
Build / Build (ARM64, Server) (push) Successful in 10m0s Details
Build / Build (ARMHF, Server) (push) Successful in 7m7s Details
Build / Build (ARMHF, Client) (push) Successful in 9m14s Details
Build / Test (Server) (push) Successful in 11m12s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m21s Details
2024-02-01 03:12:24 -05:00
TheBrokenRail d175f692e0 Put Sending Full Level Behind Flag 2024-01-31 23:52:29 -05:00
TheBrokenRail 6d4ff44092 Java Light Ramp (Also From ReMCPE)
Build / Build (AMD64, Server) (push) Successful in 9m51s Details
Build / Build (AMD64, Client) (push) Successful in 10m2s Details
Build / Build (ARM64, Server) (push) Successful in 10m4s Details
Build / Build (ARM64, Client) (push) Successful in 10m21s Details
Build / Build (ARMHF, Server) (push) Successful in 7m11s Details
Build / Build (ARMHF, Client) (push) Successful in 9m23s Details
Build / Test (Server) (push) Successful in 10m53s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m33s Details
2024-01-31 23:44:04 -05:00
TheBrokenRail 1771919cc1 Port Fire/Lava Textures From ReMCPE
Build / Build (AMD64, Server) (push) Successful in 9m44s Details
Build / Build (AMD64, Client) (push) Successful in 9m59s Details
Build / Build (ARM64, Server) (push) Successful in 9m58s Details
Build / Build (ARM64, Client) (push) Successful in 10m28s Details
Build / Build (ARMHF, Server) (push) Successful in 6m56s Details
Build / Build (ARMHF, Client) (push) Successful in 9m28s Details
Build / Test (Server) (push) Successful in 11m28s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m51s Details
2024-01-31 22:13:20 -05:00
TheBrokenRail 522cee2d3b Fix overwrite_calls_within Macro
Build / Build (AMD64, Server) (push) Successful in 9m54s Details
Build / Build (AMD64, Client) (push) Successful in 10m9s Details
Build / Build (ARM64, Server) (push) Successful in 10m14s Details
Build / Build (ARM64, Client) (push) Successful in 10m32s Details
Build / Build (ARMHF, Server) (push) Successful in 7m1s Details
Build / Build (ARMHF, Client) (push) Successful in 9m27s Details
Build / Test (Server) (push) Successful in 11m58s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 17m23s Details
2024-01-30 01:30:11 -05:00
TheBrokenRail ccc7e5b190 Fix MCPI Ignoring ♪
Build / Build (AMD64, Server) (push) Successful in 9m37s Details
Build / Build (AMD64, Client) (push) Successful in 10m3s Details
Build / Build (ARM64, Client) (push) Successful in 9m51s Details
Build / Build (ARM64, Server) (push) Successful in 9m45s Details
Build / Build (ARMHF, Server) (push) Successful in 6m56s Details
Build / Build (ARMHF, Client) (push) Successful in 9m11s Details
Build / Test (Server) (push) Successful in 11m45s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m54s Details
2024-01-28 21:48:51 -05:00
TheBrokenRail 7c9d16d662 Fix Mistake
Build / Build (AMD64, Server) (push) Successful in 9m49s Details
Build / Build (AMD64, Client) (push) Successful in 10m1s Details
Build / Build (ARM64, Server) (push) Successful in 10m0s Details
Build / Build (ARM64, Client) (push) Successful in 10m13s Details
Build / Build (ARMHF, Server) (push) Successful in 6m59s Details
Build / Build (ARMHF, Client) (push) Successful in 9m21s Details
Build / Test (Server) (push) Successful in 11m47s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m57s Details
2024-01-27 17:47:43 -05:00
TheBrokenRail 49f56bd90d Fix Benchmark
Build / Build (AMD64, Server) (push) Successful in 10m10s Details
Build / Build (AMD64, Client) (push) Successful in 10m24s Details
Build / Build (ARM64, Server) (push) Successful in 10m15s Details
Build / Build (ARM64, Client) (push) Successful in 10m35s Details
Build / Build (ARMHF, Server) (push) Successful in 7m7s Details
Build / Build (ARMHF, Client) (push) Successful in 9m43s Details
Build / Test (Server) (push) Successful in 11m22s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 17m22s Details
2024-01-23 23:00:22 -05:00
TheBrokenRail 0b252faa5f Simplify Some Code
Build / Build (AMD64, Server) (push) Successful in 10m14s Details
Build / Build (AMD64, Client) (push) Successful in 10m27s Details
Build / Build (ARM64, Server) (push) Successful in 10m18s Details
Build / Build (ARM64, Client) (push) Successful in 10m37s Details
Build / Build (ARMHF, Server) (push) Successful in 7m12s Details
Build / Build (ARMHF, Client) (push) Successful in 9m44s Details
Build / Test (Server) (push) Successful in 11m50s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Has been cancelled Details
2024-01-23 21:58:18 -05:00
Bigjango13 233e8d691b Fix Tesselator instance symbols
Build / Build (AMD64, Server) (push) Successful in 10m36s Details
Build / Build (AMD64, Client) (push) Successful in 10m48s Details
Build / Build (ARM64, Server) (push) Successful in 10m27s Details
Build / Build (ARM64, Client) (push) Successful in 10m42s Details
Build / Build (ARMHF, Server) (push) Successful in 7m15s Details
Build / Build (ARMHF, Client) (push) Successful in 9m47s Details
Build / Test (Client) (push) Failing after 2m55s Details
Build / Release (push) Has been skipped Details
Build / Test (Server) (push) Failing after 1m55s Details
2024-01-24 01:51:57 +00:00
Bigjango13 83a282551d Add packet related symbols 2024-01-24 01:51:57 +00:00
Bigjango13 29b49ac70a More symbols 2024-01-24 01:51:57 +00:00
Bigjango13 118fc6f396 Even more symbols from other projects 2024-01-24 01:51:57 +00:00
Bigjango13 e95236023c A few more symbols 2024-01-24 01:51:57 +00:00
TheBrokenRail 46241c9aa0 Expose Some Properties
Build / Build (ARM64, Client) (push) Waiting to run Details
Build / Build (ARM64, Server) (push) Waiting to run Details
Build / Build (ARMHF, Client) (push) Waiting to run Details
Build / Build (ARMHF, Server) (push) Waiting to run Details
Build / Test (Client) (push) Waiting to run Details
Build / Test (Server) (push) Waiting to run Details
Build / Release (push) Blocked by required conditions Details
Build / Build (AMD64, Server) (push) Has been cancelled Details
Build / Build (AMD64, Client) (push) Has been cancelled Details
2024-01-23 20:51:36 -05:00
TheBrokenRail f7be586a4c Build On Bullseye 2024-01-23 18:20:14 -05:00
Bigjango13 5c5538df2f Move worldgen desync patch to misc, for LAN games
Build / Build (AMD64, Server) (push) Successful in 9m30s Details
Build / Build (AMD64, Client) (push) Successful in 9m43s Details
Build / Build (ARM64, Server) (push) Successful in 8m29s Details
Build / Build (ARM64, Client) (push) Successful in 9m17s Details
Build / Build (ARMHF, Server) (push) Successful in 6m41s Details
Build / Build (ARMHF, Client) (push) Successful in 8m46s Details
Build / Test (Server) (push) Successful in 10m27s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m49s Details
2024-01-21 19:00:01 -05:00
Bigjango13 2995d1c9ad Fix short alignment 2024-01-21 18:43:31 -05:00
Bigjango13 b9b44a62bc Fix worldgen desync (and add some symbols) 2024-01-21 18:24:06 -05:00
Bigjango13 7e546a4a09 Fix ItemInHandRenderer in symbols
Build / Build (AMD64, Server) (push) Successful in 9m32s Details
Build / Build (AMD64, Client) (push) Successful in 9m46s Details
Build / Build (ARM64, Server) (push) Successful in 9m2s Details
Build / Build (ARM64, Client) (push) Successful in 9m28s Details
Build / Build (ARMHF, Server) (push) Successful in 6m39s Details
Build / Build (ARMHF, Client) (push) Successful in 8m58s Details
Build / Test (Server) (push) Successful in 11m53s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m43s Details
2024-01-20 08:24:35 +00:00
Bigjango13 be5bcf24c4 More symbols, mostly item rendering related 2024-01-20 08:24:35 +00:00
TheBrokenRail 91ff082c97 Create AppImages Using CPack
Build / Build (AMD64, Server) (push) Successful in 9m39s Details
Build / Build (AMD64, Client) (push) Successful in 9m57s Details
Build / Build (ARM64, Server) (push) Successful in 8m59s Details
Build / Build (ARM64, Client) (push) Successful in 9m17s Details
Build / Build (ARMHF, Server) (push) Successful in 6m35s Details
Build / Build (ARMHF, Client) (push) Successful in 8m47s Details
Build / Test (Server) (push) Successful in 11m17s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m22s Details
2024-01-20 02:10:18 -05:00
TheBrokenRail 40cd1b0a14 Improve CMake Superbuild
Build / Build (AMD64, Server) (push) Successful in 10m14s Details
Build / Build (AMD64, Client) (push) Successful in 10m31s Details
Build / Build (ARM64, Server) (push) Successful in 9m2s Details
Build / Build (ARM64, Client) (push) Successful in 9m27s Details
Build / Build (ARMHF, Server) (push) Successful in 6m43s Details
Build / Build (ARMHF, Client) (push) Successful in 8m50s Details
Build / Test (Server) (push) Successful in 12m13s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m57s Details
2024-01-16 03:08:34 -05:00
TheBrokenRail 5c607d96b8 Simplify CMake
Build / Build (AMD64, Server) (push) Successful in 10m2s Details
Build / Build (AMD64, Client) (push) Successful in 10m13s Details
Build / Build (ARM64, Server) (push) Successful in 9m2s Details
Build / Build (ARM64, Client) (push) Successful in 9m22s Details
Build / Build (ARMHF, Server) (push) Successful in 6m37s Details
Build / Build (ARMHF, Client) (push) Successful in 8m50s Details
Build / Test (Server) (push) Successful in 11m39s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 17m2s Details
2024-01-16 01:45:52 -05:00
TheBrokenRail 6e9b364f81 Organize Symbols
Build / Build (AMD64, Server) (push) Successful in 9m53s Details
Build / Build (AMD64, Client) (push) Successful in 10m7s Details
Build / Build (ARM64, Server) (push) Successful in 9m16s Details
Build / Build (ARM64, Client) (push) Successful in 9m49s Details
Build / Build (ARMHF, Server) (push) Successful in 6m39s Details
Build / Build (ARMHF, Client) (push) Successful in 8m49s Details
Build / Test (Server) (push) Successful in 11m35s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m27s Details
2024-01-11 22:10:30 -05:00
TheBrokenRail 67a0d3017b Fix Furnace Visual Bug
Build / Build (AMD64, Server) (push) Successful in 9m53s Details
Build / Build (AMD64, Client) (push) Successful in 10m11s Details
Build / Build (ARM64, Server) (push) Successful in 9m17s Details
Build / Build (ARM64, Client) (push) Successful in 9m34s Details
Build / Build (ARMHF, Server) (push) Successful in 6m24s Details
Build / Build (ARMHF, Client) (push) Successful in 8m42s Details
Build / Test (Server) (push) Successful in 11m19s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m15s Details
2024-01-07 04:57:16 -05:00
TheBrokenRail e4d9ee4f20 Code Style Changes 2024-01-07 03:23:43 -05:00
TheBrokenRail d32fa2d265 Add Some Symbols From MCPI-Addons
Build / Build (AMD64, Server) (push) Successful in 9m50s Details
Build / Build (AMD64, Client) (push) Successful in 10m5s Details
Build / Build (ARM64, Server) (push) Successful in 9m12s Details
Build / Build (ARM64, Client) (push) Successful in 9m46s Details
Build / Build (ARMHF, Server) (push) Successful in 6m35s Details
Build / Build (ARMHF, Client) (push) Successful in 8m49s Details
Build / Test (Server) (push) Successful in 11m0s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m16s Details
2024-01-07 02:59:04 -05:00
TheBrokenRail 34c24378f3 Update Example Mods 2024-01-06 20:36:59 -05:00
TheBrokenRail b7b60876d8 Fix Item Dropping When Killing Players From The Server Console
Build / Build (AMD64, Server) (push) Successful in 9m59s Details
Build / Build (AMD64, Client) (push) Successful in 10m15s Details
Build / Build (ARM64, Server) (push) Successful in 9m17s Details
Build / Build (ARM64, Client) (push) Successful in 9m40s Details
Build / Build (ARMHF, Server) (push) Successful in 6m31s Details
Build / Build (ARMHF, Client) (push) Successful in 9m3s Details
Build / Test (Server) (push) Successful in 12m4s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Failing after 17m0s Details
2024-01-06 18:15:52 -05:00
TheBrokenRail 4dff667749 Fix Server Build
Build / Build (ARMHF, Client) (push) Waiting to run Details
Build / Build (ARMHF, Server) (push) Waiting to run Details
Build / Test (Client) (push) Waiting to run Details
Build / Test (Server) (push) Waiting to run Details
Build / Release (push) Blocked by required conditions Details
Build / Build (AMD64, Server) (push) Successful in 10m3s Details
Build / Build (AMD64, Client) (push) Successful in 10m15s Details
Build / Build (ARM64, Client) (push) Has been cancelled Details
Build / Build (ARM64, Server) (push) Has been cancelled Details
2024-01-06 18:03:48 -05:00
TheBrokenRail aa92da6fdd WIP New Modding API
Build / Build (AMD64, Server) (push) Failing after 3m17s Details
Build / Build (AMD64, Client) (push) Successful in 8m28s Details
Build / Build (ARM64, Client) (push) Successful in 8m27s Details
Build / Build (ARM64, Server) (push) Failing after 4m1s Details
Build / Build (ARMHF, Server) (push) Failing after 3m31s Details
Build / Build (ARMHF, Client) (push) Successful in 7m38s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Failing after 5m48s Details
Build / Test (Server) (push) Failing after 3m9s Details
2024-01-06 06:30:23 -05:00
TheBrokenRail 0be1f4fce8 Tweak Outline Color
Build / Build (AMD64, Client) (push) Successful in 8m40s Details
Build / Build (AMD64, Server) (push) Successful in 8m45s Details
Build / Build (ARM64, Client) (push) Successful in 8m7s Details
Build / Build (ARM64, Server) (push) Successful in 8m1s Details
Build / Build (ARMHF, Server) (push) Successful in 6m33s Details
Build / Build (ARMHF, Client) (push) Successful in 8m48s Details
Build / Test (Server) (push) Successful in 11m30s Details
Build / Release (push) Successful in 1m1s Details
Build / Test (Client) (push) Successful in 16m23s Details
2023-12-26 19:22:50 -05:00
TheBrokenRail 631cbc07d0 Simplify Scripts 2023-12-26 17:45:53 -05:00
TheBrokenRail 5f8c700081 Fix CI
Build / Build (AMD64, Client) (push) Successful in 7m46s Details
Build / Build (AMD64, Server) (push) Successful in 7m56s Details
Build / Build (ARM64, Client) (push) Successful in 7m42s Details
Build / Build (ARM64, Server) (push) Successful in 7m19s Details
Build / Build (ARMHF, Client) (push) Successful in 8m9s Details
Build / Build (ARMHF, Server) (push) Successful in 5m59s Details
Build / Test (Server) (push) Successful in 11m14s Details
Build / Release (push) Successful in 48s Details
Build / Test (Client) (push) Successful in 16m8s Details
2023-12-26 17:29:45 -05:00
TheBrokenRail ac55d7d6b3 2.5.3
Build / Build (AMD64, Client) (push) Successful in 10m27s Details
Build / Build (AMD64, Server) (push) Successful in 10m13s Details
Build / Build (ARM64, Client) (push) Successful in 8m34s Details
Build / Build (ARM64, Server) (push) Successful in 8m28s Details
Build / Build (ARMHF, Server) (push) Successful in 6m33s Details
Build / Build (ARMHF, Client) (push) Successful in 9m15s Details
Build / Release (push) Successful in 51s Details
Build / Test (push) Failing after 16m30s Details
2023-12-26 02:31:22 -05:00
TheBrokenRail ef29e4fc0e Remove GL Stubs From Headless Mode 2023-12-25 17:29:30 -05:00
TheBrokenRail 35c6adf94b Fix Bug On X11
Build / Build (AMD64, Server) (push) Successful in 10m3s Details
Build / Build (AMD64, Client) (push) Successful in 10m21s Details
Build / Build (ARM64, Server) (push) Successful in 8m32s Details
Build / Build (ARM64, Client) (push) Successful in 9m3s Details
Build / Build (ARMHF, Server) (push) Successful in 6m6s Details
Build / Build (ARMHF, Client) (push) Successful in 8m27s Details
Build / Release (push) Has been skipped Details
Build / Test (push) Successful in 16m31s Details
2023-12-06 12:54:21 -05:00
TheBrokenRail 1d08b8a29e Update Example Mods
Build / Build (AMD64, Server) (push) Successful in 34m39s Details
Build / Build (AMD64, Client) (push) Successful in 35m14s Details
Build / Build (ARM64, Server) (push) Successful in 37m42s Details
Build / Build (ARM64, Client) (push) Successful in 39m8s Details
Build / Build (ARMHF, Server) (push) Successful in 31m38s Details
Build / Build (ARMHF, Client) (push) Successful in 38m8s Details
Build / Release (push) Has been skipped Details
Build / Test (push) Successful in 42m39s Details
2023-12-04 20:08:48 -05:00
TheBrokenRail 7296fcee83 Update Documentation
Build / Build (AMD64, Server) (push) Successful in 37m21s Details
Build / Build (AMD64, Client) (push) Successful in 37m26s Details
Build / Build (ARM64, Client) (push) Successful in 33m26s Details
Build / Build (ARM64, Server) (push) Successful in 40m19s Details
Build / Build (ARMHF, Client) (push) Successful in 35m14s Details
Build / Build (ARMHF, Server) (push) Successful in 29m48s Details
Build / Release (push) Has been skipped Details
Build / Test (push) Successful in 43m26s Details
2023-12-02 14:25:58 -05:00
TheBrokenRail 97b46ad01a Fix AppImage updating, which has apparently been broken for *years*. Why didn't anyone tell me????
Build / Build (AMD64, Client) (push) Successful in 34m25s Details
Build / Build (AMD64, Server) (push) Successful in 26m21s Details
Build / Build (ARM64, Client) (push) Successful in 31m46s Details
Build / Build (ARM64, Server) (push) Successful in 30m1s Details
Build / Build (ARMHF, Client) (push) Successful in 30m7s Details
Build / Build (ARMHF, Server) (push) Successful in 26m36s Details
Build / Release (push) Successful in 5m26s Details
Build / Test (push) Successful in 43m14s Details
2023-11-25 18:22:43 -05:00
TheBrokenRail 17d11647e7 Fix CI (Hopefully)
Build / Build (AMD64, Client) (push) Successful in 35m13s Details
Build / Build (AMD64, Server) (push) Successful in 25m45s Details
Build / Build (ARM64, Client) (push) Successful in 30m23s Details
Build / Build (ARM64, Server) (push) Successful in 28m10s Details
Build / Build (ARMHF, Client) (push) Successful in 29m18s Details
Build / Build (ARMHF, Server) (push) Successful in 26m1s Details
Build / Release (push) Successful in 5m41s Details
Build / Test (push) Successful in 43m40s Details
2023-11-25 02:39:19 -05:00
TheBrokenRail 48137f9665 Final Tweaks
Build / Build (AMD64, Client) (push) Successful in 35m5s Details
Build / Build (AMD64, Server) (push) Successful in 25m47s Details
Build / Build (ARM64, Client) (push) Successful in 30m50s Details
Build / Build (ARM64, Server) (push) Successful in 29m6s Details
Build / Build (ARMHF, Client) (push) Successful in 29m9s Details
Build / Build (ARMHF, Server) (push) Successful in 25m58s Details
Build / Release (push) Successful in 2m57s Details
Build / Test (push) Has been cancelled Details
2023-11-24 22:16:13 -05:00
TheBrokenRail c956151603 CI Fixes
Build / Build (AMD64, Server) (push) Successful in 38m56s Details
Build / Build (AMD64, Client) (push) Successful in 39m40s Details
Build / Build (ARM64, Server) (push) Successful in 41m29s Details
Build / Build (ARM64, Client) (push) Successful in 43m2s Details
Build / Build (ARMHF, Server) (push) Successful in 34m58s Details
Build / Build (ARMHF, Client) (push) Successful in 41m8s Details
Build / Release (push) Has been skipped Details
Build / Test (push) Successful in 44m51s Details
2023-11-24 18:53:16 -05:00
TheBrokenRail 73b51be43f Try Fancy CI
Build / ${{ matrix.mode }} (${{ matrix.arch }}) (AMD64, Server) (push) Has been cancelled Details
Build / ${{ matrix.mode }} (${{ matrix.arch }}) (ARM64, Client) (push) Has been cancelled Details
Build / ${{ matrix.mode }} (${{ matrix.arch }}) (ARM64, Server) (push) Has been cancelled Details
Build / ${{ matrix.mode }} (${{ matrix.arch }}) (ARMHF, Client) (push) Has been cancelled Details
Build / ${{ matrix.mode }} (${{ matrix.arch }}) (ARMHF, Server) (push) Has been cancelled Details
Build / Test (push) Has been cancelled Details
Build / ${{ matrix.mode }} (${{ matrix.arch }}) (AMD64, Client) (push) Has been cancelled Details
Build / Release (push) Has been cancelled Details
2023-11-24 18:37:08 -05:00
TheBrokenRail 71b11b314b Animated Chests 2023-11-24 17:57:39 -05:00
TheBrokenRail 168b825bf4 Clean Up CI
Build / build (push) Successful in 3h7m58s Details
2023-11-24 12:09:21 -05:00
TheBrokenRail edca3ad394 Fix ARM Build
Build / build (push) Failing after 3h12m6s Details
2023-11-24 03:43:15 -05:00
TheBrokenRail 1aed33a48b Improve Flatpak Build [skip ci]
Build / build (push) Has been cancelled Details
2023-11-24 03:28:17 -05:00
TheBrokenRail 177c5262a6 2.5.2
Build / build (push) Has been cancelled Details
2023-11-24 03:07:06 -05:00
TheBrokenRail 7969fb2127 3D Chest Model 2023-11-23 23:54:36 -05:00
TheBrokenRail b0aac13057 Ȩ̴̛̛̛̝͉̬͙͕̯̬̙̥̬̺̫̭͉̱͈̭͕͍͈̲̯̀̔͒̑̈͛̂̃̑̓̄̊͌͆̎̉͐́̀̇͒̋̒́͊̈́͊̓̈̓̍̑͛̑̃͒̌͗̐̈́̈̈̒̏̀́͌̿̂͂̽́̂̉̅̽̀͌́̔̔̾̃͆̓͗͊͌̃͘̚̚̕̚̕͝͠͝͝ê̴̢̨̧̢̧̛̛͖̲̠̞͓̪͕͙̖̟̯͕̭̘͖̤͕̲̬͔͎̞͇̩̦̳̲̺͎͍̱̯͔̼͙̯͙̮͔̼͎̫͇̯͚̳̭̇̂̃̃̓̅͐́̆̀͑̅͌̓͑̏̄̆͊̅̀̒́̌̄̌̈́͆̋̔͐͊̓͒̈́̋̉͆̑͑̿̈͑̓̾͗̿̈̏͘̕͝͠͠ͅͅḩ̵̛̘̣͖̤̪͉̦͓͖̈́̎́̌̂̈͌̍̍͋͒̊͊́̑̓̓͘͘͘̚͜͝͝͝†̷̧̨̨̨̩̩̺͔̖̼̺͙̰̞͚̻̙̙̜͙̯̪͉̻͈̲͎͔͉̟̻̱̦̝̱̝͍̩̣̞͍̘̥̪̺̺̜̯̹̬̮̱͚̥̦̲̙̪̮̠̩̞̫̞͙̰̪̤͖̙̖̼̖͇͚̆̋̋̀̃͒̑̌͛̍̿̄̏͜͠ ̵̢̛̲͈̩̭͙͙̺̠͇̲̣̗̗͕͍͚̼̯̣̮̌̾̉̓͐̄͐̓̇̂̔͂̔̒̈́͌̏̓̔̾͆̈́͌̑̄͋̃̎͑͛̈́̃̋͑͑̍̍̀̂͆͛͂̇͒͂̃͐͊̈́̍̆͆̐͊̈́̓͑́̐̾͐̈́̒̔̓̾̈́̄̔̚͘̚̕̚͘͝͠͠ͅñ̸̨̢̡̳̙͔̗͕̙̩̝̖̹̪̺̟̼̝͓̬̻͓̮̣̜̖̤̯͖͕̗̝͖̩̬͎̳͚͙̤͙̞̺͉͇̱̩̪̞̭͙̱̫̯͚͓͌̋̄̃̔́̐̀̐̍̈́̽̑͋̋̉̽̌̅̈̅̓̇̓̈̚͘͘͜͝͝͝ð̷̡̧͈̭̤̙̦͇̺̝͖͖͈̤̦̤̗̐̅̓̓̓͐͒̐͗̓̃̈̿̾̒̈̈́̂̇̂̅̽̈̈́͊́͛̅̾̔̀̎̈̽̒̓̎̎̂̀̏̽̃̌̎̎̏́̒̓͗͐̾̍͒̓̏̽̚̕̕̕̕͝þ̴̨̢͕̙̯͈͉͈̳͔̪̥̲̯̥̞̜̪̬̺͖͈͉̼̟̠̥͈̮̻̼̤̤͎̘̪̻̗͐̉͌́̎͑̊́̇̈́͑͐͆̋̆̾͂̈̉̑̈̊́̾̈́̈͂̀͛͂̂͊̓̂̆̉̀͌̒͊͊́͆͛̿͑͌͗̏̽̎̋̚̚̚͘̕͜͜͝͝͠͝͝͝͝͝ͅµ̴̡̨̛̤̭͇̫̹̳͇̞̼̳̣̙̘̫͇͖͈͕̮̀̉̒̎̈̀̓͒̽͊̎͋̆́͂͒̎̉̎̒̑͆͌̒̂̎̂͋̇͌̄͛̑̏́͂̾̎͂̅͋͗̄́̿͌̔͌͘͘ ̶̧̧̧̮̩̜̝͈͙͖̼̦͕̥̻̬̣̜̣̣͉͙͕͔͓̟͚̩͎͍̣̟͔͚͚̼̦̥̯̠͎̩͎̣͈̦̯̰͎̦̜͚̀̇̄̎̀͑́͆̽̓̋̀̎̾̃̅̏͌͑̇̏͗̅́̽̈́͐̑͊͂̃́͐̈͐̀̍̽̔͗̊̓̓̾̉̄͗̈́̓͗̇̈́͛͗͒͑̏̈́̿͗̂̀͒̾̽́̀͒̓̔́̕̕̕͘͘͘͝͠͠͝͝͠͠͝ͅͅͅͅL̵̢̡̧̧̢̨̨̨̛͉̺̖͍̻͉̟̯͔͚͎͚̝̻̞̠͓̻̰͉̲̺̦̤͍̫͙̲̺̣̬̜͖̮̬̪̣͙̩̮̭̪͖͖̱̺͚͍̳̙͚̣̬̥̫̳͔̬͇͙̣̍̓̆͊͐̂̀̔̾͌̔͐͂̃̍̍̊̈̈̐̌̈́̔͂̎͊̅̏̍̽̚̚͜͝͝͝͝ͅͅl̴̢̧̢̩͍̩̫̙̤̦͇̟̪̩̙̠̮͖̩͇̘̼̫̼̲̣̟̩̘̟̳͇̜̠͔̗͈̯͙̞͓͛́̍͂́͑͛̇͂͌͆̇͂̾̐͑̒̌́̒̑̒̈́̃̉́͑̈́͋̓̒͒̽̉̔̆̈́͑͆̍͒̂͆͊̚̚͘͘͝å̶̡̢̢̢̡̨̨̡̢̛̮̰͚͕̹̘̼͈͖̠̲̗̰̥͈̪̲̱͕̦̘͎̖͇̗̜͇̬̤̞̱̯̟͎̲̦̩̜̳̮̟͈͇̫͎̯̗͙͔̼̒̊̐͊̍̂̈͑̑̎͊̒͑̊͋̽̂̉͜͜͝ͅͅͅ¢̶̡̧̧̛̜̲͕͇̮͙̹͎̘̦̖̺͕̪͔͈͉̝͓̖͖̫͖̥̌͛̅̀͆̎́̈́͒̃͑̋͘̕ͅ ̴̨̨̛̛̛̛̛̛̰͈͔̪̥̲̲̮͖̗̺͕͚͚̦̞͕̩̙̲̫̘͚̙͚̖̳̙͈̮͉̬̹̯̞̥͉̼̦̣̠̠̹͚̗̫̝̤̩͓̪̜͒̆͗̀̐̊̔̿̈͆̍͌̾̀̓̅͑͑̄́͂̓̋͆̇͆͆͑̎̑̆̽́̒͊͂̄͊̅͗̅͌͋͑͑̎̈́́̈́̆̿̏̈́̍̊̍́̄͋̀̉̿͛̏̌̉̊͌̒̌̑̌̚͘̚̕͜͜͠͝͠Ì̷̡̧̧̛̻̟̻̤̗̙̻̻̠̖̰̞͍̤̥̙̳̮͉̱͉̳͚̉͒̎̎͌̓̈́̐̓̅̍̈́̍̂̀͒̾͑̈̚͜͠,̴̡̢̨̡̨̡̧̧̛̰͉̫͎̼͍̬̠̬̳̠̫̳̼̻̜̞̪͔̖͓͇͉͖̥̩͚̫͇̱̤́̃͆̄̒͆̒͌̉̄̓̂̂̎̂̌̇̓̈́͌́̃̌̓̈́̋͐́̀͂̓̒̀̄͗̒͂̾̂̈́̍̌̎͂͌̏̊͘͘̕̕͠͝͝͠͠͝ ̷̡̨̛͍̗̙̹̻̳͖͉̟͇͖̙̖̹̙̰̩̘̗͉̗͇͙͔̝̗̯̫̭̬̰̩͉̥͖̪̤̮̟̖̯͖͔̫̦̰̞͍̹̠͔͇̠̣͉͙̖̙̪͔̪͎̍͐̌̀̎͑́̉̈́̐͗̋̅̄͗̈́̉͆̿̓̈́̑̓͐̋̈̇̽̑̈́̓͐͛͐̓̏͒̈́͋͂̎́͐̈́͌̏̓̎̉̾̚̚͘͝͝ͅͅͅÌ̵̢̧̧̨̢̛̛̛̼̙̩̖͓̫̥͎̳͖̟͍̙̦̟͔̲̯̱̮̣̻͙̪̹̭̞̻̠̠̟͔̭̘͔̝̯̮̳̺̗̪͇͇̳̼̦͎̺̩͈̑́͋̌̋̄͌̇̍̓͂̋̆̎̔͌̀͋͆̏̈́́̍̇̈́̿͐͊̅̇̒͐̾̽̌̇́̅̑̒̄͌̿́̈̏͌̂͌̽̿̌̽͛̏͗̋̾̍̈̈́̽͐̏̒̇̈́̂̃̚͘̕̚̚͜͠͝͝͠͝͝͠þ̸̧̧̨̢̨̛̱̲̜͍̤̺̭̮̫̯̼͕͈͍̮͎̥̫̖̙͙͍̞̱̳̜͕̙̯͈̯̣̬̹̰̘̤̣̫̯̙̲͔̝̲͇͙̖̗̬̪̭̱̯̙͈̰͓̱̲̯̈̑̿͌͜͜ͅͅÇ̸̧̢̨̡̨̨̡̛̛̛̛̛̛̲̜͎̙̖̞̪̝͉̹̣̙͙̠̣͈̭̥̺̰͇̤̰̹͔͍̹̥̱̬̫̠̙͖̱̙̞̮̘̟͇̥̹̺̺̝͇̲̣͖̭̭̥͋́̃̓̉̈́̒̂̏̀̉́̾́͆͛̐̂̏́́̇͂̀̏̇̆̓̓͑͐͊̾̾͌̂͑̀͛̏͐̂͒̏̎͆̋͒͛̐͊̃͋̇̈́̓̈́̈̆̚̚̕͜͜͜͜͠͠͝͝͝M̶̡̢̧̨̡̢̛̲̥̯͉̗̥̙̲̬̫͚̼̜̝̲̲͓̖̬͔̖̦͕̫̗͈̼̹̥̣̙͚̮̣̘̟͕̰͍̬̘̮̱̲̘̜̫͚̹̤̘̥̲̮̦̱̲͍͔̝̤̣̣͕̯͕͍̞̘̰̲̮͗̎̓̀́̀̾͐́͋̍̐̽̂͌͑̅̒̏̾̇̋̓̋̈́̈́̐̅͌̈́̀̿̏̈́̒͊̃̽̐̎̆̽̄̄́̊͗̉͋̅͗͒̔̀̐́̈́͌͗̑̀̑̋̍́͂̓̏̈́̐̓̚̕͘͜͝͠͝͝͝͝ͅͅ ̸̧̢̛̛̗̣̺̩̤̬͓͈̦̙̠͉͕̲͚͕͉̩̺̬̣̳͇͍̞͈̬̉̏̔͊̔͂̋̌͒̔̎̊͂͆̓͆̄͌̓̊̈́̐̀̋̅͗͋͊͌͑̿͋̊̈͒̅́͌͒͒́̋̈́̂͌͂̇͒̈̽̔͛̉̔̀͘̚̚͝͠†̷̨̨̡̡̡̨̢̡̥͖̫͕̭͕̣̜̹̺͍̤̞̩̤̮̙̟̞̝̱͇͖͕̗̪̺̝̳͈̘̬̰͉̳̭̼̗̝̞͚̫͕̺̬̪͎̤͉̣̱̩̜́̂͂̽͑̀̀̃̇̽͑̾̈́͑͐̂͝͝͝ͅͅḁ̶̢̡̢̨̧̭̳̺̼̪͔̻̯̗͎̠̪̥̟̙͔̬̳̤͎̪͍̥̳͈̤̱̩̦͇͈̳̻͉̻̥̺͉͓̣̟̝̺̱̣̰̙̱̹̞̱̣̘͍̜̩̥̳̥̭̻̠̥̬͚̤̫̩̮̯̜͍̊̌̀͊́͂̓̒̀̈́̎͑̌́͆̒̇̽̂̿̋̓͊͂̑̌͂͛̿̊͌̈́̈̅̎͋͂͐͑̏̊̑̉͒̎͑̃̎̾̌̈̀̅͐̿̎̒̄̐̌̃̿̈́̎̉̿͋̑̌̂̑́̌̂̇͛̾̕̕̚̚͜͠͝͝͝ȩ̸̢̛̲͖̳̦̖̝͈͉̬̟͚̲͍͚̬̲̥̳͙̰͖̺̙̥̜͈̹̪͚̗̰̹͍̘͓͙̞̬̤̫̞͉̤̲͔̘̭̻̯͍̂͑͊̇̾̀͐̐́̅̒̋̃̑̅͋̀̌͒̆̇́̾̾͂̀̒́̍̒̄̏̓͗̄͑̓̏́̇͒͑͊͑̾̐͗̉͆̅̓̔͗̾̍̏͆͂̾̅͊̽̆̄͌̕̚̚͜͝͝͠͝͠͠͝ͅͅͅͅr̴̢̡̨̡̡̢̧̡̢̨̛̛̛̗͙͖̱̖̣̣̰̻̘̮̻͉̳̙͈̳͚͓̟̦͚͕͓͈̬̥͚̪̰̘̗̮͖̯̬̯̲̠͎͍͔̯̩̱͕̲̺̖̥͈̼͍̤̗͕̻̗̘̙̥̦̼͔̘̰̹̱̰̫̜͇͎͚̞̥̝̉͂̈͐̃̒̔̑̈́̉̒̃̄̀̈́̃̔͆̄̓͋͐̓̍̊̉̍̈́́̒̓̍͛͌̾̎͘͜͜͝͝͝ͅͅģ̶̧̡̧̧̨̧̡̡̨̛̛̹̻̥̱͕̥͙̮̣̻̖̭̪͚͍͖̬̲̠̞̭͈̼̙̼̼̺͍͚̟̭̫̯̦̬̭̤̙̺̪̹̣̦̘̭̠̞͕̳̻͙̟̼͉̘̞̥̭̪̺͔̼̠͖̫̥̬̦̳͈̱̱̳̀͊̅͛̎̆̓̑͒̉̀́̎̔̇̈̂̓̓̏̈̔̇͛̏̑̊͐̈́̀͊̎̏̆̿͗̂̓̊͂͒̌̄̄̔̈̔̏̔͊͊̏̂̅̄͒̀̇̚̚͜͝͝͝͝͝ ̷̢̧̡̢̢̧̺̗̙͉̠̺̤̝̲͔̠̹̬̬͎̪̖̜̘̪̪͚̹̜̥̖̻̙̩̝͕̥͚̜̣̞̫͎͚̪̰̣̭̻̠̲̮͙͙͈̜̣̲̫̺͖̤͉͙̤̻̲͖̙͗͜͜͜͜H̵̨̧̡̡̨̧̛̛̛̛̛̫͈͔̲̭̠̮̪͕̳̼̞̞͈̪̲̺̤̗͓͙̠̬̪͈̩͇͈͎̤̼̳̣̰͉̯̻̋͂̌͂̋͒̂̎̂̑͂̑͐̌̈́̌͑́͐̀̆̏̎̀͌͗̅̉̇̾̆̋̂͒̋̈́̾̓̏͌̈̏͐̈́̇̓̅́̓́͗͋̀̓͑̿̑̅̀̎͊͋̌̀͆͛̕͘̚̕̚͜͝͠͝͝͝ð̶̨̧̨̧̛͇̟͔̮͉̹̻̘͔̞͇̬̹͚̞̗͓̘̠̺̹͚̝̳̗͚͚̝͈̣̠͖̦͙̰̹͍̬̘͙͚͙̺̘̩̙̰̖͇̤̺̎́͛̍̓̊̒̈́̈́̋̈́̋̋̓̾͋̈́͐̈̓͋͋̄̑̒͛̑̄̉̅͋̽̓̋͑̉́̋͑͗̽̂͊͆̊̉̀͑̍̊̑̏̒̄́̆̊̆͒͌̒̾̌̓̐͛̄́̆̇̿̅̃͗̈̄̈́̄̓̎͐͘̚͘̚͘͘͘̕͠͝͝͠͝ͅͅ!̸̢͇̺̲͙̣͚̮͙̝͖͚̒̽̌͂̓́̌̒̓̋̓͐͑̐͋̐̀̔̊̍̂̎̍̆̓̅̒͋̆̇͂̑̀̔͊̏̕͘͝
minecraft-pi-reborn/pipeline/head This commit looks good Details
2023-11-13 17:45:05 -05:00
TheBrokenRail 80c0f24a5d J̶̨̡̨̨̧̧̧̧̨̢̢̢̧̡̨̢̨̢̢̧̧̢̡̡̧̨̤̩̱̗̣̗̱̮͇͇̻͕͉͇̗̭͕̻̝̼̻̤̞͍̫̣͔̗̠̠̪͕̮̙̤͓̯̦̙̬̫͙̖̙͙̬̜̗̙̬̩͔̹̱̠̩͎̞̪͖̯̹̲͙̥͈͕̼̜̪̙͔̖͈̞̣̝̦̤̺̺͓̮͓̮̝̤͙̗͉̗̞̟͈̞̼͕̩̻̥͖̤͇̪̪͍̗̥̼̲̝͇̜̥͚͍͕̞̝̖͔̜̦̮̫͍̜̬̥̲̮̜͈̠͙̭̱͇̥͈͇̩͖̝̱̪̹̜͕͈̫̦̭͉̞̪̤̗͙͚̰̙̝͚̹̝̫̪̤͇̠̮̤̜̭̰̞͚̝̫̭͉͕̠̻̤͕̫̳͓̳̯͍̣̭̘̤͚̯̖͓̼͕̥̞̘̤̣͔̥̮͉͍̝̣͇̳͇͎͈͖̤͎̯̬̬̭̗̫͚̹̫͉̮͋̕͜͜ͅͅͅu̶̢̡̢̧̧̡̡̨̡̧̢̧̨̢̢̧̧͚̟̥̘̭͇͈̳͔̠͓͔͉̱͙͓̪̱͚͉̬͎͉͚̹̩̪̥̤͍̖̜̼̦͍͎̫͇͉͔͔̙̪̝̱̥̭̠̭͈̙̗͓̲͙̰̻̲̬̪͖̤̹̘̬̻̜͙̫͇͎͚̺̩̬̬̰̬̣̲̯͓̝̝̹͖̼͓̹̺̯̱͚̗̩̱̠̠̺͎̮̮̪̤̝͇͚̫̹̼̗̺̻̗͓̠͕̯̯̱̘͎̳̱͉̙̪͇͓̼̯̙̘̪̲̳̭̝̹̦̮̳̗͔͈̪̰͇̖̥͕͓̺͇͔̝̲̫͉̣̭̥̹̼͖̺̰̳̪̠͕͉͚͎̪̪͎̪̩͍͛̊̈́̾͒̈̂͐̑̿͑̀̾̎̋͗̒͋̄̑͐͗́̈́̎̆̉͛̎̋̐͗͒̄̑͌͆̀̉̐̓͐̆͂̂̿̓̇̽͒̀̀̍̓͒͛͆̇̂͒́̄̔͛̎́̓͆̈͐͒͛̽̕͘͘̚̚̕͘̕͘͜͜͜͝͠͠͝͝͠͝͠͠͠ͅͅͅͅͅͅͅͅͅs̷̡̧̨̡̢̢̨̧̨̧̢̢̡̨̡̧̢̨̢̡̨̢̢̨̧̡̛̛̛̛̛̛̛̥̹̳̬͚̠̼̲̬̞̺̤͈̪̲͓̣̤̬̘̰̮̪̟͍̪̗̦̲̺͉̦̤̟̖̲̲̠͉̙̜͇̞͓̻̣̞͉̝̪̺̰͓̝̥͙̘͎̘̭͎̺̮̼̥̩͓̘̠̺̪͚̝̯͈͚̬̦̯̦͕͖̰̭̠͇̣̙͉̻̘̜̟̤͔̳̣̖̻͚͚̻̺̦̳̣̘̣̩͉͈̳͎̫̯͕̪̠͕̲͚̜̗̗̫̫̱͎̯̙̣̗̫̭͎̩̫̟͚̦̟̙̤͉̜͔͙̙͙̫̣̮̱͙̳̺̺̗̼̻͍̣͍͙̯̝̼͕̭̦͖̻̝͍̝̪̮͇̯͔̼̣̩͕͕̘̭͕̖͓̭̉͒̂̌̐̂͑̋͂͋̈͐̈́̄̂̅͗͋̾̓͌̈̀̇̂̇̃̉̎́̀̏̐̐̽̿̏̈́͗͑̓̇̊̊̇̓̈́̒̀̅̈͗̓̌̄͂̽͆̇̓̄̿̃̀͛͊̽̉̑̉̑̆̅̽̎͒̔̔̒̍͆̑̐̽̄͛̐̀́̓̈́͋̍̿́͂͊̃͐͐͋̊̌̒̾͗̓͊͐̋́̔̍́̐̑̌̏̆̓͋̐͗̀͋̆̓̃̇͂͗̎̅̈́͒͗͗̔̆̈̃͋̆̒̇̄͗̋̓̔͛̉̈́̑̂̉̐̋̎̅̅̆͒̈̀͂̾̂̐̂̊͋͋̔̃͋͆̑̇̂̾̆̎̈́̉̍̽͊͊̏̎̏͐͋͂́̾̀̓̽̐̀̓̉͂̅̂̋̅̇̚̚͘̕̕͘̚̚̚͘͘̕͜͜͜͜͜͜͜͜͜͜͝͝͝͠͝͝͝͠͝͠͠͝͝ͅͅͅt̵̡̧̛̛̛̛̛͙͉͍̱̰̘͍̻̬̝̦͎̣̖̙̠̬̻̝͔̣̲̩͍̱̑͒̍͊̊̎́̊̂̂̄̽̿̀̍͌̏̽̿́̍̆͆͗̔̈́́͊͂̆̾̿̐̓̈́̓͑̑̋͗̀͐͛̐͐́́̒͂̆̒̉͌̇̄̀̃̆̂͛̽͐͌̓͗̾̔̊͐̎͐̄͌͋̐̅͋͋͒̋̊̊̀͂̇͛̅̂̐̀͒̒̉̇̃̒̔̔̍͌̒̌̌͊͐͂̑͒̾̽͊̈́͑̐̈̑̉̽̇̆̓͂̋͌́̿̓̇̀̏̾̈́̏̌̔̉̐̽̃̿̈̈̉̈͌͐̊́̾̊̔̉͆̄͆̈́̈́̍̈̃̽̊̉͌̆͑͆̊̽̽̒̒̿̏͋́̀̅̍̏̑̈̿̋̃̈̄̏̋̋̈́̎͆̍͛̀̈̂̀̀̀̈́̐͑͌͑͒́̀̎͛̒̍͗̊̉̒͋͋͒͐̌̏̆̑̓̈́̾̒͂̆͌͆̀͊̐̎̂̅̾̋̔̂̀̍̏̓́̇̽̾̅̚̚̚̚̕̚̚̕̕͘̕̚̚͘̕͘͘̚̕͘̚̚̚͜͜͝͝͝͝͝͠͝͝͝͠͠͝͠͠͠͝͝͝ͅ ̸̡̧̡̡̧̧̧̧̡̨̡̨̨̧̧̢̛̛̛̛̛̛̘̰͓̼͍̗̥̮͕̝̞̟͇̞̙̻͙̯͕̗̺̠̺̗̭̰̗̺̗̲̥̯͎̫̻͔͓̩̜̦̘͓̬̳̟̻͈͔̯̩͕̙̩̝̬͇̣͓͇̱̹̼̹̹̩̰̣̹͈͈̬̜̳̪̹̠͓̥͎̩̥̥̳̱̩̹̝̘͕̗̘̲͓̺̱̹̫̱̟̜̺̹̥͎̳̺̹̘̞̼̟̪͉̝̼̣̤͓̮̩͍̜͍͖̻̺͈̤̹̙͇͙̭̙̜̰̻͙̣͕̼̘̠͓͉̲̻̟̻̦̺͕͍̦̩͖̰̥̩̱̱͚̩̹̰̹̙̫̟̣̗̝̹̝͉̻͉̟̗̙̫͖͈͖̬̜̬̞͍̭̻̤̣̪̭͍̗̠̬̘͕̠͈̖̥̓̀̈̉́̆̌̅̈͊̊̔͗̀͆͒̓͗̽͋̉̒̈́̃͛̾̄̄̀̍̑̀͗͋͛̓̈́̓̈̓̊̅̔̀̓̾̄̈̓̂͊͛́̾̉̉̎̍̆̅͆̀̇̈́͆̌̔̓̈́͌̄̈́̋͌̍̅̓̈͐́̉̀̓̊̍̽͗̂͑̐̔̅͆̀̎̓͊̽̔͑̽̂̓̇̓͐̎͑͛̽̄̈́̉̾͒̍̑̀̐̓̀̇̿̈́̎̊͂͑̇̎͆̇̄͒͋̀̿̓̐͆̈́̂̿̏͂̍̈͌̏̆̿͋̈͂́͗̎͊͒̅̈́̋̃̉̽̀̿̎̈̅̇̽̒́̐̈́̎̑̄̂͗͛̌̄͊̀̓͋͘̕̕͘̚͘͘̕̕̚̕̕̚͘̚͜͜͜͜͜͝͝͠͝͠͠͝͠͝͠͝͝͝͝͠͠͝͝͝͠͠͝͝͠͝͝ͅͅͅͅͅͅͅF̷̢̨̧̨̡̧̢̛̛̛̛͓͈̱̯̬̭͖̫̞̻͖̲̭̝͕̤̤̜̬̖̺̹͎̺͚͎͙̮̟̖̗̻͚͕̙̦̱͚̝̯̜̙̩͈̱̙͖̞̞̰̳͕̦̬̙̉̏̈́̑̎͛͑̆̆̽̉͂̏̑̅̌̿̔͛̿͌̏̿͋̈̐̾̃̈́̾̃̃̀͒̈́͋̅̇̐͒͆̿̄͋̉̋̏́̅͊͑̆̔̽͌͗̒̀̽̍͗́͋̔͆̎͊̊͌͑̾̈̂̑̿͆͛̅̒̇̈́̆́̉͊̆͐̀̋̊͛̌͌̈́͑̿̓̐̈́̅͌̑̅̒͋̒̈́̈́̃̈́̃̂̍̐̏̾͒̀̉̌̀́̂͐̌̒̇̉̅͗̓̈́̽̍̇̂̉̅̿̒̓̾͂̾̿̈́̂̔͋̆̈́̈͌̃̍̈́̎̈̑͆̅̓͗͆͋̈́̂̀́̏͑̃̂̍̐̃͆̓̕̕̕̕̕̕͘̕͘̕̕͘͘͜͜͜͜͝͠͝͝͝͝͝͠͝͝͝͝͝ͅͅͅi̵̢̧̢̨̢̨̧̛̛̛̥̣͕̤̤̥̺̪̝͖̫̪̻̠̲̹̞̟͖̲͕͓̝̲͉͇̙̻̞̤̩̟̣͈̜̞͈̠͇͈͍̜͔̙̦͚͔̣̙̪͙̩̝̮͇̪͙͉͖̪͈͖͖̳̗̯̠͉̭̋͗̄̾̂͆̆̐͛͗́͆͌̃̉̂̋̓̇͑̈́̓̊̀̂͆̒̾͛͗̉̌̍̅̑̀͊͑͛̐͋͆̽̎̑̂̎͑̑̌̓́̈́̒̂͌͛͐̐̿̽̈́̐̀́͆̐̌͊͊́͒̌̂͑̏̔̎͂̍̏͑̇̍̑͊͊̀̂͂̈́̎̅̔̍̅̑̅̽̃͑͒͗̿̑̔̒̑͋͂̂̑̍̄̇͒̐̌̽̀͊̔̊͋͒̾̂̿̏́̀̃̇͐̔̈́́̊̽̄̉̅̓̈̾̀̓̄͂͛̂́̍̉͆͂̓̀̂̓̎̉̎̔̓̐̂̂́̌̕̚̕̕̚̚͘͘͘̚̕̚̚͘͘̚͜͜͝͝͝͝͝͝͝͝͝͝͠ͅͅͅx̶̢̨̢̧̧̧̨̧̧̢̧̧̨̛̛̛̛̛̛̮͎̜̳̻͕̥̰͇̺̝̤͖̬̲͓̫̗͇͎̻̯͍͙̺͉̱͔̤̫̻͚̣̹̥̰̼̫̱̫͖̱̙͓̭̞͇̪̯̘̠̯̩͙͕̙̼̣̪̻̻̥̹͍̹̭̫͓̱̻̖̮̹̮̥̥͕̲͉̝͈̥̗̪̥͚͚͚͕̺̠̹͔̫̤̰̘̯͕̳͈̭͖̣͖̹͖̩̼͙̯̭̣͈̣͇͈̘̫̖̠̞͍̬̫̲̳̻̹̱̳̞͙͔̠̱͕̮̯͉̩̪͎̯̪̻̜͒̇̋̂̋̽͗̔́̐̂̂̾͆̑͗̏̐̈́̃͐̊͌̓̓̐̌̈̇̽̋͛̐͋̄̏͑͋̿̿͆̈́̐̾̈́͗͌́͑́͗̍͒̌̒̅̇͌̽̊̈́̾̒͒͒͆̅̾͌̑͛͑͒́̍̉̏̊́͂̌̇̔͛̾̾̓̽̑̌̾̏̔͋̾̈̊̑̎͋̈́̄̾̄̅͋͐̿̆̋̈̄̐͊̆͋̋̽̂̌́͆͆̎̇̄̃͊̈́̉̔̍̓͆͑̃̋͂̀̉̏̉̓͊̽́͊̓̈́͑̂̑̎̉́̈̈̋̂̈́̒̽̓̑̐́̇͒̊̿̎̔̑͊̿̈̀̈̅̈́̑̊͒̎̏̄͆̈́̇̄́̈́̑̓͗̒̃͒̀̈́̅́̑͑̂̃̂̿̆͌̎͆͌͋̅͑͋͊̈́̓̾̂̏̀̾̔̅̐́̏̓̈͊͋̇͐̅̽͌̂̀̓̏̒̿͌̿͗͗̎̾̀̈́̓̈́̊̚̚͘̚̚̚̚̚͘̕̚̚̚͘̚͜͜͜͜͜͜͜͠͝͝͝͠͝͝͝͠͝͠͝͝͠͝͝͠͝ͅͅͅͅͅͅͅͅ ̸̡̨̧̢̧̢̢̨̧̢̡̢̧̧̨̡̧̨̛̪̜̼̟̤͚̯͓̪̦̥͎̯͕̟͍͚̼̩̩̤̖̥̤̤̳̻͕̼̣͍̜͙̙̭͙̗͇̣͎̦̭͔͙̥̯̬̭̯̞̼͓̳͙͉̲͍͚̲̺͕͕̟̼̻͇͔̺̼͙̦̣̝̖͍̻͍͎̣̹̻̯̲̗̝̤̞̗͍̭̮̮͕̣̗͋̅́̍̍͌̉̊̃̓̓̂̈́͐̓̇̉̋͋̅̊̔͆͗̅̑̓̀̂̍̆̈́̈́̉̃̃̾̏̀͗́̒̌̈͌̅̿̏͆͒̌̀͛̓̐̋̾̀̈́́̾̇̈́̿̀̈́̊́́͛̽̀͌̔̈͆̉͌͋̑̌̈́̽̈́̉̀͛̓͋͗̚͘̚̚͜͜͜͠͝͝͝͠͝͠͠ͅT̴̢̢̡̢̨̡̧̡̢̧̧̡̡̡̨̨̛̛̛̛̛͖̻̯̼̗̫͕̥̝̦̹̪̙̖̩̯̮̦̗̤͚͙͙̬̣̙͈̥͓̬̰̗̤̞͖̞̪̣͎̬͈̹͕͔̦̤̙̝̣̗̜̘͎͙͕͇̟̟̠̮̹̪͖̟͎̼̯̻̮̭͕̬̖͖̼̺̟̠̫̳̖̜̳̖͕̫͔̺̼̯̫̯̫̘̙͔̰͍͎̜̭͎̖͎͚̬̘͔̯̞̝̞̜̣̥̼̙͔̤̦̭̲͍̝̩̼̦̣͇̘̟̦̳͚͔͔̟̣̼̺͎̮̟̖̠̞̗͍̪̯̠̱̭̬̰͍͓̝̲̯̙̭̯̤͕͓̲̹̣̼̦̳̝̞̰͔͍͂̿̓̔͗͌̋̆̓̋̈́̽͑͒̓̈̎̇͗͂̒͐̅̽͗͂̂̇̓̀̍̈́͗̐͂̇̇̽͑̾̏̊̑̓̋̒̒̿͐̐̿̓̅͋̑̋͛͋͗͌̌̑͂̐̏̇̽̑͛̓͗̓̃̂̈́͛̈́̆̌̆̓̋̆̏̊̾́͊̀̐͛̿̅̃̑͑̔̀͂̾̇͑̿̎̐͌͌͌̿̈̽̃́̃̆̆̈̋͑͊̍̈͛͊̐̐̀̍́͊̿̂̌͗͑̃̐̍̊̐̑̈́͛̔̏́̋̈́̑̔͆̎͋̏̒͗̍͗̋͑͂͑̐̑̏̿̃̅͆͒̽̈́͋̋̀̈́̽̑͗̂̿̑̓͐́̊͋̾̄͑̂͐͗̓͛͆̀̏̈́̊́̈́̍̈́̽̂̊̈́̆͊͗̽̈́̓͊̂̅́͗͌́̾̑̀̊͋̀͘̚̚͘̕̚͘̕̚̕̕̕̚̚͘̕͘̚̚͘͜͜͜͜͜͜͜͝͠͠͠͠͝͠͝͠͝͝͝͝͝͠͠͝͝ͅͅͅͅͅͅḧ̵̢̨̨̡̢̡̡̢̡̨̧̡̨̡̢̧̧̨̨̧̢̨̛̛̛̛̛̛̹̞̥͇̘̰̭͖͙͖̥̙̗̹̘͔̞̬̟̠͓͔̪͇̗͈̠̭̱̘̘͎̲̭̼̯̺̘̤̖̲̜̪͔̻̘͕̞͙̜̻͙̦̞̰͉͓̖̞̖͇̺̗̜̩̩̪̺̣̹̺̥͇̘͍͎̫̦͇̻͓̲̗̼͖̙͍̪̙͉̬͓̝̹̳͈̠͎̤̥̯̩̬͙̫̮͕̦͕̻̫̞̙̲͈̤͉͙̤͔̰̗̜̲̹͔̫͈̜̲̦̮͎̗͔̥̤̣̯͈̲͇̝͎͔̺̙̗̲̫̭̟̓̏͋̎̑̂̈́̀̄̉̾͋̍̒̑́̐̈͊͗͊̾̾͛̽̎̊͒̑̈́̀̑͌̌͗̑͋̍̔̎̍͋͗͂́̌̆̏͊͌͒͐͊̈́́͋̈́̒̅͒́̓̉̓́͌̐̓̎̀͂̄̉͌͂̍̌̒́̌͌̃̀̇̂̒̓́́́̃̾̉́̒̆̈̒͒̌͛͋̋̂̒̈͊͐̀͐̾͐̄͋͌̈̐̓͑̍̅͋́̀͂͛͐̉̿͒͌̈́̅̈́̆̉͊̑͊̈́͒͐̌̆́̈́̔͐͋́͐́̆͌͂͂͗̀̋͊̎̏̑̑͛͋̈́̌̿̾̂͋́̅͂̌͌̅́̄͌̎̇͋̾̀̓̀̑̚̕͘̕͘̕̕͘̕̕͜͜͜͠͝͝͝͝͝͝͝͝͝͠͝͠͝͝͠͠͠͠͝͝ͅͅͅͅͅȩ̸̢̢̡̧̨̡̡̨̨̡̛̛̛̛̛̩̪̫̲̣̹̦̝̠̺̬͖̥̬̝̞̥̦̣̤͍̘͈͉̤̘̬͉̖̫̼̘̬͕̗̲̞̟͈͖̥͖̞͔̞̣̘̙̙͖̱̮̙͉̬̤͎̲̙̦̲̱̹͓͉͕̞̰̳̤̰͍̠̻͕̥̺͙̹͇̳͈̻͌́́̀̋͂͒͗̉̏̌̆̒͒͆͒͋͌̀͒͆̂̔́̈̈́͂̾͂̓͗̓͒̆͋̏͛͒̐̈́̋̐̈́͛̉́͆̅͆̾̂̉̄͊̓͆̊͑͐̔̒͂̒̏̆̀̌̉̓̃̔̈̓͛͗̍́̀̉̅͌̀͋͋̒̿̍̒̍̈́̆̐̐͋͆̉̆͒͑̉̅͂̓̿͛́̌͊̍̊̽̽́̓̈́̿̍͑̔́̑̆͗̎͛̅̐̿̑͆͌̉̓̊̑̈́̋́̎̇͂͒̑̇̾͆͘̚͘̕̕̕̕͘͝͠͠͝͝͝ͅͅͅ ̴̡̡̨̨̧̧̢̡̧̡̡̢̡̡̢̡̨̧̧̡̢̛̛̛̛͔̝̦͉̜̭̹̫͕̻̫̳̩̰̖̤̮̮̬̱̖̱͕͙̲̹̞͎͚̻͎͎̜̗̻̪̥̥͈̖͖̖̗͎̖̼̺͖̫̪͙̻͚̱͙͚̤̞̮̯͉̲̰̼̥̙͔̱̹̭̗͙͖̥̥͕̙͎̖̮̼̤̻̙̟̹̣̞̼̫̗̳͇̖̮͍̪̹̞̦̙̹̮̭̫͍̭̹̯̗͍̣͕̱̭͓̩̗̭͍̰̱̦̮̤͓̲̮̞̖̘̲͚̗̜̲̯̱̠͍̠̺̰̳̙͎͉͉̟̮̲̩̖̤͙̰̖̙̤̹͙̭͎̹̺͙̼̠̻͉̯̪̪̫̳̰͇̘̣̻̪̙̗̠̝̤̩̤̣͚̦̹͖͚͖̜̳̦̝̺̳̻̼̩̹͖̥̞̗̥̩̱͐̓̂̊́̄̃̈́̏͋̿̿͂̐̎̈́͊̈̌͒̇͐͊̆̽̅̔̓̎̃̀͗̾̓͋͆̃̌̀̾̋̽̇͛̿̀͒̄́̉́̀̉͛̅̎̀̽͋͑͋͗̊̀͋̾͛̈́̇̐̓̏̄̂̅͘͘̚̚͘̕̕͘͜͠͠͠͝͠͝͝͝ͅͅB̴̨̧̨̢̡̨̨̨̡̨̧̡̡̢̢̡̡̛̛̲͕̹̠̮̠͖͇̮̩̰͎̱͕̳͈̱̫̹̮̗̠̙͓̮̖̻̫̟̣̗͕̫͇̗̥͔͔̩̳̥͙͔͙̥̻͙͉̣̯̮̰̩̹̼͎͓̜͈̜̖̰̣̹͕͚͔̜̹̭̗̖͍̪͔̙̭͖̹̹̮̜̮̤̜͔̜̺͕̮̯̦̣̱̖͍̭͎̦̣͎͔͚̙̩͇͓̫͎̼̻͖̼̮͖͓̼͈̞̘̤͇͈̺̞̗͔̩̮̪̱̠̬̼̺̬̲̤̖͕͍̣̤̦̘̻̹̠̘͖̥̜̮̤̰̬̖͈̤̀̈́̉̇̑̇̈̄̑̀͊̓̈́͌̾̀͊̾̀͆͑́̂͛̋̓̅͌̆̓̌̇̈͒̾̾̽̇̈̅͛̐͊̓̉̌͂̂̅͗̆͛̀̋͋̂̌͛̈͌͊͆̀͐̊̑͒̃͂̌̾̏̂͛̉͌̉̄̈́̄̀̈́̉̌͋̈́̅̀̐̀̾̈́̓̽͑̃̏͒̄̓̍̌́̀̿̐̿͒̈́̌̃̏̈́̏̈́̅͗̂̾́̆͌̏͒́̈́́̑̾̆͒̄̓̈́́̈́̀̇̒̒͋̇̈̔́̀̽̎͌̎̌̊̚̚̚͘̚̚̚̕̕͘͜͜͜͜͝͠͝͝͝͝͠͠͝͠͠͠͝͠͝͠͠͠ͅͅͅͅư̵̢̧̡̨̡̢̡̧̨̢̧̡̡̨̡̛̛̛̛̛̭̮͕̳̜̬̠̟͎͎̘̜̹̣̥̦͎̰̺̼̹̣͕̰̖͔̣̳͉͙͚̫͎̹̫͍̟̫̺͈̫͔̺̗̬̖̳̖̯͖̲̤̦̙̹̠̬̭̺̥̲̦͇̳͖̤͖͉̮͉͇̟͍͔̟͍͕͍͕̙̱̘̜̺̲̠̞̹̟͚̦͈̘̦̼̠̟̳̳̝͎̟̟̣̮̙͚̱̱̝͈̭͍̟͐̑͋̍̂̆͂̓̽̈́́̈́̑̅͊̔͑͐̓͋͆̄̅̔͒̇̋̒̓́̏̀̉̒̀̿̐̈́͗̃̏̅̾͊͗̎̏̀͆̄̈́̇̈̔̔̏̇́̀̈́̒͐̑̏̾̌̐̉̒̏̏͌̄̒̇̍̃̊̏̅̓̃͐͗̓̽̌͌͌̌̓̑̓́̂̽̓͛̂̀͌̾̄͆̀̅̌̒̆͗̐̊͆͒̀̔͆̔̏̀͒̍͋̀̅͛̒̂͂̅̉͋̿̿͌͛̍͗͑́̀̃̀̏͋̃̓̿̆̈́͘̚͘̕͘͘͘̕̚͜͜͠͝͠͝͝͝͝͝͠͝͝͠ͅͅͅį̵̛̛̛̲̫̯̟͔͖̟͇̦̠͓̘̪̻͋̾̀̿̌̀̑̿̍̈́͋̒̔̄̑̏̄̏̒͐͋̏̍̏̋̈́̃́̇̋̀̃̆̈́͒̒̅͑̈́͑̈̾̌̀̒̾̈́̊͂̅͋̃̽̃̑͋̄̍̎̑̃͒̐͂̋̊͒̌̋͌̈́̂̇̋̑͆̄͒̀͑̿͐͗̈͑̈̇̓̇̈́͋̌̄̉̂̀̀̈́̀͂̆̆͗̋̄̅̈́̔́̀̂̾̇̊͗̿͊̀̋̾̎͐̑̉͛̉̓̾̐͌̊̆̍͆̈́̆͊͂́͊̒̀͆́̌̋̾͛̈́̾̍͋̍̉͛̽̽͆̊̀̄͗̃͒͆̐̓̈͐̔̓̅̓͌̋̕̚̚̕͘̕̚̕͘̚̚͘͜͝͝͝͝͠͝͠͝͝͝͠͝͝͝͠͝͠͝͝l̸̢̨̨̧̢̢̨̡̧̧̨̢̡̢̡̡̡̢̡̡̡̨̨̛̛̛̝̰̜͎̹͉͔͓̹̱̞̥̦̘̯̩̣͈̤̙̘͈̗͖̺͇̳͙͔̩̯̱͍̱̝͖̮̭̼̬̬̙̘̜̼͉̺͔͔͇̜͖̞͔̱̱̱̘̝̦̻̘͚̤̤͈̞̟̟͚̠̯̪͖͉͖̪͔̻̖͍͖̘̟͖̳̦̻͖̮͍̬̥͚̼͔̩̯̳̯̗͚̭͚̤̩͖͍̱̻̮̦͈̪̱̹͇̬͕͉̬̦̝̜̳̣͉̘̑͐͐̅́̾͌̄͋̋̀̊͒̓̅̑̿͑͗͌̃̈́́̑̔̀̑͆͛̆̐͛͊͆̍̐͋̔̋͋̈͗̃̃̓͊̀̆͆͒̀̑̒̃́̅̆̒̈́̽̈́̒̽͌̐̌́̓̽̾͑̓̅̂̇̐̊̈́̏̾̾̀̉͒̃̾͛͐͊͆̇͌̅̈́̔͛͐̄̈̊̓̋̈́̾͑̈́̀̆̎͑́͊̀̎̐͌̋̋̅͒̒͆͋́́̈́̏̔̾͋͂̄̕̚̕̚͜͜͜͜͝͝͝͝͝͠͠͝͠͠ͅͅd̴̢̢̡̛̛̛̛̛̛̛̛̪͔̖͇͚͓̩̪͔̜͓̣͍̫̳̺̳͇̖͖̟͉̹̟̪̫̖̜̩͙̗͕̳̹̥̭̩̙̹͔͙̟͔̥̰̙̆̂̈́̍̔̌̈́̃̿̒̏̓͐͆̎̎́͗̈̽͌̆̆̑͂͛̃̆̈́͗̇͐̿̈́͒̽̌͗̾̌̐̓̈́̽͗̾̇̑̔̂́̓̓͛͋̏́̏̑̓̍̑̓̃̂̀̀̏̆͋̉̇̀͂͗̄͐̊̈̓͊̈́̽͑́̽̅̽̓̑̈́̂̈́͋́͗̑̇͋̒̋̎͛̈́̿̃̔̐͂̍̀̃̔̀̏͂̅͋̆͆̇͒̈́̾̽͂̎͊̀̄͛́́͋̉͗̓͒͌̈́̏͑̆͒̏̓̃̓͐̏̈́̋͛́́̂̈́̓̋̐̅̏͗̓̓̅͋̔́͋̏͑̑̀̓͐͒͌̀͛̔̐̓̈́̉̈̈́̍̋̄̈́͋̇̆͑̂͗̾̂̒̉̍̈̐̐͑͑̂̾͋̀̐͆̔̌̆̍̽̅͆̓͋̀̽̔̈̽̀̃͑̉̂̈̄͆̌͗̃̎̈́̇̓̍̈́̌̃̋̚̚̕̕̕̕̚̕̕̕͘̕͘̕̕̚̚̚̕̕͘͜͠͝͝͝͝͝͠͝͝͝͠͝͝͝͠͠͝͝͝͠͠͝ͅ ̵̡̨̨̧̨̧̧̨̛̛̛̪͍͖̜̟̫̬͚̦̮̪͚͓͈͙͕̺̮̬͍̯̼̞̤̙̬͚͚̖̳̹̙̤̦͙̖̼̜̫̟̘̺͖͖̰̗̦͔̫̟̗̞̹͇̣͕̫͇͔̪̬̯̩̥̭̗̫̤͉̖̻̳͔͎̤̪̻̜̦̬̫̩̟͚̺̼̩͎̖͚̩̫͖̰͐͋͑̎̎́̊͒̈́͗͆͗͑̀͌̐̎͂̑̏̾̈̈́̈́̃͌́̄̈̿̍̊͊̉̇̀̾͌͐̐̄̐̂̈́̏̒̈̀̀̎̊͋͐̈̏̅̾̈̎̆̂̍̅̈̀͌̒͌̈́̇͑̇͌͂̅̈́͐́̇͌̓͊͑̃͐̓̉̈́̊̒̀̎̔̾̉̌̓̊͌̓͋͒̏̒̀̈́͒́̓̂̂̌̄̈́̀̊̐̈́͂̓̈́͊͛̃̾̈̿̆̿̍̔̈́̽͌̊̅͆̎̊͑̉́͛̌͑̏̒̈́̈̍̔̿̊̀̂̊̾̌̃́̈̈́̐̃͆̽̒̅͊̓̿́͋̀͊́̂̍̿̐̀͋̀̂̈͑̄̍̔͌́̆͑̑̎̌̊̈́͊̿̈́́̂̇̉̋̆̌̕͘͘͘͘̚͘͘̕̚̚̕̕͜͜͜͝͠͝͠͝͝͠͝͝͝͝͠ͅͅ(̴̢̧̡̧̛̘̭̗̥̙͉̮̯͉̦̯̦̫̙̹͚̜̜̥͙̰̯͇̖̩̼̲̙͚̣͍̳̲̬͖̜̼͙̤͓̫̟̺̻̹̲̖̗̺̥̫̘͓̻̗͎̪͎̖̩̩̦̦͈̣̣̺͉̺̥͎̠̯̦͚̝͈̬̲̭̻͍͚̲̯̍̈́̈͊̾͗̊̀̓͌͌̒̎́̒̎́̅̓̅̅̈́͆̃̄̊̊́͂͒̈́̒̉̓̓̾͗̑̔̐̈́̇͗͐̈́́̅̈̄̓̓̎́̓̂̋͆̈́̂̑̑̽̈́͆͛̒̅̑̊̋̔́̎͂̈̔͋̈́̃̀̑̒̍̆̌̎͋̀͒͒͊̈̂͐̈́̽̀͌̆͐͌̈́͆͂̆̐̓͂̈̌̀́͐̑̅̋̈͐̽̂̐̇̏̐͐̄̅̔̚͘̚̚̚͘̚̕͜͜͜͝͝͝͝͠͝͠͠͝ͅͅH̵̡̢̡̧̛̛͖̤͈̣̺͉̳͈̖̜̘͖̪̼̣͇̮̜́̆̐͌̓͗̾̇̈́̏̎̊̋͑̍̌̒̉̐̐̄̓͂̽̐̅̑̀̅͗̅̀̓̓͐̅̌̉͛̀̐̓̈́̔͌̉͌̽̉͆̿̊͊̓̈́͋̓̀̇̓̂̒̓̉̀̆̊͛͆̽̽͐͐͛̇́́̀̐̓̄̾̉̎͋̑̿̐͋́́͐̿̈́̍͋͂͑̀̒͛͋̐́̿͛̓̋̏̓̓̋̎̽̉̔̈́̓̒͋͐̄͗̈̊̀̇̑͋͒̾͊̈̄́̽͘̕̕͘̕̕͘̚̚̕̚͘̚͜͠͝͝͝͠͝ͅǫ̵̡̢̨̧̧̧̨̨̧̨̧̨̡̧̧̧̨̡̧̡̨̨̡̛̛̛̛̫͇͓̗̠͈̬̼̖̗̤͕͈̠̙̼͕̪̮̜̠̻̲̺̯̣͎͙̥̯̖̳̤̞̮̞͕̭̮͓̻͕͖̝͈̟̰̱̪̤̣̰̤͉̠̰͚͇̼̯̫͍̣͚͎̭͙͍̱̳̪͈̞͈̹͚̲̞͔̙̪̞̗͈̩̹͇̠͇̩̲̟̳̖̻͍̤̜̙̜̥̪͕̤͔̮̤̗̜̪̺̺̙͕̜̞̘̳̪̹̰̺̠̩̻̤̤͍̦͚͖̩̟̖̻͕͇͕͇̲̘͎͈̪̬̜̻̜͓͓͚̮̠͚̠̼̳͎̖̜̣̘̙̹͓̮̗͕̟̭̘͉̥̩̳̱͚̣̣̱̗̩̭̦̗̦̞̦̱͙͍̰̟̱̩̠͖̮̟̱͖̰͈̖̺̣̮̗͇̦̣̬͓̳͙̰͉̖̹͖̜̫̭̥̗̦͍̘̫̯̯̗̼̩̮̟͔͖͍̞̽̅̓́̈̀̂͛̈̑̂͋̒̆̌͂̀̎̋̋͌̌́̀̌͊͊̏͋̃́̋́̈̎̎̒̌́̒͋̾̈́͊̃̃́̍͛̄̾̐̆̅͐͗͒́͋͛̌̅́͌̀́͒̇̔͂̌͗̐͛̽̀̀͗̾̂͂̃̈̐͋̒͐̐͗͗̍̿̏̀̈̾́͌̔͌̃̅̄̀̈̂̍͒̈͊̂̾́̈̋̈́͌̐͊̈̓́̒̓́̍͊̾̾̂͂̍́͌͛̆͐̓̈́́̽́̂̂͗͛͌͆̀̍̑̊̿̋̏͛͗̍̀̆͆̀̐̈́̀̒̎̐́̽͊̃̏͊͊̋͒͆̈̅̀͒̕̚̕̕͘̚̕͘͘̕̕̕͜͜͜͜͜͜͜͜͝͠͝͝͠͝͝͝͝͝͝͝͝͠͠͝͠͠ͅͅͅͅͅp̵̧̢̧̢̨̛̛̛̝̻̗̳̝̜͈̖͎̠̩̳̝̺͕̫̯͖̱͙̦̦͚͕̘̖̺̠̠̩͙̜̪͇̼̺̖̆̎̾̽̑̉̽͐͒͌͌͐̀́̿͗͊̒̇̿̇͛͂̀̊͆̈́̂́̒͑͛͂̇̃̑̉̈́͊̈́̌͌̽́́̃͊̂̓̓̐̽̊͌̈̈́͌͑͛̍͂̏͑̎̉̀̍̾͒͂̉̉͊̇͌̓̈́̀̅̇́̿͌̈́̉̂͌͌̐͑̐̐́̔̽̋̀̔͗̽͑̏̊̔̈̀͗̈̓̒̍̏͑̒͑̉̆̊̈́̈́̈́̈́̈́̓̈́̎̾̈́̂̆̊̆̏̀̄͐͒̉̈̈́̚̚̕͘͘̚̚̕͘͠͠͝͠͝͝͠ͅͅę̷̧̡̢̨̢̨̧̢̢̡̛̛̛̛̛͚̩̙̠͇͕̲͇̗͕̤͓̘͚̬̣͖̞͖̬̪͕̼̪͈̺̙̼̳̩̰̪̥̭̼̠̩͓̗͉͖̦͎̮̱̰̺̙̯̯̺̣̲͙͉̘͍͇͕̻͉͇͕̪̥̳̦̼̜̥̟̖͚͖̼͎̦̺̖̲̯͍͓̯̣̪͓̝͉̦̗̬̦̩̜͎͉̗̗͍̜͓͚̲̤̩̖̳͖͔̜̝̰͕̹̻̤̖̮͎͎̱͉̮̗͕̙̞̘͎̰͎̣̗̼̬̻͓̺̬̟̬͓̥͉̱̖̤̣͕̰̱́̾̎̉͆̆̀͛̈́̉͐̅̆̋̾̌̋́̅̊͂̀͒̓̿̆͊͐̈́̐́̎̃̔͆̈́̒̒̋̓̓̐̽̔̌̈͒͒̐̀͊̇͂͂̈̓͊̽̎̅̐̈̔̒̌̅͑̒͗̔́͛̃̈́̊͛̈́̾̅̓͑͗͐̀̌̇̈̾͌̌̄̃̈́̐͗̅̈́̈́̾̈́̓̊̃̿̆̀͐̒͆̃̂̀͗̈̈̍̿͒̉̉̒̅̇̅̄͌͂̀͋̑͂̍̊̔̌͌̈́̓̄̋̔̃̍̿͑̉̿̾̍̄͛̈̀̇̐́̅̈́͆̎̈́̂̽̂̑̏̃̏͂͌́͌́̿̀̒̂́̅́̓͂̂̈́͋̏̇́̈́̄̽̉͛̂̽̀̈̍̀̀̐̉͌̇̑̓̆̇̍̄̐̊́̅̊̈́̿̀̍̑́̇̾͒͌͂̎͆͐͗̆̇̇̄̅̀͘͘̚̚̚͘̕̚̕̕̚̚̕̚͘̚̕̚͘̚͜͜͜͜͝͝͠͠͝͠͠͝͝͝͝͠͝͝͠͠ͅͅͅͅͅf̸̢̡̡̨̢̢̢̡̧̢̢̡̢̢̨̡̢̢̢̨̢̧̧̨̛̛̛̛̛̤̭͖͇̯͍̣̜̖̟̭̭͍̰͙̯̥̱͕̤͕͇̯̩̫͈̯͚̗͇̘̦̠̦̻̟̗̳̩̥̜̱͓̬̺̦̭̥͕̖̪̻͖̳̭̮̠̘̜͈͙̤͉͚̬̞̲̳͖̦̯̞͚̜̘̯̭̥̹̯͕̱̞͙̝̳̗̰͓͙̲͇̹͍͚̣̺̮̖̤͇͉̫͉͙͇̺̦̳͉̟̫̘̹̦̮͈̟͕̫͚̤̫̱̙͍̫̲͎̪̙͔̣̮̺͉̳̫̪͇̹̜̹̺͍̟̜̼̩͇̮͍͙͙̫͕̳̣͖̬̟͓̙̗̟̪͖͕̜̰̳̼̱͈̳̩͓͙͍̖̼͔͔̬̼͓͖̯͉͖͎̻̘͙̤̯͇̠̗͈̦̈́́̐͂̀̐̆̌̇̂̊̑̅̈͐̆͗̒̑͋̅͊͂͛̀́͐̌̍͐͆̋́̏̍̓̒̎̎̍̉͂͐̐͗̀͒͆̈́͆͋̈̍̐̆̿̔̉́̀̾̃͂͗͑̋̈́̽͆͋̽̔̔͛̈̊̿̔͗̂͛͗̉̈́̉̀͊̓̒̆̔́̓̐̎̀̂͌̎̈́̀̓̀͒̈́͑͒̿̏̑͒̉̍͗̓̌̋̋͗̈̿̇̐̈́̇̍̂̓̊́̊̈́̈́̒͋̈́͆͋̽̔̓̅͂̇̽͑̃̅̀̓͗̌̐͛̓̊̀̉͛̽̅͒̌̀́̽̋̄̈̏̽̕̕̕̚̚̚̕͘̕̕͘̕͘̕͘͜͜͜͜͜͜͜͠͠͝͝͝͠͝͠͝͠͝͝͝͝͠͝͝͝͝͝ͅͅͅͅͅͅͅͅͅͅų̷̡̨̡̡̡̫̣̜̬̮͇͖̙͎͖̣͙̻̹̼̭̣̜͉̥̩͚̩̲̼̼̩̣̳͓̣͎̩̼͔̬̤̣̩̘̤̱̟̭̘̙̪̫̞͕̘̤̩̥̹̣̱̾̌͂͊̋̃̒͗́͊̈͑̒͋͘͜͠ͅͅl̸̢̢̨̡̢̡̧̡̛̛̛̛̛̛̛̛̥̯̳̬̥̺͙̰͎̭̞̘̫̼͉̫̜͖͕͔͚͇̯̮̪͖͓̥̺̦̟̪̠̣̻̣̗͖̻̲͚̮͕͈̹̺̣̮̣̘̠̜̻̘̬̹̘̠̼̳̬͕͍͇͉̲̞̪̦̰͚̘̙̺̫̻͎̦̟̹̣̠͍̭̗̖̤̫̣̣̞̱̦͇̫͚͚͇͖̯̬̤͕̪͇͈̳̠̣̻͍͖̼̹̱͕̹̟̀͂̎̈́̑͋͋̇͊͛͑̎̈̐͌͆̐̊̀̅̂̾̄͛̐̽̔́̏̀̈́̿͆̇͊̓̎̈̎̎͐̈̾̌̄̐̃̋̈̇̅͗̑̊̈́̽̌̃̈́̽̋̊̆̅̽̍̔̇̉̒̊͂́̇̃̒͆͊̌̓͌̅͊̄͆̅̂̈́͆̄̈̀̊͗̎̉͌̿͛́̂̌̊̎̎͒͊͛͗̍̀̋́̇̎͛̈́͂͐̂̆͒̈̆̑͐̾͗̆̊͐͊́̓̔͐̅̋̐̈͆͐̓̆̑̑̌̄͋̿̀͋͋̽̄͒̾͌̅͛͊̒͌͂̎̃͌̇̃̿͆̉̇͂̀͆͗̎̊͌́̀͗̽̚͘̚͘̕͘̚̕̚̚̕̚̚̕̕̕̕̚͜͜͜͠͝͝͝͝͠͝͝͠͠͝͝͠͠͝ͅͅl̶̡̧̧̧̧̡̡̨̨̨̢̢̢̡̧̨̢̧̨̡̨̡̢̛̜̳̩̪͈̰̣̤͓̙͔̗̣̗̹͉̞͉̠͖̪̭̗̲̰͇̠̱̯̟͖̯̝̠̳͍̬̳̬͔̠̟͍̬͓̜̪̭͚̟̝̺̫̩͈̩̼͕̘̜͔̹͇͙͍̪̪͔͇̩̠̟̲̝͕̖̥̣̣͕̮̣̤̙̥̼̫͓͍̥̘̩͍̯̺͍̪̠̮̟͔̠̟̮̣̞̻̥̠̯̣̯̮̬̘̦̖̝̩̥̝̪̫̱͍̥̺͙̺̹̱̤͇͕̜̻̮̞̫͖̠̳͚̪̘̖̟̭͔͙͈̜̟̰͖̪͚̖̤͕͓̘̮͚̼̰̜̺̪͖̥̠̮̯͉̙͕̹̙̲͈̫̮͓͍̣̥̥͉̹͎̥̣̫͉̞͍̲͔̣̰̳̠͈̤̣͔̠̥̥̓̆̊͋̔̆͋̊̾̃͒̉̀͛̾̍̃̋̈́̎̚͜͜͜͜͜͜͜͝ͅy̴̨̢̡̧̧̢̨̡̛̭̲͎̜̯̪̳͔͔̳̳̠͚̼͙̰̥͙̟̳͈͚͚͚̟̜̥̣̠͇̳̬͍͔͚͕͙͇͍͈͎̖̟̭̝͈͈͔͍̞͈͈͉̮̙̥͖̖̣̤͈̘̲͈͆͒͊̄̓̓͆́͛̇̍́͂́̒̿̈́͐̄̀̽͗̅̑̀͆̊̀͋̀͐̆̒͌͑̀̃͗͑̀̔̌͆̓͛̾̌̂̃̓̃̓͂̀͋̆͊̊͌̊̈́͋͐͆̾͐͛̏̏͂̀̀͐͋̇̎͗̑͛̅́́̈́̊͆̑̽̀͗̂͂̇́̎̈́̎̎́̌͐̋͋̑̎̀̐̐̐̀̉̈́̍̅̌̀̑̊̈́̍̏̾̀̊̐͊̄̅̌̅̈́̑̔̒̌̈́̄͆͒̇̒̍̓͊̀̎́̐̎̎̓̉̋̉̍̾̏͗̾̿̓̎̾̏͊̆̓̋̽̊̉̐̈̔́̈́̿͌͐̓̄̽́̓͒̀̃̀̄̇͒́̅̀̊̓̌̅͌͒̓̀̀͗̂̓̆̇͒̂̇͗̿̉́̃̉̈́͌͊̔́̽̍́̓̇̽̓̅̏̒̍̚̕͘̕̚̚̚̚͘͘͘͘͜͝͝͠͠͠͝͠͠͝͠͠͝͠͝͝͝͝͝͠͝͠͝͝ͅͅͅ)̴̨̧̡̢̢̢̢̡̡̨̢̧̢̨̨̡̡̧̰̠̣̤͕͕̳͓̲͉͎̮̳̼̟͇̲̳̺̳͚̟̙̫͈̱̮̲͈̬͓̝͙͖̝͚͕̟͎͎̪̱̹̗̼̹͙̫̰̬̮̥̦̻̪͍̮̝͓̪̤̜̹̹̝̻͓̠̗̪͚̜̭̝͉̜̣͈̹͉̪͎̜͙̗̫̺̘͙̘̼̜͕̰̠̟̮͓̳͚̬̝̼͖͕̘͚̱̜͓͉͉̮̟͕̰̮̩̬̩͓̪͓̪͓͎̻̲̙͉͚̺̻̩̮̟̬̗̖̩̝̮͖͖̺̩̝̙͓̜̪̺̩͚͓͕̙̭̯͇̪̣̭̦̼̥̥̱͔̹̤̝̗͉̙͖͕͈̪̟̗̟̞̣͖̤̪̮̹͈̰̱̬͔̗͓̫͎̦͍̬̭̲̩͉͍̺̱͇̻̟̥̞̼̫̜̯̮̗̣͙͈͛̒͋̿̾̃̾͐̓̓̌̇́̋̀͒̂͌̓͋́̂̓͜͝͝͝͝ͅͅͅͅͅ ̶̧̧̨̧̧̨̨̛̛̗̘̝̼̙͍̖̗̼̪̠͙̜̺̰̼͖̬͉̥̺͔̖͖̯̜̬͕̖̭̭̭̯̖̝̜̱͉͕̩͚̥̪̥̮̼̦̫͓̣̱̬̖̼͓͚̳͇̗̞͚̞͖̗̳͎͉̠͚̥̝͔͈̬̖͔͍̠̗̟̥̳͕͍̺͙̖̯̯̗̙̼̘͇͖͚͍̩̱͈̙̫̻̝͉̤̻̼̪̯̈́̈́̌̀͂̈́͌̋͛͋̏̿̀́̈̿̄̀͛͆̑́́͑̑͑͛͌͊̕͘͜͜͜͜͜͝ͅͅͅͅͅ(̷̢̨̢̨̢̧̡̡̡̨̟̗̖̯͕̞̞̭̰̮̫̘͓̼͇̻̝͚̬̤̻̱̫͇̳̪̼̫̼͈̮̹̮̱̗̖͇̤̱̠͙̼͚̻̞̣̳͎̩͍̭̖̩̫̖̭̬̰͚̖͓̝̟̦̫͎̩̖̩̬̖̝̬̦͚̹̞̪̪͇̭̯̘̝̹̞͉̖̘̱̣̤̖͊͌͐̔̏͛̓͆͆͐̄̑̾̌̇̆̉̌̊͆̂̅͛̀̄̇̽̋͊͒͆̐̀̾̓̌̾̑͊̌̒͗̾̈͛̍͂̈̓͘͘͘͘͘̕̕͜͠͝͝͝ͅM̴̡̨̧̨̧̡̡̨̧̧̧̛̛̛̛̛̛̛̫͇̘̬̥͎̘͓͓̮̦̗̹̭̼̭̟̩̝̣͓͚̘̥͔̲͙͈̖̤͔̯͉͕̬̰͈͍̰̭͍̗͇̦̟̙͉̦͕͍̤̯̼̹͖̜͕͉͖͔̩̝̠̘̪̠͕̯̪̲̘̭͓̬̮̰̙̥̰̝͈͍̩̜͍̥̘̮̯̞̠̲̲̯̬̝̥͎͇̼̝͇̜̰̳̯̝͖̫̪͔̝͖̯̩͕͕̮̬̠͇̻̗͉͔̖̟̙̬̞̪͇͇̠͇͚̫̯̖̝̝̱͖͉̣̙͎̥̯̗̺̜̖̜̭͚͇͈͉̖͋̎͒̈́̍̄̊̈́̒̿͊̀̔͑̈͂̉̍͛̏͗̈́̐̃̐͂̀͊̊̑̈́͌͋͆̆̆̒͋̋̊͆͌͂̇̅̽̐̀̿͋͋̌͒̓͒̈́̾͂̂͗̔́̓̋̈́͑̏̎͛̊̈́̓͋͑͛͒̌́̀̀̽̈̌̍̀̆̋̌̇͆̀́́̊̿́́̎̀̇͛̌̊̆́̌͋̅͒͂͋͑̇͌͛̈́͌͗̀͂͑͂̄͐̿͌̈́̒̐̃̄̃͂͂͛̀͌̉̍͊͊͐̊̚͘̕̕̚̚̕̕͘̚̚̚͘͜͜͜͜͜͠͠͠͝͠͝͝͠͝͝͠͝͠͠ͅͅǎ̵̡̢̧̡̧̧̧̨̢̡̨̧̨̢̡̡̨̨̢̢̧̢̛̛̛̛̛̛̪̭͙̩̥͔̪̞̣̘̩͈͎̲̹͇̟̰̖͇̙̩̹̣͎̜͕̣̙͇̲̙͇̯̖̺̘͇̹̝̪̱̭͚̜̻̻̳̹͇̺̰̬̠̞͓̟̥̣͇̗̮͈̜͈̰̲͉̰̩̩̯̯̻̻̣͈͙̜̙͙̜̝̻̼̪̳͇̲̥̞͎͉͈̙̣͕̗̩̼͎̦̹͚̣̥̲͙̣̦̤̳̮̹͔̤̝̩̜̰̤̺͓̮͔͉̞͇̣̞̪̞̫̘̻̫͚̳̤̙̜̩̦͔̘̪̠̺̪̼̤̫͎͚̳̪̥̗̰͇̻̺͕̦͖͈̤̗̭̜͔̘̝͚͔̥̹̫̻̩͈̫͔͍̲̬̲̻̦̼̮̜͕̬͖̹͎͖̭̝͍͕͓̤͈̠̹̪̣̰̟̬̖͍͖͍̥̘̰̦͚̤̙͔͕̱͚̩̫̙̳̗̣̺͚̹̜͖͉̬͙͔̎̌̊͆̃̀͗͊̂̉͂̈̍̄̏͛̾͂̊̍͑̌͌̈́̈́͂̇̀̾̋̑͑̏̈́̅̐͑̑̂̈́̒͊̿̇̈́̅́̓̎̐͌̓̀̓̾͆̉̄̑̇̈̓̋́̿́̏̈́̽͗́͗̾̌̂͊̂̈́͛͂͆̈̒̂̂̔͂̓̈́͗͒̐̾͐͌̋̐͐́̋̎̃̀́̑̅̾̇͑̽́̄̃̉́͌͆́͗͑͐͛̉̓̓̌̈́̓̔̀̍̌̃͗͗͐̂͐͊̇̈́̆͑̓͋̀́̈́̾̂̔̈̑͊͑̍́̈͗̉̋͂̍̀̔̑͆̃̔͑̍̅̄̒͒̂̐̐̈̿̑͛̄̍̒̈́̔͋̈́̚̕͘̚͘͘̚̚̕̚̕͘̚̚̚͜͜͜͜͜͜͜͜͜͜͜͠͝͠͝͝͠͝͝͝͝͠͝͝͠͠͝ͅͅͅͅͅỳ̵̧̡̧̨̡̧̧̢̢̡̧̡̢̡̡̡̨̡̧̢̧̛͉͉͕̘̳̲͚̘͙̬͓͙͎̺̗̺̘̬̠̲̳͔̥͎̟̯̮̦̰̯͔͈̮̤̗͖̩̣̥̻̹̱̟͖̥̱̰̗͓͉̟̤̰̠͓̺̘͈̻͎̜͍̞̗̫̫̼̤̤̤̮̤̮̥̳̫̝̫̞̗̲̹͈̫̼̮̬̯̻̼̖̣̺̳͇̲̠̥̳͔͖͇̟̣̩̭̥͚̟̖̯̠̥͉̭̫̹̖͇̩͉̥͉͇̪̱̠͔̟̗̞͔̙͍̙͙̺̰̖͍̱̹̦̬̳̠͇̙͉͕̗̤͕̦̯̳̘̘̖̙̺̫̝͔̱̘͍͚͎͕͔͕̹̩̼̳̝̮̤͎̪͉̫̺̪̼̠̦͚͈̿͆͐̿̊͒͋̒͗̓̀̓̾̂̏̈̊̆̎̑͊̊̽͐̄̊͌̑̽̇͗̂̋̔́͒̄͆̈́͛̃̂̎͂̈́̋͋̎́̚͘̕̚͜͜͜͜͜͜͜͜͜͜ͅͅͅb̶̡̧̧̨̨̡̡̧̧̢̧̡̢̧̡̧̧̢̢̨̢̧̡̨̛͈̘͙͙̦̘̙̞͙͉͎̱̱̹̭͈̘͚̰̠͕̦̣͇͇̠̘̘̭͓̠̻͈̙͚͔̟͚̟̪̲͇̳̼̮̤̫͉̭̬̬̺̼̼͍͓͕̱͓̝͙̺̞̯̳̣̩̯̺̙͇̣̩̣͉͔͙̗̪̺͔͓͈̮̜̱̭̩̼͉̠̹͓͕̬̳̻̱̥̦̖̯̻͔̟̻̤̞̼͎͇̲̩̻̣̠̤͙̝͎̘͇͚̗̗̞͕̼͔̮͕̥̖̹̮͎̱͎̰͙͖̤͖̝̳͉͎̪̖̬̙̖̯̖̫̝͇̣̱̩̝̲̪̺̭͎͖̫͍̯̱̥̤̪̣̫͖̞̠̖̩̞̝̟͉̠̲̦̭͖͓͈̣̳̮̟͙̯͇̹̮͍̙̩̖͚̬̺͎̬̙̜̺̞͕͙͖̬̬̖͍̝͍͈̗̘̰̪͓̣̳̱̺͇̾͛̾̏͆̇̒̈̂͛̐̀̀͂̈̍̋́̌͑̌̿̂́̆͒͋͒͐̽̈́̐̒̀͐͂̈́̾̍̇́̾̚̚͜͜͜͜͜͝͝ͅͅͅͅͅͅͅͅͅͅͅͅͅě̴̡̧̨̡̨̨̡̢̡̢̛̛̛̛̥̗͈̘̬̙̺̥̞͔̹̱̬̙̹̠͖̙̫͈̖̳̪̙͙̼͎̮̗͙̹̙̯͈̞̲̩̮̞̠̲͔̝͓̥̟̮̪̘̥͕̠̲̯̫͓͍̻͎̠̞̟̤͓͍̥͙̙̯̯̮̳̹͍̼̪̗̀͒̾̋͌̀̀͗͂͌̏̄̓͗̓͐̔̏̓̅̾͂̓̂͌̌̉̂̍̽͌̓̓͛̔̓͂͒̂͋̅̾̀̍̅͑̇̽̋̔̉̑́͗̓̂̔̄̿̾̈́̀̓͑̈́͂̾̓́̈̎̇̿̈́͋̀̀͋̎̈̀̎̈́̏͐͌̄̀̈́̾̌́͗̀͊̒̑̾̐̈́̒̊̐̍̾̏́̇͌͑̔̇̿͋̃͒́̑̆̀́̑̏̎̄̃́̋̄͑͂̈́͆̆̓̏̋̒̀̑̑̀́̈́̿̑̑̓̃̆̇͆͛̽̑̍̅̔̊͊̅̀̅́̈́̎̑̈́̈̕̚͘̕̚͘̕͘̕̚̕̚̕̕͘͜͝͝͝͝͝͝͝͝͝͝͝͝͝͠͝͝ͅͅ)̸̨̡̨̨̢̧̢̡̧̡̧̨̡̡̛̛̛̛̛̛̛̛̺̪̱̬͇̣͇̬̟͇̖̣͎̙͕̯̫͈̫̘̦͖̹̱̼̮̟̯̙͚̮̲̖̬̲̗̩̩͉̯̘̻̙̞̳̝̜̝̙̳̱͙̲͚̞̫̝̜̭͙̘̟̱͈͎̹̪̰͓͈̹̩̜̘̱̦̮̲̰̻̜̭̗̘̣̙̳͖͍̦̣̙̜̯̙͎̥̯̹̣͎̲̙̲͖̻̺̲̪͙̗̻̱̰͕̳̤͖̝̫̦̣͍̮͍̺̻͚̮̙͉͙͚̜̥̭̠̘̫͎̜̯̺͎͖͖͇̪̼͈͙̰̖̜͇̼̣̝̮̮̺̝̬̫̮͎̩̘̭͈͔̞̤͇̥̤͕̄͌̏̾̉̍̔͑͑̔̔͑̀̎́̽̀͑̽̀̍̃̇̅͆̈́̈́́̌̂̐̇̎̍̀̆̏̓̈́̀̓͛̾͋̃͊̿̉̀̄̀̎̓̅̍͆͒̈̿̀̐̏̍̀́̔̇̑̏͗̽͂̑̆̌̎́̉̋̎̈́͗̑̊́̑̈́̒͊̀̀͋͂͒̔̃̋̋̊͗̉̈́͛͗̇̋̐̔͆́́́̈́̈́͂̎̏́͒̾͗͊̑̑̆͒̂̽͛̏́̊̑̄̍̈̈́̍̔̽͛̋́̒̓̀̋͐̓͌̅̿̍͂̎̈́̀̍̆͒̀́͒͂͊̌́̆̓̊̀͆̈́͗͛̓͒̑̓͐̋͌͑́͐͒̊̋̈͆̕͘̚̕̕͘̚̚̕̕̚̕̕͘͜͜͜͜͜͜͝͝͠͝͝͝͠͠͝͝͝͝͠͝͝͝͝͝ͅͅͅͅͅͅ
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
2023-11-13 10:25:57 -05:00
TheBrokenRail 0f9da6148b (Esimorp I) (Niaga) Dliub Xif Ot Tpmetta
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2023-11-13 01:41:52 -05:00
TheBrokenRail ea48728a68 Fix ARM Build
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2023-11-11 19:22:07 -05:00
TheBrokenRail 3e7037f621 Remove iconv
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2023-11-11 01:33:19 -05:00
TheBrokenRail 11230c120d Remove LibPNG + Clean Up 2023-11-11 00:44:26 -05:00
TheBrokenRail 1f05424651 Include Compiler Check In SDK 2023-11-09 18:41:10 -05:00
TheBrokenRail 98db527a13 Older CMake Compatibility
minecraft-pi-reborn/pipeline/head This commit looks good Details
Build / build (push) Has been cancelled Details
2023-10-21 19:27:22 -04:00
TheBrokenRail 85e04fbcc6 2.5.1
Build / build (push) Has been cancelled Details
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2023-10-21 16:36:54 -04:00
TheBrokenRail 018e506c80 Include More Dependencies
Build / build (push) Has been cancelled Details
minecraft-pi-reborn/pipeline/head This commit looks good Details
2023-10-19 21:50:39 -04:00
TheBrokenRail 945ce81fe1 Skip CI On Flatpak Tag
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
2023-10-19 21:14:52 -04:00
TheBrokenRail fab66319ea Merge pull request 'Update ARM GNU toolchain to version 12.3-rel1' (#64) from taylorthemushroom/minecraft-pi-reborn:master into master
Build / build (push) Has been cancelled Details
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
Reviewed-on: minecraft-pi-reborn/minecraft-pi-reborn#64
2023-10-19 21:13:00 -04:00
taylorthemushroom 99424546f8 Remove old toolchain URLs 2023-10-19 21:13:00 -04:00
taylorthemushroom cef22a5325 Oops
Forgot to update a few lines of code in the previous commit. Sorry!
2023-10-19 21:13:00 -04:00
taylorthemushroom 67ef365505 Rewrite asset file loading for new toolchain
Old implementation throws null dereference errors on new toolchain. New implementation has not been fully stress-tested but should be mostly operational.
2023-10-19 21:13:00 -04:00
taylorthemushroom 588eb5feb0 Update ARM GNU toolchain URLs and hope nothing breaks :) 2023-10-19 21:13:00 -04:00
TheBrokenRail c711c8b019 2.5.0
Build / build (push) Has been cancelled Details
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
2023-10-19 21:03:01 -04:00
TheBrokenRail 864c096785 Use Official Skin Server 2023-10-19 20:53:38 -04:00
TheBrokenRail 9ef0868889 Update Dependencies 2023-10-19 02:11:41 -04:00
TheBrokenRail 5b792fbf3a Add Feature Flag For Custom Skins 2023-10-19 01:56:09 -04:00
TheBrokenRail c908d46d54 Fix "Sleeping Beauty" Bug 2023-10-19 01:46:09 -04:00
TheBrokenRail db03d964de WIP Custom Skin Support 2023-10-19 01:23:34 -04:00
TheBrokenRail c0cd9b8b1f Nicer Release Formatting
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
Build / build (push) Successful in 1h36m19s Details
2023-09-21 12:57:59 -04:00
TheBrokenRail a8835153b0 CI Fix Attempt #2
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
Build / build (push) Successful in 1h36m49s Details
2023-09-21 00:25:47 -04:00
TheBrokenRail e1f2867d78 Attempt To Fix CI
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
Build / build (push) Successful in 1h37m45s Details
2023-09-20 22:34:19 -04:00
TheBrokenRail 7a5fef7024 Try Gitea Releases
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
Build / build (push) Failing after 1h37m8s Details
2023-09-20 20:54:07 -04:00
TheBrokenRail da9edee160 2.4.9
minecraft-pi-reborn/pipeline/head This commit looks good Details
Build / build (push) Successful in 2h38m15s Details
2023-09-17 15:53:34 -04:00
TheBrokenRail 9e517f5e60 The Return Of ES2 Support
minecraft-pi-reborn/pipeline/head This commit looks good Details
Build / build (push) Successful in 1h43m7s Details
2023-09-07 21:38:14 -04:00
TheBrokenRail 85e3cb6228 Fix CMake (Again) (Again)
Build / build (push) Successful in 2h44m8s Details
minecraft-pi-reborn/pipeline/head This commit looks good Details
2023-08-05 17:26:36 -04:00
TheBrokenRail 1dd0526197 Fix CMake (Again)
Build / build (push) Failing after 1h26m22s Details
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2023-08-05 01:42:47 -04:00
TheBrokenRail 7ecc6cb00b Fix CMake
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
Build / build (push) Failing after 1h10m4s Details
2023-08-04 23:32:25 -04:00
TheBrokenRail 4189f3fd1d Use Newer GLES Compatibility Layer
Build / build (push) Failing after 7m31s Details
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2023-08-04 22:52:30 -04:00
TheBrokenRail de18189b44 Fix Graphical Glitches On Some NVIDIA GPUs And Fix Crash When Taking Large Screenshots
Build / build (push) Failing after 7m24s Details
minecraft-pi-reborn/pipeline/head This commit looks good Details
2023-08-02 01:08:31 -04:00
TheBrokenRail a622858a18 Better Fog Shader
Build / build (push) Failing after 2h11m44s Details
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2023-06-12 19:14:37 -04:00
TheBrokenRail b005106b44 [Gitea Actions] Clone Submodules
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
Build / build (push) Failing after 1h33m17s Details
2023-06-04 00:58:26 -04:00
TheBrokenRail 61add936cc Fix Workflow Name
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
Build / build (push) Failing after 27m6s Details
2023-06-04 00:03:15 -04:00
TheBrokenRail d3b78acbef Gitea Actions Attempt #2
Build / check-and-test (push) Has been cancelled Details
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
2023-06-03 23:53:26 -04:00
TheBrokenRail 07a27d4dd9 Try Gitea Actions
Build / check-and-test (push) Failing after 20s Details
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
2023-06-03 23:48:28 -04:00
TheBrokenRail 6779905830 Reference New AUR Package
minecraft-pi-reborn/pipeline/head This commit looks good Details
2023-05-28 02:58:28 -04:00
TheBrokenRail c3fda82642 2.4.8
minecraft-pi-reborn/pipeline/head This commit looks good Details
2023-05-28 00:50:08 -04:00
TheBrokenRail e0ab968fa3 2.4.7
minecraft-pi-reborn/pipeline/head This commit looks good Details
2023-05-18 18:38:35 -04:00
TheBrokenRail 45b93534fa Revert "Add Night Vision"
This reverts commit 5273d6cdf9.
2023-02-25 19:36:35 -05:00
TheBrokenRail 5273d6cdf9 Add Night Vision 2023-02-25 04:05:20 -05:00
TheBrokenRail 06af8c821f Add Cave Generation 2023-02-25 00:26:45 -05:00
TheBrokenRail 7b4729b8ec Add Biome Colors To Grass 2023-02-24 19:53:41 -05:00
TheBrokenRail ffad36224e Improve Server Performance 2023-02-24 17:41:49 -05:00
TheBrokenRail 236f7e385d Update Dependencies
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-10-31 19:27:02 -04:00
TheBrokenRail f506b10051 Add Minecraft::handleBack Safety Check
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-10-20 23:58:40 -04:00
TheBrokenRail 9b4a9994ba 2.4.6
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-10-08 16:33:12 -04:00
TheBrokenRail 32cd0c426f Workaround GLFW Joystick Bugs 2022-10-08 16:27:04 -04:00
TheBrokenRail 5690df3ebe Formatting Tweaks 2022-10-08 16:27:04 -04:00
TheBrokenRail b4bebfb701 More Fixes 2022-10-08 16:27:04 -04:00
TheBrokenRail 1fa444f810 Fix Controls Documentation 2022-10-08 16:27:04 -04:00
TheBrokenRail f3dc145d4a Allow Opening Crafting With Controller 2022-10-08 16:27:03 -04:00
TheBrokenRail 5d65b4092f Move Code Around 2022-10-08 16:27:03 -04:00
TheBrokenRail 81aa01daf9 Fix Silly Typo 2022-10-08 16:27:03 -04:00
TheBrokenRail 2edfa62c25 Fix Holding Left-Click When Attacking 2022-10-08 16:26:57 -04:00
TheBrokenRail 4870afcc7f Document Controls 2022-10-02 01:23:46 -04:00
TheBrokenRail c178e5e5eb Logging Improvements 2022-10-02 00:47:11 -04:00
TheBrokenRail 57b0bce12c Fix For ARMHF 2022-10-01 19:29:11 -04:00
TheBrokenRail 95345a5f1b Minimal Controller Support + Input Fixes 2022-10-01 01:37:20 -04:00
TheBrokenRail 717b4a11a7 2.4.5
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-09-26 22:19:27 -04:00
TheBrokenRail 40a527bb23 Bundle QEMU 2022-09-26 20:59:46 -04:00
TheBrokenRail 2766611878 Small Fixes
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-09-25 20:56:45 -04:00
TheBrokenRail 8532e7707f 2.4.4
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-09-25 19:53:19 -04:00
TheBrokenRail 703ced337b Use File Locking 2022-09-25 19:35:51 -04:00
TheBrokenRail bedd5ea53a Replace PatcheLF With LIEF 2022-09-25 15:47:36 -04:00
TheBrokenRail eb3c5d2e6f Remove Unused File 2022-09-23 17:56:44 -04:00
TheBrokenRail ab1dbd2996 Update Docs 2022-09-23 17:55:38 -04:00
TheBrokenRail 29bc6faf3d Add Disable Creative Mode Mining Delay 2022-09-23 17:08:26 -04:00
TheBrokenRail 5aae95fd37 Add --wipe-cache 2022-09-23 00:31:42 -04:00
TheBrokenRail 5739c5f999 Add Disable Speed Bridging 2022-09-22 23:59:44 -04:00
TheBrokenRail 34ef2d51aa Small Fixes To The Launcher 2022-09-22 18:08:12 -04:00
TheBrokenRail f328800ce8 Cache Launcher Configuration 2022-09-22 17:43:21 -04:00
TheBrokenRail 02c73176a5 Fix Particles In Front-Facing View 2022-09-21 23:06:58 -04:00
TheBrokenRail 16ce586e9c Add Quit Button 2022-09-21 20:15:00 -04:00
TheBrokenRail 6378a18494 Add 3D Anaglyph To In-Game Options 2022-09-21 18:40:09 -04:00
TheBrokenRail 6994671c6d Add MCPI_API_PORT 2022-09-21 17:54:40 -04:00
TheBrokenRail 58f329bb4f Bug Fixes 2022-09-21 17:34:19 -04:00
TheBrokenRail d03a1a96ff Tweaks & Fixes 2022-09-20 18:25:27 -04:00
TheBrokenRail 35cafec1ee Tweaks
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-08-10 17:21:38 -04:00
TheBrokenRail 4ab6b7aed1 New GCC Is *Still* Broken
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-08-09 18:48:30 -04:00
TheBrokenRail edd346dd66 Stop Fighting CMake
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2022-08-09 18:39:34 -04:00
TheBrokenRail 0d9f498aa7 Fix ZLib In "git status" 2022-08-07 14:14:00 -04:00
TheBrokenRail d761ad8614 Better CMake
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-08-05 22:07:19 -04:00
TheBrokenRail 4977898bcd Use New Repos
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2022-08-05 20:37:11 -04:00
TheBrokenRail 513628d91f More CMake Tweaks
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2022-08-05 20:08:13 -04:00
TheBrokenRail 9a521ebca2 Remove Warnings From SDK
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-08-03 13:08:20 -04:00
TheBrokenRail deae36ed94 Better SDK Setup
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-08-01 19:56:35 -04:00
TheBrokenRail 00d6ee4f9a 2.4.3
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-08-01 18:41:08 -04:00
TheBrokenRail 8dd562a20f Fix Signs With CP-437 2022-07-30 23:52:50 -04:00
TheBrokenRail c11c7203ef 2.4.2
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-07-29 22:13:03 -04:00
TheBrokenRail 379da809cd 2.4.1
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-07-20 02:58:14 -04:00
TheBrokenRail 96baf9627a Actually Fix Screen Rendering When GUI is Hidden
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-07-16 00:02:51 -04:00
TheBrokenRail 279b101e46 Hotfix #2
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-07-15 23:20:31 -04:00
TheBrokenRail b190851d36 Hotfix
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-07-15 22:08:12 -04:00
TheBrokenRail c3c7d22006 Actually Fix CI
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-07-15 20:09:51 -04:00
TheBrokenRail 3abbb0cb16 Improve Server Dockerfile 2022-07-15 19:54:58 -04:00
TheBrokenRail dda511f8ff Fix CI (Again)
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2022-07-15 19:43:26 -04:00
TheBrokenRail 0ccc1ba6e8 Fix CI
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2022-07-15 19:05:59 -04:00
TheBrokenRail 9d3a0964b0 Fix CI Stage Name
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2022-07-15 17:54:43 -04:00
TheBrokenRail ed9bef8492 2.4.0
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
2022-07-15 17:27:21 -04:00
TheBrokenRail c4e26c5be2 Fix Classic HUD 2022-07-15 01:37:12 -04:00
TheBrokenRail 0c82db4116 Diable Broken Touchscreen-Specific Block Outline Behavior 2022-07-15 01:28:51 -04:00
TheBrokenRail ce168c1c16 Add Translucent Toolbar 2022-07-14 19:52:51 -04:00
TheBrokenRail 93eb7807aa Fix Attacking 2022-07-14 18:23:40 -04:00
TheBrokenRail 12074e15d9 Fix Sound 2022-07-14 18:11:44 -04:00
TheBrokenRail 010aaa89e3 Embed Feature Flag Data 2022-07-13 23:35:05 -04:00
TheBrokenRail 0e32fd36c8 Store Temporary Logs In Own Directory 2022-07-13 23:05:59 -04:00
TheBrokenRail 6c89e64f8b Add Classic HUD 2022-07-13 22:11:46 -04:00
TheBrokenRail 9fe6a2fb39 Remove Superfluous Mutexes 2022-07-13 19:32:08 -04:00
TheBrokenRail c87a6fa3c0 Improve Proxy Client 2022-07-13 17:02:18 -04:00
TheBrokenRail 69d3832815 Move Screenshot Code To ARM 2022-07-13 16:46:33 -04:00
TheBrokenRail 67002006f3 Vendor PatchELF 2022-07-13 11:58:35 -04:00
TheBrokenRail eb96d80e5a CMake Restructure 2022-07-11 23:51:27 -04:00
TheBrokenRail 968001897d Build Fixes + Don't Force EGL 2022-07-11 20:47:57 -04:00
TheBrokenRail 68519f06fd Add Buckets 2022-07-10 10:37:19 -04:00
TheBrokenRail b3b935dd1d Logging Changes 2022-07-08 22:40:56 -04:00
TheBrokenRail 006243d02f OpenAL Fixes 2022-07-08 15:00:01 -04:00
TheBrokenRail 3c1bce876c Run Benchmark During CI Test 2022-07-08 13:57:48 -04:00
TheBrokenRail 484d3e7f90 More Miscellaneous Fixes + Fixed GLES v1.1 Support 2022-07-08 00:25:01 -04:00
TheBrokenRail 23df63abb7 CMake Cleanup 2022-07-07 18:55:43 -04:00
TheBrokenRail 126c3d618d No More APT 2022-07-07 18:54:11 -04:00
TheBrokenRail 3937f88084 More Fixes 2022-07-07 00:37:53 -04:00
TheBrokenRail 4bd2fecfa2 Better package.sh 2022-07-04 16:51:56 -04:00
TheBrokenRail b539491713 Treat AppImages As Self-Mounting Tarballs 2022-07-04 16:44:00 -04:00
TheBrokenRail ea4c5c77a1 Cmake Refactor 2022-07-02 18:14:23 -04:00
TheBrokenRail e506dbb1bb GL Fixes 2022-06-30 19:53:32 -04:00
TheBrokenRail 699d83c61b Recipes API 2022-06-27 14:47:55 -04:00
TheBrokenRail 329f92c0a4 Fix Weird Shading 2022-06-26 22:01:31 -04:00
TheBrokenRail bfa0567ac9 Better Examples 2022-06-26 21:17:52 -04:00
TheBrokenRail a94708a1ae More Reliable Jenkins 2022-06-25 23:40:24 -04:00
TheBrokenRail 905a569c09 Better Flathub Badge 2022-06-25 23:38:29 -04:00
TheBrokenRail 53f602403a Cache Blacklist/Whitelist 2022-06-25 23:32:31 -04:00
TheBrokenRail 2f64552926 Fix SDK Bugs 2022-06-25 23:03:46 -04:00
TheBrokenRail 2b920f50ba Improve Example Mod README 2022-06-25 17:49:09 -04:00
TheBrokenRail d859a16b5a Initial SDK Support 2022-06-25 17:30:08 -04:00
TheBrokenRail 78e17d8c18 Block Running As Root
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-06-24 20:37:52 -04:00
TheBrokenRail 0e7a108a0a Improve Build
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-06-13 22:53:43 -04:00
TheBrokenRail ca21877000 Ditch FreeImage
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-06-13 20:49:09 -04:00
TheBrokenRail f1ec29ec86 Build Tweak
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-06-12 16:23:32 -04:00
TheBrokenRail 13ac816baa Fix Invalid AppStream XML
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-06-10 23:49:15 -04:00
TheBrokenRail 6ba86b9193 Tiny Docker Fix
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-06-10 22:02:43 -04:00
TheBrokenRail 49f8da2a80 Fix Build
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
2022-06-10 21:59:57 -04:00
TheBrokenRail e8faee62fa Improve AppStream
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2022-06-09 23:23:37 -04:00
TheBrokenRail a8ff58f0c4 Update Dependency Installation 2022-06-09 23:10:29 -04:00
TheBrokenRail daccf65361 Improve Metadata 2022-06-09 21:31:40 -04:00
TheBrokenRail 3d508d7609 2.3.13
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-06-05 16:14:03 -04:00
TheBrokenRail 0061edb3b2 2.3.12
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-06-04 14:36:47 -04:00
TheBrokenRail baeeceeaac Slightly Faster 2022-06-04 14:34:15 -04:00
TheBrokenRail 211bf265ff Optimizations & Fixes 2022-06-03 22:25:22 -04:00
TheBrokenRail 0dd0706f52 2.3.11
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-29 22:54:57 -04:00
TheBrokenRail 1743626113 Sweeping Media Layer Changes (GL ES 2.0 Support) 2022-05-29 18:44:27 -04:00
TheBrokenRail 4ed11b67e7 Add Front-Facing View 2022-05-17 18:31:25 -04:00
TheBrokenRail 365e238c29 Small Fix
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-16 18:56:19 -04:00
TheBrokenRail 36c4ed7e4d Fix Stupid Mistake
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-15 15:16:45 -04:00
TheBrokenRail cf1faf4835 Better Exit Code Messages
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-15 13:51:28 -04:00
TheBrokenRail cb4560a602 Don't Require MCPI_DEBUG For Command Errors
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2022-05-15 00:53:46 -04:00
TheBrokenRail b3a96dc3e2 2.3.10
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-14 00:16:25 -04:00
TheBrokenRail be300a2809 Fix Zenity On Wayland 2022-05-13 23:27:06 -04:00
TheBrokenRail 77d7b82a14 Add Crash Report Dialog 2022-05-13 22:36:12 -04:00
TheBrokenRail b59c580f6a Fix Build On Ubuntu 22.04 & Bug Fixes
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-11 18:24:03 -04:00
TheBrokenRail 524a390921 Use Debian Sid As AppImage And ARMHF Sysroot Base
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-04 20:47:15 -04:00
TheBrokenRail ead7e575f3 Allow Specifying Custom Sysroot
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-03 21:08:56 -04:00
TheBrokenRail f2a9b274d2 Cleanup Sysroot Sources
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-03 17:29:10 -04:00
TheBrokenRail dd4972172d Fix In-Source Build
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-03 17:27:52 -04:00
TheBrokenRail 8822a22987 Re-Run CMake On Version Change
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-02 22:52:52 -04:00
TheBrokenRail 53cb68beee 2.3.9
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-02 22:46:53 -04:00
TheBrokenRail 47ae13ac51 Bundle An ARM Sysroot 2022-05-02 22:44:10 -04:00
TheBrokenRail 492725ed63 Colored Logs 2022-05-02 20:43:52 -04:00
TheBrokenRail 7c2d0d5625 2.3.8: Switch Up Mod Loading Order
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-05-01 00:25:29 -04:00
TheBrokenRail 9449cdf747 Fix Bad Comment
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-04-30 23:29:29 -04:00
TheBrokenRail d95a9e1871 Update Changelog Formatting
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-04-30 22:34:52 -04:00
TheBrokenRail 8a83702c3c 2.3.7
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-04-28 20:54:00 -04:00
TheBrokenRail be7e44fd3c Update GLFW
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-04-28 17:00:11 -04:00
TheBrokenRail 651c49980e 2.3.6
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-04-27 23:43:13 -04:00
TheBrokenRail 46a53ba3cf New Create World Dialog 2022-04-27 23:38:30 -04:00
TheBrokenRail 186728ca5f Small Tweaks 2022-04-24 22:30:35 -04:00
TheBrokenRail 9412c07c45 Fix ARM Check
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-04-24 18:56:21 -04:00
TheBrokenRail 2717e062b3 Replace LINK_FLAGS With LINK_OPTIONS
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-04-24 17:56:21 -04:00
TheBrokenRail 0723fb1894 Improve Docs
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-04-23 23:01:52 -04:00
TheBrokenRail 16f919d147 2.3.5
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-04-23 21:19:53 -04:00
TheBrokenRail e18fc9fc63 Simplify 2022-04-23 21:10:44 -04:00
TheBrokenRail 3ebdffd396 Fixes 2022-04-23 18:49:08 -04:00
TheBrokenRail 82b6252927 Classic UI By Default! 2022-04-23 16:46:40 -04:00
TheBrokenRail 4a35935daf Add Improved Title Background 2022-04-22 19:38:15 -04:00
TheBrokenRail 89c29f14b1 More AppImage Fixes
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-04-20 18:21:29 -04:00
TheBrokenRail 4edfaeead4 More Fixes 2022-04-16 16:38:09 -04:00
TheBrokenRail bfcdd3c7e9 AppImage Fixes 2022-04-14 21:12:42 -04:00
TheBrokenRail 5467b5178f Fix LD_PRELOAD 2022-04-13 20:59:47 -04:00
TheBrokenRail 8f49c550ba 2.3.4 2022-04-12 22:08:27 -04:00
TheBrokenRail 50eb4801a0 Revert Earlier Username Decision 2022-04-12 20:38:44 -04:00
TheBrokenRail a3eef9fc3b Add "Fix Pause Menu" 2022-04-11 22:52:38 -04:00
TheBrokenRail f455780833 Add "Force Touch Inventory" 2022-04-11 19:59:21 -04:00
TheBrokenRail 0150879d2b Fix Options Button On Classic UI 2022-04-11 18:48:43 -04:00
TheBrokenRail 623cf06516 Fix Options Screen 2022-04-10 22:41:47 -04:00
TheBrokenRail 0b1849a9ad Make Death Messages Customizable Server-Side 2022-04-09 20:06:44 -04:00
TheBrokenRail 157d51e6b6 Improve feature_has 2022-04-09 20:01:16 -04:00
TheBrokenRail ed58356dd8 Fix Q Behavior 2022-04-02 19:25:03 -04:00
TheBrokenRail fae728061a Update Screenshot
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-28 17:29:28 -04:00
TheBrokenRail 353565ce5a Hide Server Desktop Entry
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-27 23:24:42 -04:00
TheBrokenRail efa21bc8a5 Fix AppStream
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-27 16:42:24 -04:00
TheBrokenRail 61f9a329ea 2.3.3
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-27 16:21:58 -04:00
TheBrokenRail 3c0c260920 Add Smooth Stone Slab
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-25 22:40:13 -04:00
TheBrokenRail 0592db9bdf 2.3.2
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-25 21:20:34 -04:00
TheBrokenRail 3fee57ce60 Fix Missing Comment 2022-03-25 21:09:29 -04:00
TheBrokenRail b3c32b211b Add Grass To Expanded Creative Inventory 2022-03-25 21:07:28 -04:00
TheBrokenRail ea92e5188e Add Nether Reactor Stages To Expanded Creative Inventory 2022-03-25 00:35:06 -04:00
TheBrokenRail 9a4b70b5ca Improve Temporary File Improving 2022-03-24 23:03:59 -04:00
TheBrokenRail b5974f3f46 Simplify Launch Process 2022-03-24 22:47:34 -04:00
TheBrokenRail 709de17558 Fix Nether Reactor With Creative Restrictions Disabled 2022-03-23 19:26:49 -04:00
TheBrokenRail 3894e98a04 2022! 2022-03-18 23:56:27 -04:00
TheBrokenRail bf890d190b Sort Feature Flags 2022-03-16 19:51:45 -04:00
TheBrokenRail a40da62b70 Speedup run_command 2022-03-16 19:51:33 -04:00
TheBrokenRail 59b8fd9f54 Make iterate_text_sections MCPI-Agnostic 2022-03-16 19:50:46 -04:00
TheBrokenRail 55a815643b Add "Disable V-Sync" Feature Flag 2022-03-16 19:49:13 -04:00
TheBrokenRail aa471fb4ba Update Zenity 2022-03-16 19:48:37 -04:00
TheBrokenRail 4c33b6da9a 2.3.1 Final
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-14 21:51:38 -04:00
TheBrokenRail 3048b3bf50 Load Custom Mods First
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-14 20:49:56 -04:00
TheBrokenRail 03312f44b6 2.3.1
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-14 19:09:25 -04:00
TheBrokenRail bdeb45eed2 Hardcode ldconfig Path
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-13 17:13:50 -04:00
TheBrokenRail 9f63fa712f Fix ARM32 Support
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-12 22:52:58 -05:00
TheBrokenRail e319d46ea0 Update Changelog
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-11 23:19:24 -05:00
TheBrokenRail c88cbd151e Shallow Submodules Just Break Things
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-11 21:38:46 -05:00
TheBrokenRail 46abc4c4bd Fix Jenkins
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-03-11 20:39:00 -05:00
TheBrokenRail 00f8ed4752 2.3.0
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2022-03-11 20:34:50 -05:00
TheBrokenRail 0fd8ba7de9 Improve AppImages & Safer OpenAL 2022-03-11 20:02:38 -05:00
TheBrokenRail 07baea7b5a Vendor Zenity For AppImages 2022-03-11 00:00:13 -05:00
TheBrokenRail 8792e5749d Remove Broken WebKit Exclusion 2022-03-10 21:05:33 -05:00
TheBrokenRail 53b2c20b8b Fix More AppImage Bugs 2022-03-09 23:29:37 -05:00
TheBrokenRail 244a69d1aa Move CI Dockerfile 2022-03-09 22:54:30 -05:00
TheBrokenRail a1f777f632 Add MCPI_DEBUG & Improve Documentation 2022-03-09 22:40:21 -05:00
TheBrokenRail 5d8a1e4230 Small Debug Fixes 2022-03-09 22:08:47 -05:00
TheBrokenRail 742ead51e1 Vendor GLFW 2022-03-09 21:23:41 -05:00
TheBrokenRail c33a27b2ea AppImage! 2022-03-09 18:47:31 -05:00
TheBrokenRail c1377d4f2a Add "Disable Hosting LAN Worlds" 2022-03-07 17:03:03 -05:00
TheBrokenRail e0ebc7fc32 Fix Furnace Not Checking Item Auxiliary 2022-03-06 22:43:42 -05:00
TheBrokenRail 0fcda17120 (Hopefully) Improve CI Speed 2022-03-06 20:46:18 -05:00
TheBrokenRail e9e9b90bdb Use Ninja 2022-03-06 20:13:41 -05:00
TheBrokenRail 0fd562af40 Allow Disabling Raw Mouse Motion 2022-03-06 20:07:49 -05:00
TheBrokenRail 1eb06b6b60 Add Back ~/.minecraft-pi/mods & Fix Segmentation Fault With Media Layer Proxy 2022-03-06 18:22:28 -05:00
TheBrokenRail c6983ac6c5 Improve Build System + Use GCC (Clang Is Just Too Broken) 2022-03-06 15:53:27 -05:00
TheBrokenRail 4a69d38e35 Add "Close Current Screen On Death"
minecraft-pi-reborn/pipeline/head This commit looks good Details
2022-01-02 15:26:56 -05:00
TheBrokenRail 5636abc051 Fix More Furnace UI 2022-01-01 19:04:58 -05:00
TheBrokenRail 33c7d025a5 2.2.10
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-12-29 21:12:49 -05:00
TheBrokenRail 7f7bc08201 Update Image
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-12-22 14:05:05 -05:00
TheBrokenRail b36df1d8ff Improve Handling When MCPI-Reborn Directory != MCPI Directory
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-12-19 18:24:59 -05:00
TheBrokenRail bf58129164 Extended ASCII Is A Myth Perpetuated By ASCII Table Manufacturers
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-12-19 17:17:34 -05:00
TheBrokenRail 654c719187 Add MCPI_OPEN_SOURCE_ONLY Build Option
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-12-19 16:09:16 -05:00
TheBrokenRail e1e2977c29 Move Icon To Incorrect Place That Everyone Checks
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-12-18 16:51:40 -05:00
TheBrokenRail a85fc1f5fa Fix CI Build
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-12-18 16:29:35 -05:00
TheBrokenRail e3a4cabf61 Stop Using Static QEMU
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-12-17 21:04:05 -05:00
TheBrokenRail 4c3fefae89 Fix Symlink
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-12-17 20:01:29 -05:00
TheBrokenRail 729eff232a Move Icon Again...
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-12-17 19:37:52 -05:00
TheBrokenRail 560c040416 Fix Desktop File
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-12-17 19:22:03 -05:00
TheBrokenRail ea49470450 No More /opt
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-12-17 19:07:58 -05:00
TheBrokenRail 5a5fe4c731 Fix CMake
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-12-17 18:19:23 -05:00
TheBrokenRail 406aa3f9a6 Stuff Learned From Legacy
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-30 21:54:43 -05:00
TheBrokenRail 55679dd54c Fix Small Bug
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-30 21:58:44 +00:00
TheBrokenRail dbee357ebc Fix More Size Data
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-29 22:54:40 +00:00
TheBrokenRail bc461d39d5 Fix More Size Info
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-28 23:02:34 +00:00
TheBrokenRail 21de7487bb Fix Size Data
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-28 21:42:26 +00:00
TheBrokenRail 7ad36d0ce1 Finally Make Server STDIN Code Not Suck As Much
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-20 23:09:25 -05:00
TheBrokenRail d17416421a Remove Useless Code
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-15 20:14:11 -05:00
TheBrokenRail 154adea292 Add Eating To Removed Creative Restrictions
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-14 17:28:20 -05:00
TheBrokenRail 291e560c8f Last Minute 2.2.8 Fix
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-14 13:37:51 -05:00
TheBrokenRail 472f5d67a5 2.2.8
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-13 23:29:48 -05:00
TheBrokenRail a79a601c59 Use -ffast-math
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-12 17:12:37 -05:00
TheBrokenRail e85231bf69 Fix ARMHF Output Path
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-12 05:04:11 +00:00
TheBrokenRail da0aef568d Fix CI Test
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-11 22:52:47 -05:00
TheBrokenRail f8b7af1370 Fix CI Again
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-11-11 22:27:10 -05:00
TheBrokenRail 6a7d881258 Fix CI
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-11-11 21:37:29 -05:00
TheBrokenRail 2e9ee42d75 Fix ZLib Includes
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-11-11 20:37:43 -05:00
TheBrokenRail 941572063e Revert To Binary Packaging
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-11-11 20:12:16 -05:00
TheBrokenRail 43d27e8e11 Fix Build Dependencies
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-10 22:52:33 -05:00
TheBrokenRail 7e3cfaa1a8 Update Build Dependencies
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
2021-11-10 22:48:41 -05:00
TheBrokenRail 320e0c652a Add Missing File
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-10 22:37:29 -05:00
TheBrokenRail e5fc2a61aa Revamp Packaging
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-11-10 22:17:04 -05:00
TheBrokenRail 5cf4d7f915 Small Cleanup 2021-11-09 16:26:02 -05:00
TheBrokenRail 51d7974ded Fix Typo
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-06 22:40:11 -04:00
TheBrokenRail 16ebea9ed6 Even More Symbols
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-11-02 17:50:26 -04:00
TheBrokenRail 05587efc04 Fix CMake
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-10-28 22:57:47 -04:00
TheBrokenRail 9ad6cc3906 Add Tile Symbols
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-10-28 19:21:07 -04:00
TheBrokenRail 12de038f37 Improve Patch Comment 2021-10-27 18:14:30 -04:00
TheBrokenRail 1daede7dba Fix ARM Toolchain On Some Devices
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-10-22 22:39:26 -04:00
TheBrokenRail 28a6d59c2d Fix Build Better
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-10-22 18:36:09 -04:00
TheBrokenRail f2bd893241 Fix Build (Finally)
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-10-22 17:28:26 -04:00
TheBrokenRail 28424aa86a Faster Build
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-10-12 16:13:11 -04:00
TheBrokenRail 637f1c1132 2.2.7
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-10-12 16:01:07 -04:00
TheBrokenRail 74d14ecaa6 Small Optimization
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-10-07 16:54:47 -04:00
TheBrokenRail f3eaa57041 Fix Symbol Name
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-10-04 19:46:51 -04:00
TheBrokenRail 015235b889 Clean Up
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-10-04 19:42:55 -04:00
TheBrokenRail 8c356dd65c Update README Image
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-30 20:28:37 -04:00
TheBrokenRail 6a9a22ac25 Fix Bug In Texture Scaling Code
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-30 19:37:24 -04:00
TheBrokenRail c45211ad22 Improve Changelog Formatting
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-28 16:03:56 -04:00
TheBrokenRail 7498c1e932 Scale Animated Textures
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-28 14:04:05 -04:00
TheBrokenRail 734bded289 Add Note To Building Docs
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-21 22:21:53 -04:00
TheBrokenRail b7b130e675 Fix Building Documentation
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-21 22:15:04 -04:00
TheBrokenRail 0a65c91d14 Fix Cross-Compilation Toolchain (Again)
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-20 23:16:09 -04:00
TheBrokenRail 55475a3a0c Fix Cross-Compilation Toolchain
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-20 22:47:33 -04:00
TheBrokenRail f9acb08e4f Document Server Docker Image
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-19 15:44:13 -04:00
TheBrokenRail db64afc550 Improve Build System
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-16 22:00:40 -04:00
TheBrokenRail 0465dc75a7 Instead Of Crashing, Disable Polling Block Hits In Survival Mode Using The API
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-16 16:39:24 -04:00
TheBrokenRail 68a252c3df Fix Crash When Taking Odd-Sized Screenshots
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-15 19:12:03 -04:00
TheBrokenRail 866ebfe159 Don't Cache GCC Version
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-14 19:29:48 -04:00
TheBrokenRail 1f3036c7e1 Improve Clang Toolchain (Again)
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-09-14 19:04:39 -04:00
TheBrokenRail a338c11f9d Improve Clang Toolchain
minecraft-pi-reborn/pipeline/head Something is wrong with the build of this commit Details
2021-09-14 19:02:50 -04:00
TheBrokenRail 647a482fbd Build Using Clang
minecraft-pi-reborn/pipeline/head There was a failure building this commit Details
2021-09-14 18:39:23 -04:00
TheBrokenRail 6c791d6c9d Add More Missing Sound Events
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-13 17:09:57 -04:00
TheBrokenRail d18afddf1b Prevent random.burp Sound From Crashing Game
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-12 16:41:10 -04:00
TheBrokenRail d851a8f3e1 2.2.0
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-09-12 00:08:01 -04:00
TheBrokenRail a762654e35 Split Headless And Server Mode Code
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-08-26 23:05:26 -04:00
TheBrokenRail 4aeb2fd95b RIP Debian Buster, You Won't Be Missed
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-08-26 20:33:01 -04:00
TheBrokenRail c60fb51fae Move ServerLevel To minecraft.h
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-08-24 17:21:38 -04:00
TheBrokenRail 4597e824bb Split Off "Allow Joining Survival Servers" From Game-Mode Mod
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-08-23 18:33:50 -04:00
TheBrokenRail d372169c79 Clean Up Some Code, No Noticeable Difference
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-08-21 23:00:12 -04:00
TheBrokenRail 99b709fea7 Fix Crash On ARM Systems
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-08-15 23:11:03 -04:00
TheBrokenRail 578bb1c89f Fix On 64-Bit ARM Systems
minecraft-pi-reborn/pipeline/head This commit looks good Details
2021-08-05 21:00:41 -04:00
482 changed files with 15559 additions and 4890 deletions

122
.gitea/workflows/build.yml Normal file
View File

@ -0,0 +1,122 @@
name: 'CI'
on:
push:
branches:
- master
tags:
- '*'
- '!flatpak'
jobs:
# Build Project
build:
strategy:
fail-fast: false
matrix:
mode:
- Client
- Server
arch:
- AMD64
- ARM64
- ARMHF
name: Build
runs-on: ubuntu-latest
container: node:lts-bullseye
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: true
# Dependencies
- name: Install Dependencies
run: ./scripts/install-dependencies.sh ${{ matrix.arch }}
# Build
- name: Build
run: ./scripts/build.mjs appimage ${{ matrix.mode }} ${{ matrix.arch }}
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.mode }} (${{ matrix.arch }})
path: ./out/*.AppImage*
if-no-files-found: error
# Test Project
test:
strategy:
fail-fast: false
matrix:
mode:
- Client
- Server
name: Test
runs-on: ubuntu-latest
container: node:lts-bullseye
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: true
# Dependencies
- name: Install Dependencies
run: ./scripts/install-dependencies.sh
# Test
- name: Test
run: ./scripts/test.sh ${{ matrix.mode }}
# Example Mods
example-mods:
name: Build Example Mods
runs-on: ubuntu-latest
container: node:lts-bullseye
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: true
# Dependencies
- name: Install Dependencies
run: ./scripts/install-dependencies.sh
- name: Install ARM Toolchain
run: apt-get install --no-install-recommends -y g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf
# Build SDK
- name: Build SDK
run: |
./scripts/build.mjs none client host
export _MCPI_SKIP_ROOT_CHECK=1
export DISPLAY=
./out/client/host/usr/bin/minecraft-pi-reborn-client --copy-sdk
# Build Example Mods
- name: Build Example Mods
run: ./example-mods/build.sh
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: Example Mods
path: ./example-mods/out/*
if-no-files-found: error
# Create Release
release:
if: startsWith(github.ref, 'refs/tags/')
needs: build
name: Release
runs-on: ubuntu-latest
container: node:lts-bullseye
steps:
# Dependencies
- name: Install Go
uses: actions/setup-go@v4
with:
go-version: '>=1.20.1'
# Download Artifacts
- name: Download Artifacts
uses: actions/download-artifact@v3
with:
path: out
# Create Release
- name: Create Release
uses: https://gitea.com/actions/release-action@main
with:
files: ./out/*/*.AppImage*
api_key: ${{ secrets.RELEASE_TOKEN }}
title: v${{ github.ref_name }}
body: "[View Changelog](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/src/branch/master/docs/CHANGELOG.md)"

14
.gitignore vendored
View File

@ -1,6 +1,18 @@
/out
/debian/tmp
/.vscode
/build
/build*
/CMakeLists.txt.user
*.autosave
/AppImageBuilder.yml
/appimage-builder-cache
/appimage-build
/AppDir
/*.zsync
/*.AppImage
/core*
/qemu_*
/example-mods/out
/.testing-tmp
/cmake-build-*
/.idea

24
.gitmodules vendored Normal file
View File

@ -0,0 +1,24 @@
[submodule "dependencies/glfw/src"]
path = dependencies/glfw/src
url = https://github.com/glfw/glfw.git
[submodule "dependencies/zenity/src"]
path = dependencies/zenity/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/zenity.git
[submodule "dependencies/LIEF/src"]
path = dependencies/LIEF/src
url = https://github.com/lief-project/LIEF.git
[submodule "media-layer/core/gles/dependencies/gles-compatibility-layer"]
path = dependencies/gles-compatibility-layer/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/gles-compatibility-layer.git
[submodule "dependencies/stb_image/include"]
path = dependencies/stb_image/include
url = https://github.com/nothings/stb.git
[submodule "dependencies/utf8cpp/src"]
path = dependencies/utf8cpp/src
url = https://github.com/nemtrif/utfcpp.git
[submodule "archives"]
path = archives
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/archives.git
[submodule "dependencies/symbol-processor/src"]
path = dependencies/symbol-processor/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/symbol-processor.git

View File

@ -1,104 +1,97 @@
cmake_minimum_required(VERSION 3.13.0)
cmake_minimum_required(VERSION 3.17.0)
# Specify Options
option(MCPI_USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" FALSE)
option(MCPI_SERVER_MODE "Server Mode" FALSE)
set(MCPI_BUILD_MODE "both" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code; \"both\" = Build All Code As ARM")
set_property(CACHE MCPI_BUILD_MODE PROPERTY STRINGS "both" "arm" "native")
# Configure Build Mode
if(MCPI_BUILD_MODE STREQUAL "arm")
set(USE_ARM32_TOOLCHAIN TRUE)
set(BUILD_ARM_COMPONENTS TRUE)
set(BUILD_NATIVE_COMPONENTS FALSE)
elseif(MCPI_BUILD_MODE STREQUAL "native")
set(USE_ARM32_TOOLCHAIN FALSE)
set(BUILD_ARM_COMPONENTS FALSE)
set(BUILD_NATIVE_COMPONENTS TRUE)
elseif(MCPI_BUILD_MODE STREQUAL "both")
set(USE_ARM32_TOOLCHAIN TRUE)
set(BUILD_ARM_COMPONENTS TRUE)
set(BUILD_NATIVE_COMPONENTS TRUE)
else()
message(FATAL_ERROR "Invalid Mode")
# Avoid Warning About DOWNLOAD_EXTRACT_TIMESTAMP
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24.0)
cmake_policy(SET CMP0135 NEW)
endif()
# Use Clang By Default
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
if(NOT DEFINED CMAKE_C_COMPILER)
set(CMAKE_C_COMPILER clang)
endif()
if(NOT DEFINED CMAKE_CXX_COMPILER)
set(CMAKE_CXX_COMPILER clang++)
endif()
endif()
# Core Options
include(cmake/options/core-options.cmake)
# Setup ARM Cross Compilation
if(USE_ARM32_TOOLCHAIN)
include(cmake/arm-toolchain.cmake)
endif()
# Use LLD When Using Clang
if(CMAKE_C_COMPILER STREQUAL "clang")
add_link_options("-fuse-ld=lld")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld") # Fix try_compile()
endif()
# Utility Functions
include(cmake/util.cmake)
# Specify Variant Name
set(MCPI_VARIANT_NAME "minecraft-pi-reborn")
if(MCPI_SERVER_MODE)
set(MCPI_VARIANT_NAME "${MCPI_VARIANT_NAME}-server")
else()
set(MCPI_VARIANT_NAME "${MCPI_VARIANT_NAME}-client")
endif()
# Specify Installation Paths
set(MCPI_INSTALL_DIR "opt/${MCPI_VARIANT_NAME}")
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
set(MCPI_FALLBACK_LIB_DIR "${MCPI_INSTALL_DIR}/fallback-lib")
# Optimizations
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_compile_options(-O3)
else()
add_compile_options(-g)
add_definitions(-DDEBUG)
# Build Mode
if(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
endif()
# Start Project
project(minecraft-pi-reborn)
# Specify Default Installation Prefix
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "/" CACHE PATH "" FORCE)
endif()
# Utility Functions
include(cmake/util/util.cmake)
# Buld LibPNG + ZLib + Download Minecraft: Pi Edition
# Sanity Checks
string(CONCAT ARM_SANITY_CHECK
"include(CheckSymbolExists)\n"
"check_symbol_exists(\"__arm__\" \"\" IS_ARM_TARGETING)"
)
if(BUILD_ARM_COMPONENTS)
add_subdirectory(dependencies)
string(CONCAT ARM_SANITY_CHECK
"${ARM_SANITY_CHECK}\n"
"if(NOT IS_ARM_TARGETING)\n"
" message(FATAL_ERROR \"ARM-Targeting Compiler Required\")\n"
"endif()"
)
endif()
cmake_language(EVAL CODE "${ARM_SANITY_CHECK}")
# Extra Options
include(cmake/options/extra-options.cmake)
# Paths
include(cmake/options/paths.cmake)
# Required Compile Flags
string(CONCAT COMPILE_FLAGS_SETUP
# Optimizations
"if(CMAKE_BUILD_TYPE STREQUAL \"Release\")\n"
" add_compile_options(-O3)\n"
" add_link_options(-s)\n"
"else()\n"
" add_compile_options(-g)\n"
"endif()\n"
# PIC
"set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)\n"
# Warnings
"add_link_options(-Wl,--no-undefined)\n"
# C Standard
"add_definitions(-D_GNU_SOURCE)\n"
"set(CMAKE_C_STANDARD 99)\n"
"set(CMAKE_CXX_STANDARD 11)\n"
# Skip RPath
"set(CMAKE_SKIP_BUILD_RPATH TRUE)"
)
cmake_language(EVAL CODE "${COMPILE_FLAGS_SETUP}")
# Fast Math
add_compile_options(-ffast-math)
# Warnings
add_compile_options(-Wall -Wextra -Werror -Wpointer-arith -Wshadow -Wnull-dereference)
add_link_options(-Wl,--no-undefined)
add_definitions(-D_GNU_SOURCE)
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 11)
# Specify Constants
if(MCPI_SERVER_MODE)
add_definitions(-DMCPI_SERVER_MODE)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
# Prevents False Positives
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 10.0)
add_compile_options(-Wno-stringop-overflow)
endif()
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 11.0)
add_compile_options(-Wno-array-bounds -Wno-stringop-overread)
endif()
endif()
# Buld Dependencies
add_subdirectory(dependencies)
# Version
file(STRINGS VERSION VERSION)
add_definitions(-DVERSION="${VERSION}")
set_property(
DIRECTORY
APPEND
PROPERTY CMAKE_CONFIGURE_DEPENDS VERSION
)
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" MCPI_VERSION)
file(TIMESTAMP "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" MCPI_VERSION_DATE "%Y-%m-%d" UTC)
# Build libreborn
add_subdirectory(libreborn)
@ -111,7 +104,79 @@ if(BUILD_NATIVE_COMPONENTS)
add_subdirectory(launcher)
endif()
# Include Symbols
if(BUILD_ARM_COMPONENTS)
add_subdirectory(symbols)
endif()
# Build Mods
if(BUILD_ARM_COMPONENTS)
add_subdirectory(mods)
endif()
# Include Images
if(BUILD_NATIVE_COMPONENTS)
add_subdirectory(images)
endif()
# Install Prebuilt ARMHF Toolchain Sysroot
if(BUILD_ARM_COMPONENTS AND MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
install_arm_sysroot()
endif()
# Install SDK
if(BUILD_ARM_COMPONENTS)
install(EXPORT sdk DESTINATION "${MCPI_SDK_DIR}" FILE "sdk-targets.cmake" EXPORT_LINK_INTERFACE_LIBRARIES)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake"
# Compile Flags
"${COMPILE_FLAGS_SETUP}\n"
# Snaity Check
"${ARM_SANITY_CHECK}\n"
# Log
"message(STATUS \"Using Reborn SDK v${MCPI_VERSION}\")\n"
# Include Targets
"include(\"\${CMAKE_CURRENT_LIST_DIR}/sdk-targets.cmake\")\n"
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake" DESTINATION "${MCPI_SDK_DIR}")
endif()
# Packaging
if(BUILD_NATIVE_COMPONENTS)
include(cmake/cpack/packaging.cmake)
endif()
# Superbuild
if(BUILD_NATIVE_COMPONENTS)
include(ExternalProject)
# Arguments
set(ARM_OPTIONS "${MCPI_OPTIONS}")
list(APPEND ARM_OPTIONS "-DMCPI_BUILD_MODE:STRING=arm")
list(APPEND ARM_OPTIONS "-DCMAKE_INSTALL_MESSAGE:STRING=NEVER")
list(APPEND ARM_OPTIONS "-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>/install")
if(NOT MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
if(DEFINED CMAKE_TOOLCHAIN_FILE)
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_TOOLCHAIN_FILE}")
endif()
else()
list(APPEND ARM_OPTIONS "-DMCPI_USE_PREBUILT_ARMHF_TOOLCHAIN:BOOL=TRUE")
endif()
list(APPEND ARM_OPTIONS "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}")
# Build
ExternalProject_Add(arm-components
DOWNLOAD_COMMAND ""
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
CMAKE_CACHE_ARGS ${ARM_OPTIONS}
INSTALL_COMMAND "${CMAKE_COMMAND}" "-E" "rm" "-rf" "<INSTALL_DIR>/install"
COMMAND
"${CMAKE_COMMAND}" "-E" "env"
"DESTDIR="
"${CMAKE_COMMAND}" "--install" "<BINARY_DIR>"
USES_TERMINAL_CONFIGURE TRUE
USES_TERMINAL_BUILD TRUE
USES_TERMINAL_INSTALL TRUE
BUILD_ALWAYS TRUE
)
# Install
ExternalProject_Get_Property(arm-components INSTALL_DIR)
install(DIRECTORY "${INSTALL_DIR}/install/${MCPI_INSTALL_DIR}/" DESTINATION "${MCPI_INSTALL_DIR}")
endif()

View File

@ -1,21 +1,19 @@
FROM debian:bullseye
# Copy DEB
ADD ./out/minecraft-pi-reborn-server_*~bullseye_amd64.deb /root
FROM debian:bullseye-slim
# Install
RUN \
apt-get update && \
apt-get install -y tini && \
(dpkg -i /root/*.deb || :) && \
apt-get install -y tini qemu-user && \
apt-get --fix-broken install -y && \
rm -f /root/*.deb && \
rm -rf /var/lib/apt/lists/*
# Copy
ADD ./out/server-amd64 /app
# Setup Working Directory
RUN mkdir /data
WORKDIR /data
# Setup Entrypoint
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["minecraft-pi-reborn-server"]
CMD ["/app/usr/bin/minecraft-pi-reborn-server"]

54
Jenkinsfile vendored
View File

@ -1,54 +0,0 @@
pipeline {
agent none
stages {
stage('Debian Bullseye') {
agent {
docker {
image 'debian:bullseye'
args '-v /var/run/docker.sock:/var/run/docker.sock'
}
}
stages {
stage('Build') {
steps {
sh './scripts/ci/run.sh'
}
post {
success {
archiveArtifacts artifacts: 'out/*.deb', fingerprint: true
}
}
}
stage('Publish') {
steps {
sh 'apt-get update && apt-get install -y docker.io'
sh 'docker build --no-cache --tag thebrokenrail/minecraft-pi-reborn-server .'
withCredentials([usernamePassword(credentialsId: 'docker_hub_login', usernameVariable: 'DOCKER_HUB_USERNAME', passwordVariable: 'DOCKER_HUB_PASSWORD')]) {
sh 'docker login -u "${DOCKER_HUB_USERNAME}" -p "${DOCKER_HUB_PASSWORD}"'
}
sh 'docker push thebrokenrail/minecraft-pi-reborn-server'
}
}
}
}
stage('Debian Buster') {
agent {
docker {
image 'debian:buster'
}
}
stages {
stage('Build') {
steps {
sh './scripts/ci/run.sh'
}
post {
success {
archiveArtifacts artifacts: 'out/*.deb', fingerprint: true
}
}
}
}
}
}
}

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2021 TheBrokenRail
Copyright (c) 2024 TheBrokenRail
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1 +1 @@
2.1.6
3.0.0

1
archives Submodule

@ -0,0 +1 @@
Subproject commit 37d4baec5874b39e10cafda2f9fcf6b63129c85a

View File

@ -1,13 +0,0 @@
# Compile For ARM
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64_be" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "armv8b" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "armv8l")
# Force 32-Bit Compile
add_compile_options("-m32")
elseif(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "arm")
# Use ARM Cross-Compiler
set(TARGET "arm-linux-gnueabihf")
set(CMAKE_C_COMPILER "${TARGET}-gcc")
set(CMAKE_CXX_COMPILER "${TARGET}-g++")
set(CMAKE_FIND_ROOT_PATH "/usr/${TARGET}" "/usr/lib/${TARGET}")
endif()
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "arm")

View File

@ -1,10 +0,0 @@
# Compile For ARM64
if(NOT (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64_be" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "armv8b" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "armv8l"))
# Use ARM64 Cross-Compiler
set(TARGET "aarch64-linux-gnu")
set(CMAKE_C_COMPILER "${TARGET}-gcc")
set(CMAKE_CXX_COMPILER "${TARGET}-g++")
set(CMAKE_FIND_ROOT_PATH "/usr/${TARGET}" "/usr/lib/${TARGET}")
endif()
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "aarch64")

View File

@ -0,0 +1,62 @@
# Downlaod AppImage Runtime
set(RUNTIME_ARCH "unknown")
if(CPACK_MCPI_ARCH STREQUAL "armhf")
set(RUNTIME_ARCH "armhf")
elseif(CPACK_MCPI_ARCH STREQUAL "arm64")
set(RUNTIME_ARCH "aarch64")
elseif(CPACK_MCPI_ARCH STREQUAL "amd64")
set(RUNTIME_ARCH "x86_64")
endif()
set(RUNTIME "${CPACK_TOPLEVEL_DIRECTORY}/runtime")
file(DOWNLOAD
"https://github.com/AppImage/AppImageKit/releases/download/continuous/runtime-${RUNTIME_ARCH}"
"${RUNTIME}"
STATUS DOWNLOAD_STATUS
)
list(GET DOWNLOAD_STATUS 0 STATUS_CODE)
list(GET DOWNLOAD_STATUS 1 ERROR_MESSAGE)
if(NOT STATUS_CODE EQUAL 0)
message(FATAL_ERROR "Unable To Downlopad AppImage Runtime: ${ERROR_MESSAGE}")
else()
message(STATUS "Downloaded AppImage Runtime: ${RUNTIME}")
endif()
# Package
set(APPIMAGE_ARCH "unknown")
if(CPACK_MCPI_ARCH STREQUAL "armhf")
set(APPIMAGE_ARCH "arm")
elseif(CPACK_MCPI_ARCH STREQUAL "arm64")
set(APPIMAGE_ARCH "arm_aarch64")
elseif(CPACK_MCPI_ARCH STREQUAL "amd64")
set(APPIMAGE_ARCH "x86_64")
endif()
execute_process(
COMMAND
"${CMAKE_COMMAND}" "-E" "env"
"ARCH=${APPIMAGE_ARCH}"
"appimagetool"
"--updateinformation" "zsync|https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases/download/latest/${CPACK_PACKAGE_FILE_NAME_ZSYNC}.AppImage.zsync"
"--runtime-file" "${RUNTIME}"
"--comp" "xz"
"${CPACK_TEMPORARY_DIRECTORY}"
"${CPACK_PACKAGE_FILE_NAME}.AppImage"
WORKING_DIRECTORY "${CPACK_PACKAGE_DIRECTORY}"
RESULT_VARIABLE APPIMAGETOOL_RESULT
)
if(NOT APPIMAGETOOL_RESULT EQUAL 0)
message(FATAL_ERROR "Unable Package AppImage")
endif()
# Rename ZSync File
file(RENAME "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}.AppImage.zsync" "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME_ZSYNC}.AppImage.zsync")
# Summary Message
function(check_file name)
if(EXISTS "${CPACK_PACKAGE_DIRECTORY}/${name}")
message(STATUS "Generated: ${name}")
else()
message(FATAL_ERROR "Missing File: ${name}")
endif()
endfunction()
check_file("${CPACK_PACKAGE_FILE_NAME}.AppImage")
check_file("${CPACK_PACKAGE_FILE_NAME_ZSYNC}.AppImage.zsync")

View File

@ -0,0 +1,38 @@
# Determine Architecture
set(CPACK_MCPI_ARCH "unknown")
include(CheckSymbolExists)
function(check_arch symbol name)
set(CMAKE_REQUIRED_QUIET TRUE)
check_symbol_exists("${symbol}" "" "IS_ARCH_${name}")
unset(CMAKE_REQUIRED_QUIET)
if("${IS_ARCH_${name}}")
set(CPACK_MCPI_ARCH "${name}" PARENT_SCOPE)
endif()
endfunction()
check_arch("__arm__" "armhf")
check_arch("__aarch64__" "arm64")
check_arch("__x86_64__" "amd64")
# CPack
set(CPACK_PACKAGE_NAME "${MCPI_VARIANT_NAME}")
set(CPACK_PACKAGE_VENDOR "TheBrokenRail & Mojang AB")
set(CPACK_VERBATIM_VARIABLES TRUE)
set(CPACK_MONOLITHIC_INSTALL TRUE)
set(CPACK_PACKAGE_FILE_NAME "${MCPI_VARIANT_NAME}-${MCPI_VERSION}-${CPACK_MCPI_ARCH}")
set(CPACK_PACKAGE_FILE_NAME_ZSYNC "${MCPI_VARIANT_NAME}-latest-${CPACK_MCPI_ARCH}")
# Version
string(REPLACE "." ";" VERSION_LIST "${MCPI_VERSION}")
list(GET VERSION_LIST 0 CPACK_PACKAGE_VERSION_MAJOR)
list(GET VERSION_LIST 1 CPACK_PACKAGE_VERSION_MINOR)
list(GET VERSION_LIST 2 CPACK_PACKAGE_VERSION_PATCH)
# AppImage
if(MCPI_IS_APPIMAGE_BUILD)
set(CPACK_GENERATOR "External")
set(CPACK_EXTERNAL_ENABLE_STAGING TRUE)
set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/appimage.cmake")
endif()
# Package
include(CPack)

View File

@ -0,0 +1,29 @@
# Build Mode
set(MCPI_BUILD_MODE "native" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code")
set_property(CACHE MCPI_BUILD_MODE PROPERTY STRINGS "arm" "native")
if(MCPI_BUILD_MODE STREQUAL "arm")
set(BUILD_ARM_COMPONENTS TRUE)
set(BUILD_NATIVE_COMPONENTS FALSE)
elseif(MCPI_BUILD_MODE STREQUAL "native")
set(BUILD_ARM_COMPONENTS FALSE)
set(BUILD_NATIVE_COMPONENTS TRUE)
else()
message(FATAL_ERROR "Invalid Mode")
endif()
# Specify Options
set(MCPI_OPTIONS "")
function(mcpi_option name description type default)
set(full_name "MCPI_${name}")
set("${full_name}" "${default}" CACHE "${type}" "${description}")
list(APPEND MCPI_OPTIONS "-D${full_name}:${type}=${${full_name}}")
set(MCPI_OPTIONS "${MCPI_OPTIONS}" PARENT_SCOPE)
endfunction()
# Prebuilt ARMHF Toolchain
if(BUILD_ARM_COMPONENTS)
mcpi_option(USE_PREBUILT_ARMHF_TOOLCHAIN "Whether To Use A Prebuilt ARMHF Toolchain For Building ARM Components" BOOL FALSE)
if(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
include("${CMAKE_CURRENT_LIST_DIR}/prebuilt-armhf-toolchain.cmake")
endif()
endif()

View File

@ -0,0 +1,76 @@
# Specify Options
mcpi_option(OPEN_SOURCE_ONLY "Only Install Open-Source Code (Will Result In Broken Install)" BOOL FALSE)
mcpi_option(IS_APPIMAGE_BUILD "AppImage Build" BOOL FALSE)
mcpi_option(IS_FLATPAK_BUILD "Flatpak Build" BOOL FALSE)
if(MCPI_IS_APPIMAGE_BUILD AND MCPI_IS_FLATPAK_BUILD)
message(FATAL_ERROR "Invalid Build Configuration")
endif()
# Server/Headless Builds
mcpi_option(SERVER_MODE "Server Mode" BOOL FALSE)
mcpi_option(HEADLESS_MODE "Headless Mode" BOOL "${MCPI_SERVER_MODE}")
# Prebuilt ARMHF Toolchain
if(BUILD_NATIVE_COMPONENTS)
set(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN FALSE)
if(NOT IS_ARM_TARGETING)
set(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN TRUE)
endif()
endif()
# Media Layer
if(NOT MCPI_HEADLESS_MODE)
set(DEFAULT_USE_MEDIA_LAYER_PROXY FALSE)
if(BUILD_NATIVE_COMPONENTS AND NOT IS_ARM_TARGETING)
set(DEFAULT_USE_MEDIA_LAYER_PROXY TRUE)
endif()
mcpi_option(USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" BOOL "${DEFAULT_USE_MEDIA_LAYER_PROXY}")
mcpi_option(USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" BOOL TRUE)
else()
set(MCPI_USE_MEDIA_LAYER_PROXY FALSE)
endif()
if(MCPI_USE_MEDIA_LAYER_PROXY)
set(BUILD_MEDIA_LAYER_CORE "${BUILD_NATIVE_COMPONENTS}")
else()
set(BUILD_MEDIA_LAYER_CORE "${BUILD_ARM_COMPONENTS}")
endif()
# Specify Variant Name
set(MCPI_VARIANT_NAME "minecraft-pi-reborn")
if(MCPI_SERVER_MODE)
string(APPEND MCPI_VARIANT_NAME "-server")
else()
string(APPEND MCPI_VARIANT_NAME "-client")
endif()
# App ID
set(DEFAULT_APP_ID "com.thebrokenrail.MCPIReborn")
if(MCPI_SERVER_MODE)
string(APPEND DEFAULT_APP_ID "Server")
else()
string(APPEND DEFAULT_APP_ID "Client")
endif()
set(MCPI_APP_ID "${DEFAULT_APP_ID}" CACHE STRING "App ID")
# App Title
mcpi_option(APP_BASE_TITLE "Base App Title" STRING "Minecraft: Pi Edition: Reborn")
set(DEFAULT_APP_TITLE "${MCPI_APP_BASE_TITLE}")
if(MCPI_SERVER_MODE)
string(APPEND DEFAULT_APP_TITLE " (Server)")
else()
string(APPEND DEFAULT_APP_TITLE " (Client)")
endif()
mcpi_option(APP_TITLE "App Title" STRING "${DEFAULT_APP_TITLE}")
# Skin Server
mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data")
# QEMU
if(BUILD_NATIVE_COMPONENTS)
include(CheckSymbolExists)
check_symbol_exists("__ARM_ARCH" "" MCPI_IS_ARM32_OR_ARM64_TARGETING)
set(MCPI_USE_QEMU TRUE)
if(MCPI_IS_ARM32_OR_ARM64_TARGETING)
set(MCPI_USE_QEMU FALSE)
endif()
endif()

33
cmake/options/paths.cmake Normal file
View File

@ -0,0 +1,33 @@
# Specify Installation Paths
set(MCPI_INSTALL_DIR "lib/${MCPI_VARIANT_NAME}")
set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin")
set(MCPI_LEGAL_DIR "${MCPI_INSTALL_DIR}/legal") # For Software Licenses
set(MCPI_SDK_DIR "${MCPI_INSTALL_DIR}/sdk")
set(MCPI_SDK_LIB_DIR "${MCPI_SDK_DIR}/lib")
set(MCPI_SDK_INCLUDE_DIR "${MCPI_SDK_DIR}/include")
# Library Directory
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
if(BUILD_ARM_COMPONENTS)
string(APPEND MCPI_LIB_DIR "/arm")
elseif(BUILD_NATIVE_COMPONENTS)
string(APPEND MCPI_LIB_DIR "/native")
endif()
# Share Directory
set(MCPI_SHARE_DIR "share")
if(MCPI_IS_APPIMAGE_BUILD)
string(PREPEND MCPI_SHARE_DIR "usr/")
endif()
# Specify Default Installation Prefix
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(DEFAULT_PREFIX "/usr")
if(MCPI_IS_APPIMAGE_BUILD)
set(DEFAULT_PREFIX "/")
elseif(MCPI_IS_FLATPAK_BUILD)
set(DEFAULT_PREFIX "/app")
endif()
set(CMAKE_INSTALL_PREFIX "${DEFAULT_PREFIX}" CACHE PATH "" FORCE)
set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT FALSE)
endif()

View File

@ -0,0 +1,70 @@
# Pick Archive
set(toolchain_version "13.2.rel1")
execute_process(COMMAND uname -m OUTPUT_VARIABLE arch OUTPUT_STRIP_TRAILING_WHITESPACE)
if(arch STREQUAL "x86_64")
set(toolchain_file "arm-gnu-toolchain-${toolchain_version}-x86_64-arm-none-linux-gnueabihf.tar.xz")
elseif(arch STREQUAL "aarch64" OR arch STREQUAL "armv8b" OR arch STREQUAL "armv8l")
set(toolchain_file "arm-gnu-toolchain-${toolchain_version}-aarch64-arm-none-linux-gnueabihf.tar.xz")
else()
message(FATAL_ERROR "Unable To Download Prebuilt ARMHF Toolchain")
endif()
# Download If Needed
include(FetchContent)
FetchContent_Declare(
prebuilt-armhf-toolchain
URL "${CMAKE_CURRENT_LIST_DIR}/../../archives/${toolchain_file}"
)
FetchContent_MakeAvailable(prebuilt-armhf-toolchain)
set(toolchain_dir "${prebuilt-armhf-toolchain_SOURCE_DIR}")
# Force Toolchain
file(WRITE "${toolchain_dir}/toolchain.cmake"
"set(CMAKE_C_COMPILER \"\${CMAKE_CURRENT_LIST_DIR}/bin/arm-none-linux-gnueabihf-gcc\")\n"
"set(CMAKE_CXX_COMPILER \"\${CMAKE_CURRENT_LIST_DIR}/bin/arm-none-linux-gnueabihf-g++\")\n"
"set(CMAKE_SYSTEM_NAME \"Linux\")\n"
"set(CMAKE_SYSTEM_PROCESSOR \"arm\")\n"
"set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\n"
)
set(CMAKE_TOOLCHAIN_FILE "${toolchain_dir}/toolchain.cmake" CACHE FILEPATH "" FORCE)
# Build Sysroot
set(sysroot_dir "${CMAKE_CURRENT_BINARY_DIR}/bundled-armhf-sysroot")
if("${toolchain_dir}/bin/arm-none-linux-gnueabihf-gcc" IS_NEWER_THAN "${sysroot_dir}")
# Create Directory
file(REMOVE_RECURSE "${sysroot_dir}")
file(MAKE_DIRECTORY "${sysroot_dir}")
# Copy Files From Toolchain
file(
COPY "${toolchain_dir}/arm-none-linux-gnueabihf/libc/"
DESTINATION "${sysroot_dir}"
USE_SOURCE_PERMISSIONS
FILES_MATCHING
PATTERN "*.so*"
)
# Delete Unneeded Files
file(REMOVE_RECURSE "${sysroot_dir}/usr/lib/audit")
file(REMOVE_RECURSE "${sysroot_dir}/usr/lib/gconv")
# Strip Files
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE "${sysroot_dir}/*")
foreach(file IN LISTS files)
execute_process(COMMAND "${toolchain_dir}/bin/arm-none-linux-gnueabihf-strip" "${file}" RESULT_VARIABLE ret)
# Check Result
if(NOT ret EQUAL 0)
# Delete Invalid Files
file(REMOVE "${file}")
endif()
endforeach()
endif()
# Install Sysroot (Skipping Empty Directories)
function(install_arm_sysroot)
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE RELATIVE "${sysroot_dir}" "${sysroot_dir}/*")
foreach(file IN LISTS files)
get_filename_component(parent "${file}" DIRECTORY)
install(PROGRAMS "${sysroot_dir}/${file}" DESTINATION "${MCPI_INSTALL_DIR}/sysroot/${parent}")
endforeach()
endfunction()

View File

@ -0,0 +1,7 @@
# Compile For x86_64
include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake")
# Use x86_64 Cross-Compiler
setup_toolchain("x86_64-linux-gnu")
# Details
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "x86_64")

View File

@ -0,0 +1,7 @@
# Compile For ARM64
include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake")
# Use ARM64 Cross-Compiler
setup_toolchain("aarch64-linux-gnu")
# Details
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "aarch64")

View File

@ -0,0 +1,7 @@
# Compile For ARM
include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake")
# Use ARM Cross-Compiler
setup_toolchain("arm-linux-gnueabihf")
# Details
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "arm")

View File

@ -0,0 +1,37 @@
# Setup Toolchain
macro(setup_toolchain target)
# Target Variants
set(target_variants "${target}")
macro(add_target_variant value)
string(REPLACE "-linux" "-${value}-linux" target_variant "${target}")
list(APPEND target_variants "${target_variant}")
endmacro()
add_target_variant(unknown)
add_target_variant(none)
add_target_variant(pc)
# Find Compiler
macro(find_compiler output name)
set(possible_names "")
foreach(possible_target IN LISTS target_variants)
list(APPEND possible_names "${possible_target}-${name}")
endforeach()
find_program(
"${output}"
NAMES ${possible_names}
NO_CACHE
)
if("${${output}}" STREQUAL "${output}-NOTFOUND")
message(FATAL_ERROR "Unable To Find ${name}")
endif()
endmacro()
find_compiler(CMAKE_C_COMPILER "gcc")
find_compiler(CMAKE_CXX_COMPILER "g++")
# Extra
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Custom Search Paths
set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}" "/usr")
# pkg-config
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/${target}/pkgconfig:/usr/${target}/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig")
endmacro()

View File

@ -1,20 +0,0 @@
# Symlink Function
function(install_symlink target link)
install(CODE "\
# Prepare\n \
set(file \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${link}\")\n \
\
# Create Directory\n \
get_filename_component(dir \"\${file}\" DIRECTORY)\n \
file(MAKE_DIRECTORY \${dir})\n \
\
# Create Symlink\n \
if(NOT EXISTS \"\${file}\")\n \
execute_process(COMMAND \${CMAKE_COMMAND} -E create_symlink ${target} \"\${file}\")\n \
message(\"-- Installing: \${file}\")\n \
else()\n \
message(\"-- Up-to-date: \${file}\")\n \
endif() \
")
endfunction()

View File

@ -0,0 +1,12 @@
# Read Hex Data
file(READ "${EMBED_IN}" data HEX)
# Convert Hex Data For C Compatibility
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," data "${data}")
# Get C Name
get_filename_component(name "${EMBED_IN}" NAME)
string(MAKE_C_IDENTIFIER "${name}" name)
# Write Data
file(WRITE "${EMBED_OUT}" "#include <stddef.h>\nconst unsigned char ${name}[] = {${data}};\nconst size_t ${name}_len = sizeof (${name});\n")

33
cmake/util/util.cmake Normal file
View File

@ -0,0 +1,33 @@
# Symlink Function
function(install_symlink target link)
get_filename_component(parent "${link}" DIRECTORY)
if(parent STREQUAL "")
set(parent ".")
endif()
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/symlink/${parent}")
file(CREATE_LINK "${target}" "${CMAKE_BINARY_DIR}/symlink/${link}" SYMBOLIC)
install(FILES "${CMAKE_BINARY_DIR}/symlink/${link}" DESTINATION "${parent}")
endfunction()
# Embed Resources
set(util_list_dir "${CMAKE_CURRENT_LIST_DIR}")
function(embed_resource target file)
# Get C Name
get_filename_component(name "${file}" NAME)
string(MAKE_C_IDENTIFIER "${name}" name)
# Add Command
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${name}.c"
COMMAND "${CMAKE_COMMAND}"
ARGS "-DEMBED_IN=${CMAKE_CURRENT_SOURCE_DIR}/${file}" "-DEMBED_OUT=${CMAKE_CURRENT_BINARY_DIR}/${name}.c" "-P" "${util_list_dir}/embed-resource.cmake"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${file}" "${util_list_dir}/embed-resource.cmake"
)
# Add To Target
target_sources("${target}" PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
endfunction()
# Nicer Output
function(message log_level)
if((NOT MESSAGE_QUIET) OR (NOT (log_level STREQUAL "STATUS" OR log_level MATCHES "^CHECK_")))
_message("${log_level}" ${ARGN})
endif()
endfunction()

7
debian/client-arm vendored
View File

@ -1,7 +0,0 @@
Package: minecraft-pi-reborn-client
Version: ${VERSION}
Maintainer: TheBrokenRail <connor24nolan@live.com>
Description: Fun with Blocks
Homepage: https://www.minecraft.net/en-us/edition/pi
Architecture: armhf
Depends: zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3

7
debian/client-arm64 vendored
View File

@ -1,7 +0,0 @@
Package: minecraft-pi-reborn-client
Version: ${VERSION}
Maintainer: TheBrokenRail <connor24nolan@live.com>
Description: Fun with Blocks
Homepage: https://www.minecraft.net/en-us/edition/pi
Architecture: arm64
Depends: zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3, libc6-armhf-cross, libstdc++6-armhf-cross

View File

@ -1,7 +0,0 @@
Package: minecraft-pi-reborn-client
Version: ${VERSION}
Maintainer: TheBrokenRail <connor24nolan@live.com>
Description: Fun with Blocks
Homepage: https://www.minecraft.net/en-us/edition/pi
Architecture: amd64
Depends: zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3, libc6-armhf-cross, libstdc++6-armhf-cross, qemu-user-static

6
debian/server-arm vendored
View File

@ -1,6 +0,0 @@
Package: minecraft-pi-reborn-server
Version: ${VERSION}
Maintainer: TheBrokenRail <connor24nolan@live.com>
Description: Fun with Blocks
Homepage: https://www.minecraft.net/en-us/edition/pi
Architecture: armhf

7
debian/server-arm64 vendored
View File

@ -1,7 +0,0 @@
Package: minecraft-pi-reborn-server
Version: ${VERSION}
Maintainer: TheBrokenRail <connor24nolan@live.com>
Description: Fun with Blocks
Homepage: https://www.minecraft.net/en-us/edition/pi
Architecture: arm64
Depends: libc6-armhf-cross, libstdc++6-armhf-cross

View File

@ -1,7 +0,0 @@
Package: minecraft-pi-reborn-server
Version: ${VERSION}
Maintainer: TheBrokenRail <connor24nolan@live.com>
Description: Fun with Blocks
Homepage: https://www.minecraft.net/en-us/edition/pi
Architecture: amd64
Depends: libc6-armhf-cross, libstdc++6-armhf-cross, qemu-user-static

View File

@ -1,8 +1,36 @@
project(dependencies)
# ZLib
add_subdirectory(zlib)
# LibPNG
add_subdirectory(libpng)
# stb_image
if(BUILD_ARM_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
add_subdirectory(stb_image)
endif()
# Minecraft: Pi Edition
add_subdirectory(minecraft-pi)
if(BUILD_ARM_COMPONENTS AND NOT MCPI_OPEN_SOURCE_ONLY)
add_subdirectory(minecraft-pi)
endif()
# Zenity (Minimal Build)
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_SERVER_MODE)
add_subdirectory(zenity)
endif()
# LIEF
if(BUILD_NATIVE_COMPONENTS OR (BUILD_MEDIA_LAYER_CORE AND NOT MCPI_HEADLESS_MODE))
add_subdirectory(LIEF)
endif()
# QEMU
if(BUILD_NATIVE_COMPONENTS AND MCPI_USE_QEMU)
add_subdirectory(qemu)
endif()
# GLFW
if(BUILD_MEDIA_LAYER_CORE AND NOT MCPI_HEADLESS_MODE)
add_subdirectory(glfw)
endif()
# GLES Compatibility Layer
if(BUILD_MEDIA_LAYER_CORE AND NOT MCPI_HEADLESS_MODE AND MCPI_USE_GLES1_COMPATIBILITY_LAYER)
add_subdirectory(gles-compatibility-layer)
endif()
# UTF8-CPP
add_subdirectory(utf8cpp)
# Symbol Prcoessor
if(BUILD_ARM_COMPONENTS)
add_subdirectory(symbol-processor)
endif()

38
dependencies/LIEF/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,38 @@
project(LIEF)
# Silence Warnings
add_compile_options(-w -Wno-psabi)
## LIEF
# Options
set(BUILD_SHARED_LIBS TRUE CACHE BOOL "" FORCE)
set(LIEF_C_API FALSE CACHE BOOL "" FORCE)
set(LIEF_EXAMPLES FALSE CACHE BOOL "" FORCE)
set(LIEF_PYTHON_API FALSE CACHE BOOL "" FORCE)
set(LIEF_TESTS FALSE CACHE BOOL "" FORCE)
set(LIEF_USE_CCACHE FALSE CACHE BOOL "" FORCE)
set(LIEF_LOGGING FALSE CACHE BOOL "" FORCE)
set(LIEF_LOGGING_DEBUG FALSE CACHE BOOL "" FORCE)
set(LIEF_ENABLE_JSON FALSE CACHE BOOL "" FORCE)
set(LIEF_ELF TRUE CACHE BOOL "" FORCE)
set(LIEF_PE FALSE CACHE BOOL "" FORCE)
set(LIEF_MACHO FALSE CACHE BOOL "" FORCE)
set(LIEF_DEX FALSE CACHE BOOL "" FORCE)
set(LIEF_ART FALSE CACHE BOOL "" FORCE)
set(LIEF_OAT FALSE CACHE BOOL "" FORCE)
set(LIEF_VDEX FALSE CACHE BOOL "" FORCE)
# Download
set(MESSAGE_QUIET TRUE)
add_subdirectory(src EXCLUDE_FROM_ALL)
unset(MESSAGE_QUIET)
# Install
install(TARGETS LIB_LIEF DESTINATION "${MCPI_LIB_DIR}")
if(BUILD_ARM_COMPONENTS)
install(TARGETS LIB_LIEF EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
endif()
# License
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/LIEF")

1
dependencies/LIEF/src vendored Submodule

@ -0,0 +1 @@
Subproject commit 16962f2f36a51b2acefad9cec3622f6de5730aa3

View File

@ -0,0 +1,7 @@
project(gles-compatibility-layer)
# GLES Compatibility Layer
set(GLES_COMPATIBILITY_LAYER_USE_ES3 FALSE CACHE BOOL "" FORCE)
set(GLES_COMPATIBILITY_LAYER_USE_SDL FALSE CACHE BOOL "" FORCE)
set(GLES_COMPATIBILITY_LAYER_DEPENDENCY glfw CACHE STRING "" FORCE)
add_subdirectory(src)

@ -0,0 +1 @@
Subproject commit 67a8d026aa5aef062dae654d418c3cd09417c0c1

27
dependencies/glfw/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,27 @@
project(glfw)
# Silence Warnings
add_compile_options(-w)
## GLFW
# Download
set(BUILD_SHARED_LIBS TRUE CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES FALSE CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS FALSE CACHE BOOL "" FORCE)
set(GLFW_BUILD_DOCS FALSE CACHE BOOL "" FORCE)
set(GLFW_INSTALL FALSE CACHE BOOL "" FORCE)
set(GLFW_BUILD_WIN32 FALSE CACHE BOOL "" FORCE)
set(GLFW_BUILD_COCOA FALSE CACHE BOOL "" FORCE)
set(GLFW_BUILD_X11 TRUE CACHE BOOL "" FORCE)
set(GLFW_BUILD_WAYLAND TRUE CACHE BOOL "" FORCE)
set(GLFW_LIBRARY_TYPE "SHARED" CACHE BOOL "" FORCE)
set(MESSAGE_QUIET TRUE)
add_subdirectory(src EXCLUDE_FROM_ALL)
unset(MESSAGE_QUIET)
# Install
install(TARGETS glfw DESTINATION "${MCPI_LIB_DIR}")
# License
install(FILES src/LICENSE.md DESTINATION "${MCPI_LEGAL_DIR}/glfw")

1
dependencies/glfw/src vendored Submodule

@ -0,0 +1 @@
Subproject commit 7b6aead9fb88b3623e3b3725ebb42670cbe4c579

View File

@ -1,28 +0,0 @@
project(libpng)
include(FetchContent)
# Silence Warnings
add_compile_options(-w)
## LibPNG
# Download
set(SKIP_INSTALL_ALL TRUE) # Skip Default LibPNG Installation
FetchContent_Declare(
libpng
GIT_REPOSITORY "https://git.code.sf.net/p/libpng/code"
GIT_TAG "v1.2.59"
)
FetchContent_Populate(libpng)
set(ZLIB_LIBRARY zlib)
set(ZLIB_INCLUDE_DIR "${zlib_SOURCE_DIR}" "${zlib_BINARY_DIR}")
set(CMAKE_POLICY_DEFAULT_CMP0054 OLD) # Silence Warning
add_subdirectory("${libpng_SOURCE_DIR}" "${libpng_BINARY_DIR}")
set(CMAKE_POLICY_DEFAULT_CMP0054 NEW) # Re-Enable New Behavior
set_target_properties(png12 PROPERTIES LINK_FLAGS "-Wl,--version-script='${CMAKE_CURRENT_SOURCE_DIR}/libpng.vers'") # Use Symbol Versioning
set_target_properties(png12 PROPERTIES DEBUG_POSTFIX "") # Fix LibPNG Suffix In Debug Mode
# Install
install(TARGETS png12 DESTINATION "${MCPI_LIB_DIR}")

View File

@ -1,208 +0,0 @@
PNG12_0 {global:
png_libpng_ver;
png_pass_start;
png_pass_inc;
png_pass_ystart;
png_pass_yinc;
png_pass_mask;
png_pass_dsp_mask;
png_access_version_number;
png_set_sig_bytes;
png_sig_cmp;
png_check_sig;
png_create_read_struct;
png_create_write_struct;
png_get_compression_buffer_size;
png_set_compression_buffer_size;
png_reset_zstream;
png_create_read_struct_2;
png_create_write_struct_2;
png_write_chunk;
png_write_chunk_start;
png_write_chunk_data;
png_write_chunk_end;
png_create_info_struct;
png_info_init;
png_info_init_3;
png_write_info_before_PLTE;
png_write_info;
png_read_info;
png_convert_to_rfc1123;
png_convert_from_struct_tm;
png_convert_from_time_t;
png_set_expand;
png_set_expand_gray_1_2_4_to_8;
png_set_palette_to_rgb;
png_set_tRNS_to_alpha;
png_set_gray_1_2_4_to_8;
png_set_bgr;
png_set_gray_to_rgb;
png_set_rgb_to_gray;
png_set_rgb_to_gray_fixed;
png_get_rgb_to_gray_status;
png_build_grayscale_palette;
png_set_strip_alpha;
png_set_swap_alpha;
png_set_invert_alpha;
png_set_filler;
png_set_add_alpha;
png_set_swap;
png_set_packing;
png_set_packswap;
png_set_shift;
png_set_interlace_handling;
png_set_invert_mono;
png_set_background;
png_set_strip_16;
png_set_dither;
png_set_gamma;
png_permit_empty_plte;
png_set_flush;
png_write_flush;
png_start_read_image;
png_read_update_info;
png_read_rows;
png_read_row;
png_read_image;
png_write_row;
png_write_rows;
png_write_image;
png_write_end;
png_read_end;
png_destroy_info_struct;
png_destroy_read_struct;
png_destroy_write_struct;
png_set_crc_action;
png_set_filter;
png_set_filter_heuristics;
png_set_compression_level;
png_set_compression_mem_level;
png_set_compression_strategy;
png_set_compression_window_bits;
png_set_compression_method;
png_init_io;
png_set_error_fn;
png_get_error_ptr;
png_set_write_fn;
png_set_read_fn;
png_get_io_ptr;
png_set_read_status_fn;
png_set_write_status_fn;
png_set_mem_fn;
png_get_mem_ptr;
png_set_read_user_transform_fn;
png_set_write_user_transform_fn;
png_set_user_transform_info;
png_get_user_transform_ptr;
png_set_read_user_chunk_fn;
png_get_user_chunk_ptr;
png_set_progressive_read_fn;
png_get_progressive_ptr;
png_process_data;
png_progressive_combine_row;
png_malloc;
png_malloc_warn;
png_free;
png_free_data;
png_data_freer;
png_malloc_default;
png_free_default;
png_memcpy_check;
png_memset_check;
png_error;
png_chunk_error;
png_warning;
png_chunk_warning;
png_get_valid;
png_get_rowbytes;
png_get_rows;
png_set_rows;
png_get_channels;
png_get_image_width;
png_get_image_height;
png_get_bit_depth;
png_get_color_type;
png_get_filter_type;
png_get_interlace_type;
png_get_compression_type;
png_get_pixels_per_meter;
png_get_x_pixels_per_meter;
png_get_y_pixels_per_meter;
png_get_pixel_aspect_ratio;
png_get_x_offset_pixels;
png_get_y_offset_pixels;
png_get_x_offset_microns;
png_get_y_offset_microns;
png_get_signature;
png_get_bKGD;
png_set_bKGD;
png_get_cHRM;
png_get_cHRM_fixed;
png_set_cHRM;
png_set_cHRM_fixed;
png_get_gAMA;
png_get_gAMA_fixed;
png_set_gAMA;
png_set_gAMA_fixed;
png_get_hIST;
png_set_hIST;
png_get_IHDR;
png_set_IHDR;
png_get_oFFs;
png_set_oFFs;
png_get_pCAL;
png_set_pCAL;
png_get_pHYs;
png_set_pHYs;
png_get_PLTE;
png_set_PLTE;
png_get_sBIT;
png_set_sBIT;
png_get_sRGB;
png_set_sRGB;
png_set_sRGB_gAMA_and_cHRM;
png_get_iCCP;
png_set_iCCP;
png_get_sPLT;
png_set_sPLT;
png_get_text;
png_set_text;
png_get_tIME;
png_set_tIME;
png_get_tRNS;
png_set_tRNS;
png_get_sCAL;
png_set_sCAL;
png_set_keep_unknown_chunks;
png_handle_as_unknown;
png_set_unknown_chunks;
png_set_unknown_chunk_location;
png_get_unknown_chunks;
png_set_invalid;
png_read_png;
png_write_png;
png_get_copyright;
png_get_header_ver;
png_get_header_version;
png_get_libpng_ver;
png_permit_mng_features;
png_get_mmx_flagmask;
png_get_asm_flagmask;
png_get_asm_flags;
png_get_mmx_bitdepth_threshold;
png_get_mmx_rowbytes_threshold;
png_set_asm_flags;
png_set_mmx_thresholds;
png_mmx_support;
png_set_strip_error_numbers;
png_set_user_limits;
png_get_user_width_max;
png_get_user_height_max;
png_get_uint_32;
png_get_uint_16;
png_get_int_32;
png_get_uint_31;
png_save_uint_32;
png_save_int_32;
png_save_uint_16;
local: *; };

View File

@ -8,10 +8,22 @@ include(FetchContent)
FetchContent_Declare(
minecraft-pi
URL "${CMAKE_CURRENT_SOURCE_DIR}/minecraft-pi-0.1.1.tar.gz"
URL_HASH "SHA256=e0d68918874cdd403de1fd399380ae2930913fcefdbf60a3fbfebb62e2cfacab"
)
FetchContent_Populate(minecraft-pi)
# Install
install(DIRECTORY "${minecraft-pi_SOURCE_DIR}/" DESTINATION "${MCPI_INSTALL_DIR}" USE_SOURCE_PERMISSIONS)
install(
DIRECTORY "${minecraft-pi_SOURCE_DIR}/"
DESTINATION "${MCPI_INSTALL_DIR}/game"
USE_SOURCE_PERMISSIONS
REGEX "api" EXCLUDE
REGEX "data" EXCLUDE
)
if(NOT MCPI_HEADLESS_MODE)
install(
DIRECTORY "${minecraft-pi_SOURCE_DIR}/data/"
DESTINATION "${MCPI_INSTALL_DIR}/game/data"
USE_SOURCE_PERMISSIONS
)
endif()
install_symlink("game/minecraft-pi" "${MCPI_INSTALL_DIR}/minecraft-pi")

50
dependencies/qemu/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,50 @@
project(qemu)
## QEMU
# Version
set(QEMU_VERSION "8.2.1")
# Flatpak Support
set(QEMU_PATCH "")
if(MCPI_IS_FLATPAK_BUILD)
set(QEMU_PATCH "sed" "-i" "s/libdrm/libdrm-dis/g" "<SOURCE_DIR>/meson.build")
endif()
# Build
include(ExternalProject)
set(PKGCONFIG_ENV "")
if(DEFINED ENV{PKG_CONFIG_LIBDIR})
set(PKGCONFIG_ENV "PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}")
endif()
ExternalProject_Add(qemu
URL "${CMAKE_CURRENT_SOURCE_DIR}/../../archives/qemu-${QEMU_VERSION}.tar.xz"
CONFIGURE_COMMAND
"${CMAKE_COMMAND}" "-E" "env"
${PKGCONFIG_ENV}
"CFLAGS=-s"
"CXXFLAGS=-s"
"<SOURCE_DIR>/configure"
"--prefix=${CMAKE_INSTALL_PREFIX}"
"--cross-prefix="
"--cc=${CMAKE_C_COMPILER}"
"--cxx=${CMAKE_CXX_COMPILER}"
"--disable-debug-info"
"--target-list=arm-linux-user"
"--without-default-features"
USES_TERMINAL_CONFIGURE TRUE
BUILD_COMMAND ninja "qemu-arm"
USES_TERMINAL_BUILD TRUE
INSTALL_COMMAND ""
TEST_COMMAND ""
PATCH_COMMAND ${QEMU_PATCH}
BUILD_BYPRODUCTS "<BINARY_DIR>/qemu-arm"
)
# Install
ExternalProject_Get_property(qemu BINARY_DIR)
install(PROGRAMS "${BINARY_DIR}/qemu-arm" DESTINATION "${MCPI_BIN_DIR}")
# License
ExternalProject_Get_property(qemu SOURCE_DIR)
install(FILES "${SOURCE_DIR}/COPYING" DESTINATION "${MCPI_LEGAL_DIR}/qemu")

30
dependencies/stb_image/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,30 @@
project(stb_image)
# Silence Warnings
add_compile_options(-w)
## stb_image
# Build
add_library(stb_image SHARED src/stb_image_impl.c)
target_include_directories(
stb_image
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/stb_image>"
)
target_link_libraries(stb_image PRIVATE m)
target_compile_definitions(stb_image PUBLIC STBI_ONLY_PNG)
# Install
install(TARGETS stb_image DESTINATION "${MCPI_LIB_DIR}")
install(
DIRECTORY "include/"
DESTINATION "${MCPI_SDK_INCLUDE_DIR}/stb_image"
FILES_MATCHING
PATTERN "*.h"
)
install(TARGETS stb_image EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
# License
install(FILES include/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/stb_image")

1
dependencies/stb_image/include vendored Submodule

@ -0,0 +1 @@
Subproject commit beebb24b945efdea3b9bba23affb8eb3ba8982e7

View File

@ -0,0 +1,5 @@
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image.h"
#include "stb_image_write.h"

View File

@ -0,0 +1,20 @@
project(symbol-processor)
# Install Dependencies
set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(NODE_MODULES "${SRC}/node_modules")
function(npm_run)
execute_process(
COMMAND npm ${ARGV}
WORKING_DIRECTORY "${SRC}"
RESULT_VARIABLE RESULT
)
if(NOT RESULT EQUAL 0)
file(REMOVE_RECURSE "${NODE_MODULES}")
message(FATAL_ERROR "Unable To Run NPM Command")
endif()
endfunction()
if(NOT EXISTS "${NODE_MODULES}")
npm_run(ci --silent)
npm_run(run --silent lint)
endif()

1
dependencies/symbol-processor/src vendored Submodule

@ -0,0 +1 @@
Subproject commit 67c4adaa772445f919f37131d7605bd374c67845

12
dependencies/utf8cpp/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,12 @@
project(utf8cpp)
# Silence Warnings
add_compile_options(-w)
## stb_image
# Build
add_subdirectory(src EXCLUDE_FROM_ALL)
# License
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/utf8cpp")

1
dependencies/utf8cpp/src vendored Submodule

@ -0,0 +1 @@
Subproject commit f6780f77f6824aa0fbe69f9b97ef7d8aba26ed92

20
dependencies/zenity/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,20 @@
project(zenity)
# Silence Warnings
add_compile_options(-w)
## Zenity
# Download
set(MESSAGE_QUIET TRUE)
add_subdirectory(src EXCLUDE_FROM_ALL)
unset(MESSAGE_QUIET)
# Ensure Build
add_custom_target(zenity-build ALL DEPENDS zenity)
# Install
install(TARGETS zenity DESTINATION "${MCPI_BIN_DIR}")
# License
install(FILES src/COPYING DESTINATION "${MCPI_LEGAL_DIR}/zenity")

1
dependencies/zenity/src vendored Submodule

@ -0,0 +1 @@
Subproject commit a7496461161c917878d58131711425e7c8e59436

View File

@ -1,23 +0,0 @@
project(zlib)
include(FetchContent)
# Silence Warnings
add_compile_options(-w)
## zlib
# Download
set(SKIP_INSTALL_ALL TRUE) # Skip Default ZLib Installation
FetchContent_Declare(
zlib
GIT_REPOSITORY "https://github.com/madler/zlib.git"
GIT_TAG "v1.2.11"
)
FetchContent_Populate(zlib)
include_directories("${zlib_SOURCE_DIR}" "${zlib_BINARY_DIR}") # Fix ZLib Build
add_subdirectory("${zlib_SOURCE_DIR}" "${zlib_BINARY_DIR}")
# Install
install(TARGETS zlib DESTINATION "${MCPI_LIB_DIR}")

View File

@ -2,16 +2,24 @@
## Launch Sequence
### Common
1. The launcher forks itself.
1. The child process continues the launch sequence.
2. The original process monitors the child process for crashes.
### Client
1. The launcher is started by the user
1. The launcher starts several Zenity dialogs to configure MCPI-Reborn
2. The launcher replaces itself with MCPI
1. MCPI-Reborn components are loaded using ``LD_PRELOAD`` and ``LD_LIBRARY_PATH``
2. If the Media Layer Proxy is enabled, the Media Layer Proxy Client is started as a sub-process
1. The launcher is started by the user.
1. The launcher starts several Zenity dialogs to configure MCPI-Reborn.
1. If the corresponding environmental variable for a setting is specified, it will be used instead of the dialog.
2. If a setting is cached, then the dialog's default value will be the cached value instead of the normal default.
3. When configuration has been completed, the settings specified will be cached.
2. The launcher replaces itself with MCPI.
1. MCPI-Reborn components are loaded using `LD_PRELOAD` and `LD_LIBRARY_PATH`.
2. If the Media Layer Proxy is enabled, then the Media Layer Proxy Client is started as a sub-process.
### Server
1. The launcher is started by the user
2. The launcher replaces itself with MCPI
1. The launcher is started by the user.
2. The launcher replaces itself with MCPI.
## Components
@ -19,11 +27,11 @@
This component configures the various environmental variables required for MCPI-Reborn to work. When running in client-mode, this component will also launch several Zenity dialogs for interactive configuration.
The environmental variables configured by this component includes:
* ``LD_PRELOAD``
* ``LD_LIBRAR_PATH``
* ``MCPI_FEATURE_FLAGS``
* ``MCPI_RENDER_DISTANCE``
* ``MCPI_USERNAME``
* `LD_PRELOAD`
* `LD_LIBRARY_PATH`
* `MCPI_FEATURE_FLAGS`
* `MCPI_RENDER_DISTANCE`
* `MCPI_USERNAME`
This is always compiled for the host system's architecture.
@ -34,11 +42,11 @@ The Media Layer handles MCPI's graphics calls and user input. It replaces MCPI's
This sub-component re-implements a subset of SDL 1.2 calls with GLFW. It also provides a few utility functions that are used internally by MCPI-Reborn.
The utility functions include:
* Taking Screenshots
* Fullscreen
* Audio
* Etc
This is always compiled for the host system's architecture.
This is always compiled for the host system's architecture unless the Media Layer Proxy is disabled.
This was created because SDL 1.2 has numerous bugs and is in-general unsupported.
@ -59,47 +67,40 @@ It is made of two parts:
While proxying all Media Layer Core API calls across UNIX pipes does hurt performance, it is better than emulating the entire graphics stack.
Using this in server-mode is redundant (and disallowed).
Using this in server-mode is redundant (but is possible).
#### Extras
This sub-component contains code that must always be linked directly to MCPI.
This is always compiled for ARM.
#### Stubs
This sub-component implements stubs for various redundant libraries used by MCPI to silence linker errors.
This is always compiled for ARM.
##### What To Stub And What To Patch?
Most libraries (like ``bcm_host``) can just be replaced with stubs, because they don't need to do anything and aren't used by anything else. However, some libraries (like EGL and X11) might be used by some of MCPI-Reborn's dependencies (like GLFW) so instead of being replaced by a stub, each call is manually patched out from MCPI. A stub is still generated just in case that library isn't present on the system to silence linker errors, but it is only loaded if no other version is available.
#### Headers
This sub-component includes headers for SDL, GLES, and EGL allowing easy (cross-)compilation.
### Mods
This component links directly to MCPI and patches it to modify its behavior.
This component patches MCPI to modify its behavior. It's loaded using `LD_PRELOAD`.
This is always compiled for ARM.
### ``libreborn``
### `libreborn`
This component contains various utility functions including:
* Code Patching (ARM Only)
* Logging
* MCPI Symbols
* Etc
The code patching is ARM only because it relies on hard-coded ARM instructions. However, this is irrelevant since code patching is only needed in ARM code (to patch MCPI).
### `symbols`
This component contains all MCPI symbols.
## Dependencies
MCPI-Reborn has several dependencies:
* MCPI (Bundled)
* GLFW (Only In Client Mode)
* Open GL ES 1.1
* EGL
* GLFW (Only In Client Mode; Bundled)
* OpenGL ES 2.0
* OpenAL (Only In Client Mode)
* ZLib (Required By LibPNG; Bundled)
* LibPNG (Bundled)
* FreeImage (Only In Client Mode)
* QEMU User Mode (Only On Non-ARM Hosts; Runtime Only)
* Zenity (Only In Client Mode; Runtime Only)
* Zenity (Only In Client Mode; Runtime Only; Bundled)

View File

@ -1,63 +1,13 @@
# Building
## Build Options
* ``MCPI_BUILD_MODE``
* ``arm``: Only Build ARM Components
* ``native``: Only Build Native Components
* ``both`` (Default): Build Both ARM And Native Components For ARM
* ``MCPI_SERVER_MODE``
* ``ON``: Enable Server Mode
* ``OFF`` (Default): Disable Server Mode
* ``MCPI_USE_MEDIA_LAYER_PROXY``
* ``ON``: Enable The Media Layer Proxy
* ``OFF`` (Default): Disable The Media Layer Proxy
## Build Dependencies
* Common
* ARM Compiler
* Host Compiler (Clang)
* CMake
* Host Architecture Dependencies
* Client Mode Only
* GLFW
* FreeImage
## Runtime Dependencies
* Non-ARM Host Architectures
* QEMU User-Mode Static
* Host Architecture Dependencies
* CLient Mode Only
* OpenGL ES 1.1
* GLFW
* FreeImage
* Zenity
## Two-Step Build
Use this when the host architecture is not ARM.
## Dependencies
### Debian/Ubuntu
```sh
# Create Build Directory
mkdir build && cd build
# Build ARM Components
mkdir arm && cd arm
cmake -DMCPI_BUILD_MODE=arm ../..
make -j$(nproc) && sudo make install
# Build Native Components
mkdir native && cd native
cmake -DMCPI_BUILD_MODE=native ../..
make -j$(nproc) && sudo make install
./scripts/install-dependencies.sh
```
## One-Step Build
Use this when the host architecture is ARM.
## Instructions
```sh
# Create Build Directory
mkdir build && cd build
# Build
cmake ..
make -j$(nproc) && sudo make install
./scripts/build.mjs <none|appimage|flatpak> <client|server> <armhf|arm64|amd64|host> [--clean] [--install] [-Dvar=value...]
```

View File

@ -1,5 +1,280 @@
# Changelog
**3.0.0**
* Modding API Revamped
* `*(unsigned char **)` Is Dead!
* Add Peaceful Mode To Options Screen
* Proper Create New World Screen
* Proper Chat Screen
* Add `Animated Lava` Feature Flag (Enabled By Default)
* Add `Animated Fire` Feature Flag (Enabled By Default)
* Add `Use Java Beta 1.3 Light Ramp` Feature Flag (Enabled By Default)
* Add `Send Full Level When Hosting Game` Feature Flag (Enabled By Default)
* Add `Food Overlay` Feature Flag (Disabled By Default)
* Add `Display Date In Select World Screen` Feature Flag (Enabled By Default)
* Add `Optimized Chunk Sorting` Feature Flag (Enabled By Default)
* Add `Add Cake` Feature Flag (Enabled By Default)
* Add Milk Buckets
* Implement Crafting Remainders
* Improve Death Messages
* Massive Build System Improvements
* Fix Item Dropping When Killing Players From The Server Console
* Fix Furnace Visual Bug When Using Lava Bucket As Fuel
* Add Splash Text To Start Screen
* `overwrite_calls` Now Scans VTables
**2.5.3**
* Add `Replace Block Highlight With Outline` Feature Flag (Enabled By Default)
* By Default, The Outline Width Is Set Using The GUI Scale
* This Can Be Overridden Using The `MCPI_BLOCK_OUTLINE_WIDTH` Environmental Variable
* Added `overwrite_calls_within` Function
**2.5.2**
* Add `3D Chest Model` Feature Flag (Enabled By Default)
* Stop Using Jenkins
* Replace `iconv`
* Replace LibPNG
**2.5.1**
* Allow Overriding Custom Skin Server Using `MCPI_SKIN_SERVER` Environmental Variable
* Fix Bug With SDK Generation
**2.5.0**
* [Custom skin support](CUSTOM_SKINS.md)!
* Add `Load Custom Skins` Feature Flag (Enabled By Default)
**2.4.9**
* Allow Overriding GUI Scale With `MCPI_GUI_SCALE` Environmental Variable
* Add `Disable Block Tinting` Feature Flag (Disabled By Default)
* Add `Disable Hostile AI In Creative Mode` Feature Flag (Enabled By Default)
* Allow Accessing Configuration At Runtime (Useful For Mods That Need To Support Multiple Versions)
**2.4.8**
* Fix Bug In `extract_from_bl_instruction`
* Update LIEF And GLFW
* Allow Mods To Access The Original GLFW Keycode For Key Events (But Better)
* More Accurate Sound
**2.4.7**
* Improve Server Performance
* Add `Add Biome Colors To Grass` Feature Flag (Disabled By Default)
* Add `Generate Caves` Feature Flag (Enabled By Default)
* Allow Mods To Access The Original GLFW Keycode For Key Events
**2.4.6**
* [Minimal Controller Support](CONTROLS.md)
* Fix Holding Left-Click When Attacking
* Fix Crashing On ARMHF
* Heavily Improved Crash Report Dialog
**2.4.5**
* Bundle QEMU
**2.4.4**
* Cache Previous Launcher Configuration
* Add `MCPI_API_PORT` Environmental Variable
* Fix Particles In Front-Facing View
* Fixed Launch Crash On Ubuntu ARM64
* PatchELF Replaced With LIEF
* Moved `3D Anaglyph` Feature Flag To Options Screen
* Add `Improved Classic Title Screen` Feature Flag (Enabled By Default)
* Add Quit button
* Add Options Button (Moved From `Fix Options Screen` Feature Flag)
* Add `Disable Speed Bridging` Feature Flag (Disabled By Default)
* Add `Disable Creative Mode Mining Delay` Feature Flag (Disabled By Default)
* Improved Feature Flag Names
* Miscellaneous Bug Fixes
* Improved Build System
**2.4.3**
* Fix Signs With CP-437
**2.4.2**
* Fix Picking Up Lava
* Fix Wayland App ID
**2.4.1**
* Allow More Characters In Usernames And Chat
* Fix Running On ARMHF Debian Buster
**2.4.0**
* [Modding SDK](../example-mods/README.md)
* Cache Blacklist/Whitelist
* More Reliable AppImages
* CMake Refactors
* Disable Broken Touchscreen-Specific Block Outline Behavior
* Add `Remove Forced GUI Lag (Can Break Joining Servers)` Feature Flag (Disabled By Default)
* Add `Add Buckets` Feature Flag (Enabled By Default)
* Add `Classic HUD` Feature Flag (Enabled By Default)
* Add `Translucent Toolbar` Feature Flag (Enabled By Default)
* Add `Force EGL` Feature Flag (Disabled By Default)
* Fix Sound Pitch/Volume/Attenuation
* Fix Holding Left-Click When Attacking
* Don't Force EGL (Should Fix Some NVIDIA Systems)
* Performance Fixes
**2.3.13**
* Fix Texture Bug
**2.3.12**
* Media Layer Proxy Optimizations
* Bug Fixes
**2.3.11**
* `--version` Command Line Option
* TPS Measured In Benchmark & Server
* Front-Facing Third-Person
* GLESv1 Comparability Layer
* Miscellaneous Bug Fixes
**2.3.10**
* Add Crash Report Dialog
* Disable V-Sync By Default
* Refactor Child Process Management
* Improve Build System
* Support For Building On Ubuntu 22.04
**2.3.9**
* Bundle An ARM Sysroot
* Not Used On ARM32 Systems
* Based On Debian Bullseye
* Colored Log Output
**2.3.8**
* Switch Up Mod Loading Order
**2.3.7**
* Don't Append Hyphens To New World Name, Only Folder Names
**2.3.6**
* Fix `Invert Y-axis` Option Name
* Improve Touch GUI Inventory In Non-Touch GUI
* New Create World Dialog
* Controlled By `Implement Create World Dialog` Feature Flag (Enabled By Default)
* Custom World Names
* Game-Mode Selection
* Custom Seeds
**2.3.5**
* Renamed Some Feature Flags
* Add `Improved Title Background` Feature Flag (Enabled By Default)
* Non-Touch GUI Rework
* Make `Full Touch GUI` Feature Flag Disabled By Default
* Add `Force Touch GUI Button Behavior` Feature Flag (Enabled By Default)
* Add `Improved Button Hover Behavior` Feature Flag (Enabled By Default)
**2.3.4**
* AppImage Fixes
* Make Death Messages Customizable Server-Side
* Fix Q-Key Behavior Behavior When Editing Signs
* Add `Force Touch Inventory` Feature Flag (Disabled By Default)
* Add `Fix Pause Menu` Feature Flag (Enabled By Default)
* Enables Server Visibility Toggle Button
* Options Changes (Not Supported On Legacy)
* Add `Fix Options Screen` Feature Flag (Enabled By Default)
* Adds Options Button To Classic UI Start Screen
* Removes Useless Options Toggles
* Fixes Options Toggles' Default Position
* Store Multiple Settings In `options.txt`
* `Peaceful Mode` Feature Flag Moved To `game_difficulty`
* `Smooth Lighting` Feature Flag Moved To `gfx_ao`
* `Fancy Graphics` Feature Flag Moved To `gfx_fancygraphics`
* `Disable Hosting LAN Worlds` Feature Flag Moved To `mp_server_visible_default`
**2.3.3**
* Add More Blocks To Expanded Creative Inventory
* Add AppStream Metadata
**2.3.2**
* Simplify Launch Sequence
* Add More Blocks To Expanded Creative Inventory
* Fix Nether Reactor With Creative Restrictions Disabled
* Alphabetize Feature Flags
* Add `Disable V-Sync` Feature Flag (Disabled By Default)
**2.3.1**
* Internal Refactor Of `libreborn`
* Remove Use Of `/bin/sh`
* Load Custom Mods First
* Use Zenity Dark Mode
* Add `Improved Cursor Rendering` Feature Flag (Enabled By Default)
**2.3.0**
* Switch To AppImage For Packaging
* Prevent OpenAL From Crashing When Out Of Memory
* Vendor GLFW & Zenity
* Seamless Wayland Support
* Add `MCPI_DEBUG` Environmental Variable
* Add `Disable Hosting LAN Worlds` Feature Flag (Disabled By Default)
* Add `Fix Furnace Not Checking Item Auxiliary` Feature Flag (Enabled By Default)
* Add `Disable Raw Mouse Motion (Not Recommended)` Feature Flag (Disabled By Default) For Broken X11 Setups
* Added Back `~/.minecraft-pi/mods`
* Improve Build System
* Improve Documentation
**2.2.11**
* Add `Close Current Screen On Death` Feature Flag (Enabled By Default) To Prevent Bugs
* Fix More Furnace UI Bugs When Using "Disable 'gui_blocks' Atlas"
**2.2.10**
* Fix Bug With Picking Up Items In "Remove Creative Mode Restrictions" Mode
**2.2.9**
* Fix String Sanitization
* Store Files In `/usr/lib`
**2.2.8**
* Add `Hide Chat Messages` Optional Feature Flag
* Add `Remove Creative Mode Restrictions` Optional Feature Flag
* Improve GLFW->SDL Mouse Motion Event Conversion
* Performance Optimizations
* Make Majority Of Server-Specific Logging Code Also Apply To The Client
* Simple Benchmark Mode
* Fix Typo When Audio Source File Doesn't Exist
* Improve Build System
**2.2.7**
* Fix Crash When OpenAL Is Unavailable
* Fix Command Input In Server
**2.2.5**
* Fix Bug In Texture Scaling Code
**2.2.5**
* Scale Animated Textures
* Add More Blocks To Expanded Creative Inventory
* Reduce Unnecessary Logging
* Log IPs In Server Mode
**2.2.4**
* Instead Of Crashing, Disable Polling Block Hits In Survival Mode Using The API
**2.2.3**
* Fix Crash When Taking Odd-Sized Screenshots
**2.2.2**
* Add More Missing Sound Events
* Make Missing Sound Event Cause Warning Rather Than Crash
**2.2.1**
* Prevent `random.burp` Sound From Crashing Game
* Always Cleanup Media Layer, Even On Crash
* Resolve All Sounds On Startup
**2.2.0**
* Sound Support
* Split Off `Allow Joining Survival Servers` From Game-Mode Mod
* Separate Headless Code From Server Code
* Fix Bug Where `RakNetInstance` Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
* Clean-Up Code
* Remove Support For Debian Buster
**2.1.8**
* Fix Crash On ARM Systems
**2.1.7**
* Fix On 64-Bit ARM Systems
**2.1.6**
* Optimize Media Layer Proxy
@ -7,7 +282,7 @@
* Print Error Message If RakNet Fails To Start
**2.1.4**
* Fix RakNet::RakString Security Bug
* Fix `RakNet::RakString` Security Bug
**2.1.3**
* Workaround Broken Library Search Path On Some ARM 32-Bit Systems
@ -19,16 +294,16 @@
* Fix Symlink Code
**2.1.0**
* Allow Binding ``Q`` Key To Item Dropping
* Allow Binding `Q` Key To Item Dropping
* Expose More Feature Flags
* Replace ``Mob Spawning`` Feature Flag With ``Force Mob Spawning``
* Fix ``ESC`` Key In Options Menu When ``Miscellaneous Input Fixes`` Is Enabled
* Replace `Mob Spawning` Feature Flag With `Force Mob Spawning`
* Fix `ESC` Key In Options Menu When `Miscellaneous Input Fixes` Is Enabled
**2.0.9**
* Fix Translucent Preview Items In Furnace UI Being Fully Opaque When The ``gui_blocks`` Atlas Is Disabled
* Fix Translucent Preview Items In Furnace UI Being Fully Opaque When The `gui_blocks` Atlas Is Disabled
**2.0.8**
* Use Default Port In ``servers.txt`` If Not Specified
* Use Default Port In `servers.txt` If Not Specified
**2.0.7**
* Fix Sign Text Not Updating In Multiplayer When Exiting Editing UI Using Escape Button
@ -45,7 +320,7 @@
* Optimize Media Layer Proxy
**2.0.3**
* Make "kill" Admin Command Print Death Message
* Make `kill` Admin Command Print Death Message
**2.0.2**
* Fix Mouse Cursor Bugs

View File

@ -1,11 +1,64 @@
# Command Line Arguments
# Command Line Usage
## ``--print-available-feature-flags`` (Client Mode Only)
If you run MCPI-Reborn with ``--print-available-feature-flags``, it will print the available feature flags and then immediately exit. The feature flags are printed in the following format:
## Command Line Arguments
### `--version` (Or `-v`)
If you run MCPI-Reborn with `--version` it will print its version to `stdout`.
### `--debug`
This sets `MCPI_DEBUG`.
### `--copy-sdk`
This extracts the modding SDK and immediately exits. (This allows the SDK to be extracted without starting the game.)
### Client Mode Only
#### `--print-available-feature-flags`
This print the available feature flags (and their default values) to `stdout` and then immediately exit.
The feature flags are printed in the following format:
```
TRUE This Flag Is On By Default
FALSE This Flag Is Off By Default
```
## ``--only-generate`` (Server Mode Only)
If you run MCPI-Reborn with ``--only-generate``, it will immediately exit once world generation has completed. This is mainly used for automatically testing MCPI-Reborn.
#### `--default`
This will skip the startup configuration dialogs and just use the default values. This will use the cached configuration unless `--no-cache` is used.
#### `--benchmark`
This will make MCPI-Reborn enter a simple benchmark mode. This means automatically loading a newly generated world, then rotating the camera for a period of time. When it has finished, it will then exit and print the average FPS while the world was loaded. In this mode, all user input is blocked. However you can still modify rendering settings by changing feature flags.
The world used will always be re-created on start and uses a hard-coded seed.
#### `--no-cache`
This will skip loading and saving the cached launcher configuration.
#### `--wipe-cache`
This will wipe the cached launcher configuration.
### Server Mode Only
#### `--only-generate`
This will make MCPI-Reborn immediately exit once world generation has completed. This is mainly used for automatically testing MCPI-Reborn.
## Environmental Variables
### `MCPI_DEBUG`
This enables debug logging if it is set.
### `MCPI_API_PORT`
This configures the API to use a different port (the default is 4711).
### Client Mode Only
If any of the following variables aren't set, one configuration dialog will open on startup for each unset variable.
#### `MCPI_FEATURE_FLAGS`
This corresponds to `--print-available-feature-flags`. This is just a list of all enabled feature flags separated by `|`.
For instance, the string `Feature A|Feature B` would enable both `Feature A` and `Feature B` and *disable every other available feature flag*.
#### `MCPI_RENDER_DISTANCE`
This is the render distance. The possible values are: `Far`, `Normal`, `Short`, and `Tiny`.
#### `MCPI_USERNAME`
This is the username.

45
docs/CONTROLS.md Normal file
View File

@ -0,0 +1,45 @@
# In-Game Controls
## Keyboard & Mouse
| Action | Function |
| --- | --- |
| W | Move Forward |
| A | Move Left |
| S | Move Backward |
| D | Move Right |
| Space | Jump |
| Shift | Sneak |
| E | Open Inventory |
| Q | Drop Item |
| Ctrl+Q | Drop Item Stack |
| 1-9 | Select Item In Toolbar/Hotbar |
| Escape | Pause |
| Tab | Lock/Unlock Mouse |
| F11 | Fullscreen |
| F2 | Screenshot |
| F1 | Hide GUI |
| F5 | Change Perspective |
| T | Open Chat |
| Mouse Movement | Camera Control |
| Scroll Wheel | Cycle Selected Item In Toolbar |
| Left-CLick | Attack/Destroy |
| Right-Click | Use Item/Place Block |
## Game Controller
| Action | Function |
| --- | --- |
| A | Jump |
| Y | Open Inventory |
| B | Sneak[^1] |
| X | Open Crafting |
| D-Pad Up | Change Perspective |
| D-Pad Down | Drop Item |
| D-Pad Right | Open Chat |
| Left/Right Bumper | Cycle Selected Item In Toolbar |
| Left Trigger | Use Item/Place Block |
| Right Trigger | Attack/Destroy |
| Start/Back | Pause |
| Left Stick | Movement |
| Right Stick | Camera Control |
[^1]: Unlike Minecraft: Bedrock Edition, this *is not* a toggle.

6
docs/CUSTOM_SKINS.md Normal file
View File

@ -0,0 +1,6 @@
# Custom Skins
MCPI-Reborn supports downloading custom skins from [a central skin server](https://github.com/MCPI-Revival/Skins). Skins are downloaded based on the current MCPI username.
This *does not* cache skins and *will not* work without internet access.
Custom skins can be disabled using the `Load Custom Skins` feature flag.

View File

@ -1,14 +1,14 @@
# Dedicated Server
The dedicated server is a version of Minecraft: Pi Edition modified to run in a headless environment. It loads settings from a ``server.properties`` file.
The dedicated server is a version of Minecraft: Pi Edition modified to run in a headless environment. It loads settings from a `server.properties` file.
This server is also compatible with MCPE Alpha v0.6.1.
This server is also compatible with MCPE Alpha v0.6.1[^1].
## Setup
### Debian Package
To use, install and run ``minecraft-pi-reborn-server``. It will generate the world and ``server.properties`` in the current directory.
To use, install and run the `minecraft-pi-reborn-server` AppImage. It will generate the world and `server.properties` in the current directory.
## Server Limitations
* Player data is not saved because of limitations with MCPE LAN worlds
* An easy workaround is to place your inventory in a chest before logging off
* Survival Mode servers are incompatible with unmodded MCPI
[^1]: The exception to this is buckets, those will crash MCPE players.

View File

@ -1,26 +1,30 @@
# Manual Installation
[Download Packages Here](https://jenkins.thebrokenrail.com/job/minecraft-pi-reborn/job/master/lastSuccessfulBuild/artifact/out/)
# Installation
## Picking A Package
## AppImage
Download packages [here](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases).
### Name Format
```
minecraft-pi-reborn-<Variant>_X.Y.Z~<Distribution>_<Architecture>
```
### System Requirements
* Debian Bullseye/Ubuntu 20.04 Or Higher
* FUSE 2
* Debian/Ubuntu: `sudo apt install libfuse2`
* Arch: `sudo pacman -S fuse2`
* Client-Only Dependencies
* Graphics Drivers
* GTK+ 3
* Debian/Ubuntu: `sudo apt install libgtk-3-0`
* Arch: `sudo pacman -S gtk3`
* OpenAL
* Debian/Ubuntu: `sudo apt install libopenal1`
* Arch: `sudo pacman -S openal`
### Picking A Variant
* ``client``: Client mode, use this if you want to play MCPI
* ``server``: Server mode, use this if you want to host a dedicated MCPI server
### Running
Follow [these](https://docs.appimage.org/introduction/quickstart.html#how-to-run-an-appimage) instructions.
### Picking A Distribution
This specifies which version of Debian MCPI-Reborn was built against. Which one you should use depends on your current distribution. If your distribution supports it, you should use ``bullseye`` for better mouse sensitivity.
## Flatpak
<a href="https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn"><img width="240" alt="Download On Flathub" src="https://flathub.org/assets/badges/flathub-badge-en.svg" /></a>
* Ubuntu 20.04+: ``bullseye``
* Raspberry Pi OS Buster: ``buster``
* Debian Bullseye+: ``bullseye``
* Debian Buster: ``buster``
### Note
Game data is stored in `~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi` instead of `~/.minecraft-pi`.
### Picking An Architecture
* ``amd64``: x86_64, use this if you are using a device with an AMD or Intel processor
* ``armhf``: ARM 32-Bit, use this if you are using an ARM device (like a Raspberry Pi)
* ``arm64``: ARM 64-Bit, ``armhf`` but for 64-bit devices
## Arch User Repository (Arch Linux Only)
The [`minecraft-pi-reborn-git`](https://aur.archlinux.org/packages/minecraft-pi-reborn-git) is available in the AUR.

View File

@ -5,9 +5,9 @@ MCPI-Reborn supports two ways to play multiplayer.
This is also supported by vanilla MCPI. Just load a world in MCPI and other devices on the network can join.
## External Servers
Unlike vanilla MCPI, MCPI-Reborn allows you to natively join a server outside of the local network. Just modify ``~/.minecraft-pi/servers.txt`` and it should show up in MCPI's server list.
Unlike vanilla MCPI, MCPI-Reborn allows you to natively join a server outside of the local network. Just modify `~/.minecraft-pi/servers.txt` and it should show up in MCPI's server list.
### Example ``~/.minecraft-pi/servers.txt``
### Example `~/.minecraft-pi/servers.txt`
```
# Default Port Is 19132
example.com

View File

@ -1,6 +1,8 @@
# Overriding Assets
To make overriding assets easier, MCPI-Reborn provides an overrides folder. Any file located in Minecraft: Pi Edition's ``data`` folder can be overridden by placing a file with the same name and path in the overrides folder. The overrides folder is located at ``~/.minecraft-pi/overrides``.
To make overriding assets easier, MCPI-Reborn provides an overrides folder. Any file located in Minecraft: Pi Edition's `data` folder can be overridden by placing a file with the same name and path in the overrides folder. The overrides folder is located at `~/.minecraft-pi/overrides`[^1].
## Examples
- ``data/images/terrain.png`` -> ``~/.minecraft-pi/overrides/images/terrain.png``
- ``data/lang/en_US.lang`` -> ``~/.minecraft-pi/overrides/lang/en_US.lang``
- `data/images/terrain.png` -> `~/.minecraft-pi/overrides/images/terrain.png`
- `data/lang/en_US.lang` -> `~/.minecraft-pi/overrides/lang/en_US.lang`
[^1]: On Flatpak, the path is `~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi/overrides`.

View File

@ -1,5 +1,5 @@
# Documentation
* [View Manual Installation](INSTALL.md)
* [View Installation](INSTALL.md)
* [View Overriding Assets](OVERRIDING_ASSETS.md)
* [View Dedicated Server](DEDICATED_SERVER.md)
* [View Credits](CREDITS.md)
@ -8,4 +8,7 @@
* [View Architecture](ARCHITECTURE.md)
* [View Command Line Arguments](COMMAND_LINE.md)
* [View Multiplayer](MULTIPLAYER.md)
* [View Sound](SOUND.md)
* [View In-Game Controls](CONTROLS.md)
* [View Custom Skins](CUSTOM_SKINS.md)
* [View Changelog](CHANGELOG.md)

8
docs/SOUND.md Normal file
View File

@ -0,0 +1,8 @@
# Sound
One of MCPI-Reborn's main modifications is a sound-engine since MCPI does not include one by default[^1]. However, it can't be used out-of-box because MCPI does not contain any sound data and MCPI-Reborn can't include it because of copyright.
MCPE's sound data can be extracted from any MCPE v0.6.1[^2] APK file, just place its `libminecraftpe.so` into `~/.minecraft-pi/overrides`[^3] and you should have sound!
[^1]: The mute button is just leftover code from MCPE, it does not actually do anything in un-modded MCPI, however it is connected to MCPI-Reborn's sound-engine.
[^2]: This is not a hard limit, an MCPE v0.8.1 APK would probably work, but don't rely on it.
[^3]: On Flatpak, the path is `~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi/overrides`.

View File

@ -2,6 +2,7 @@
| Name | Description |
| --- | --- |
| MCPI | Shorthand for Minecraft: Pi Edition |
| MCPE | Shorthand for Minecraft: Pocket Edition |
| Host Architecture | The native architecture of the CPU that MCPi-Reborn will be running on |
| Native Component | A component that *can* be compiled for the host architecture |
| ARM Component | A component that *must* be compiled for ARM |

19
example-mods/README.md Normal file
View File

@ -0,0 +1,19 @@
# Example Mods
This is an example of a mod that can be built using the modding SDK.
* **Expanded Creative Mod**: This specific mod adds even more items and blocks to the Creative Inventory. It was originally by [@Bigjango13](https://github.com/bigjango13).
* **Chat Commands Mod**: This specific mod makes an chat message starting with a ``/`` handled by the MCPI API.
* **Recipes Mod**: This specific mod demos custom recipes.
## The SDK
The modding SDK is a collection of exported CMake targets that allows anyone to create their own MCPI mod!
The SDK is copied to ``~/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cmake`` whenever MCPI-Reborn is started.
## How do I use this?
```sh
mkdir build
cd build
cmake ..
cp libexpanded-creative.so ~/.minecraft-pi/mods
```

26
example-mods/build.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/sh
set -e
# Create Output Directory
cd "$(dirname "$0")"
ROOT="$(pwd)"
OUT="${ROOT}/out"
rm -rf "${OUT}"
mkdir -p "${OUT}"
# Build
build() {
cd "${ROOT}/$1"
# Build
rm -rf build
mkdir build
cd build
cmake -GNinja ..
cmake --build .
# Copy Result
cp lib*.so "${OUT}"
}
build chat-commands
build expanded-creative
build recipes

15
example-mods/chat-commands/.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
/out
/debian/tmp
/.vscode
/build*
/CMakeLists.txt.user
*.autosave
/AppImageBuilder.yml
/appimage-builder-cache
/appimage-build
/AppDir
/*.zsync
/*.AppImage
/core*
/qemu_*
/cmake/.prebuilt-armhf-toolchain

View File

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.16.0)
# Build For ARM
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "arm")
# Start Project
project(chat-commands)
# Include SDK
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cmake")
# Build
add_library(chat-commands SHARED chat-commands.cpp)
target_link_libraries(chat-commands mods reborn-patch symbols)

View File

@ -0,0 +1,24 @@
// Headers
#include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#include <mods/chat/chat.h>
#include <mods/misc/misc.h>
// The Actual Mod
HOOK(chat_handle_packet_send, void, (Minecraft *minecraft, ChatPacket *packet)) {
// Get Message
const char *message = packet->message.c_str();
if (message[0] == '/') {
// API Command
Gui *gui = &minecraft->gui;
std::string out = chat_send_api_command(minecraft, (char *) &message[1]);
if (out.length() > 0 && out[out.length() - 1] == '\n') {
out[out.length() - 1] = '\0';
}
misc_add_message(gui, out.c_str());
} else {
// Call Original Method
ensure_chat_handle_packet_send();
real_chat_handle_packet_send(minecraft, packet);
}
}

View File

@ -0,0 +1,15 @@
/out
/debian/tmp
/.vscode
/build*
/CMakeLists.txt.user
*.autosave
/AppImageBuilder.yml
/appimage-builder-cache
/appimage-build
/AppDir
/*.zsync
/*.AppImage
/core*
/qemu_*
/cmake/.prebuilt-armhf-toolchain

View File

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.16.0)
# Build For ARM
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "arm")
# Start Project
project(expanded-creative)
# Include SDK
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cmake")
# Build
add_library(expanded-creative SHARED expanded-creative.cpp)
target_link_libraries(expanded-creative mods reborn-patch symbols)

View File

@ -0,0 +1,636 @@
// Headers
#include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#include <mods/misc/misc.h>
// The Actual Mod
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(FillingContainer *filling_container) {
ItemInstance *fire_instance = new ItemInstance;
ALLOC_CHECK(fire_instance);
fire_instance->count = 255;
fire_instance->auxiliary = 0;
fire_instance->id = 51;
FillingContainer_addItem(filling_container, fire_instance);
ItemInstance *mushroomStew_instance = new ItemInstance;
ALLOC_CHECK(mushroomStew_instance);
mushroomStew_instance->count = 255;
mushroomStew_instance->auxiliary = 0;
mushroomStew_instance->id = 282;
FillingContainer_addItem(filling_container, mushroomStew_instance);
ItemInstance *steak_instance = new ItemInstance;
ALLOC_CHECK(steak_instance);
steak_instance->count = 255;
steak_instance->auxiliary = 0;
steak_instance->id = 364;
FillingContainer_addItem(filling_container, steak_instance);
ItemInstance *cookedChicken_instance = new ItemInstance;
ALLOC_CHECK(cookedChicken_instance);
cookedChicken_instance->count = 255;
cookedChicken_instance->auxiliary = 0;
cookedChicken_instance->id = 366;
FillingContainer_addItem(filling_container, cookedChicken_instance);
ItemInstance *porkCooked_instance = new ItemInstance;
ALLOC_CHECK(porkCooked_instance);
porkCooked_instance->count = 255;
porkCooked_instance->auxiliary = 0;
porkCooked_instance->id = 320;
FillingContainer_addItem(filling_container, porkCooked_instance);
ItemInstance *apple_instance = new ItemInstance;
ALLOC_CHECK(apple_instance);
apple_instance->count = 255;
apple_instance->auxiliary = 0;
apple_instance->id = 260;
FillingContainer_addItem(filling_container, apple_instance);
ItemInstance *tallGrass_instance = new ItemInstance;
ALLOC_CHECK(tallGrass_instance);
tallGrass_instance->count = 255;
tallGrass_instance->auxiliary = 0;
tallGrass_instance->id = 31;
FillingContainer_addItem(filling_container, tallGrass_instance);
ItemInstance *crops_instance = new ItemInstance;
ALLOC_CHECK(crops_instance);
crops_instance->count = 255;
crops_instance->auxiliary = 0;
crops_instance->id = 59;
FillingContainer_addItem(filling_container, crops_instance);
ItemInstance *farmland_instance = new ItemInstance;
ALLOC_CHECK(farmland_instance);
farmland_instance->count = 255;
farmland_instance->auxiliary = 0;
farmland_instance->id = 60;
FillingContainer_addItem(filling_container, farmland_instance);
ItemInstance *activeFurnace_instance = new ItemInstance;
ALLOC_CHECK(activeFurnace_instance);
activeFurnace_instance->count = 255;
activeFurnace_instance->auxiliary = 0;
activeFurnace_instance->id = 62;
FillingContainer_addItem(filling_container, activeFurnace_instance);
ItemInstance *ironDoor_instance = new ItemInstance;
ALLOC_CHECK(ironDoor_instance);
ironDoor_instance->count = 255;
ironDoor_instance->auxiliary = 0;
ironDoor_instance->id = 330;
FillingContainer_addItem(filling_container, ironDoor_instance);
ItemInstance *activeRedstoneOre_instance = new ItemInstance;
ALLOC_CHECK(activeRedstoneOre_instance);
activeRedstoneOre_instance->count = 255;
activeRedstoneOre_instance->auxiliary = 0;
activeRedstoneOre_instance->id = 74;
FillingContainer_addItem(filling_container, activeRedstoneOre_instance);
ItemInstance *pumkinStem_instance = new ItemInstance;
ALLOC_CHECK(pumkinStem_instance);
pumkinStem_instance->count = 255;
pumkinStem_instance->auxiliary = 0;
pumkinStem_instance->id = 105;
FillingContainer_addItem(filling_container, pumkinStem_instance);
ItemInstance *newGrass_instance = new ItemInstance;
ALLOC_CHECK(newGrass_instance);
newGrass_instance->count = 255;
newGrass_instance->auxiliary = 0;
newGrass_instance->id = 253;
FillingContainer_addItem(filling_container, newGrass_instance);
ItemInstance *reserved6_instance = new ItemInstance;
ALLOC_CHECK(reserved6_instance);
reserved6_instance->count = 255;
reserved6_instance->auxiliary = 0;
reserved6_instance->id = 1;
FillingContainer_addItem(filling_container, reserved6_instance);
ItemInstance *doubleStoneSlab_instance = new ItemInstance;
ALLOC_CHECK(doubleStoneSlab_instance);
doubleStoneSlab_instance->count = 255;
doubleStoneSlab_instance->auxiliary = 0;
doubleStoneSlab_instance->id = 43;
FillingContainer_addItem(filling_container, doubleStoneSlab_instance);
ItemInstance *arrow_instance = new ItemInstance;
ALLOC_CHECK(arrow_instance);
arrow_instance->count = 255;
arrow_instance->auxiliary = 0;
arrow_instance->id = 262;
FillingContainer_addItem(filling_container, arrow_instance);
ItemInstance *coal_instance = new ItemInstance;
ALLOC_CHECK(coal_instance);
coal_instance->count = 255;
coal_instance->auxiliary = 0;
coal_instance->id = 263;
FillingContainer_addItem(filling_container, coal_instance);
ItemInstance *diamond_instance = new ItemInstance;
ALLOC_CHECK(diamond_instance);
diamond_instance->count = 255;
diamond_instance->auxiliary = 0;
diamond_instance->id = 264;
FillingContainer_addItem(filling_container, diamond_instance);
ItemInstance *ironIngot_instance = new ItemInstance;
ALLOC_CHECK(ironIngot_instance);
ironIngot_instance->count = 255;
ironIngot_instance->auxiliary = 0;
ironIngot_instance->id = 265;
FillingContainer_addItem(filling_container, ironIngot_instance);
ItemInstance *goldIngot_instance = new ItemInstance;
ALLOC_CHECK(goldIngot_instance);
goldIngot_instance->count = 255;
goldIngot_instance->auxiliary = 0;
goldIngot_instance->id = 266;
FillingContainer_addItem(filling_container, goldIngot_instance);
ItemInstance *woodSword_instance = new ItemInstance;
ALLOC_CHECK(woodSword_instance);
woodSword_instance->count = 255;
woodSword_instance->auxiliary = 0;
woodSword_instance->id = 268;
FillingContainer_addItem(filling_container, woodSword_instance);
ItemInstance *woodShovel_instance = new ItemInstance;
ALLOC_CHECK(woodShovel_instance);
woodShovel_instance->count = 255;
woodShovel_instance->auxiliary = 0;
woodShovel_instance->id = 269;
FillingContainer_addItem(filling_container, woodShovel_instance);
ItemInstance *woodPickaxe_instance = new ItemInstance;
ALLOC_CHECK(woodPickaxe_instance);
woodPickaxe_instance->count = 255;
woodPickaxe_instance->auxiliary = 0;
woodPickaxe_instance->id = 270;
FillingContainer_addItem(filling_container, woodPickaxe_instance);
ItemInstance *woodAxe_instance = new ItemInstance;
ALLOC_CHECK(woodAxe_instance);
woodAxe_instance->count = 255;
woodAxe_instance->auxiliary = 0;
woodAxe_instance->id = 271;
FillingContainer_addItem(filling_container, woodAxe_instance);
ItemInstance *stoneSword_instance = new ItemInstance;
ALLOC_CHECK(stoneSword_instance);
stoneSword_instance->count = 255;
stoneSword_instance->auxiliary = 0;
stoneSword_instance->id = 272;
FillingContainer_addItem(filling_container, stoneSword_instance);
ItemInstance *stoneShovel_instance = new ItemInstance;
ALLOC_CHECK(stoneShovel_instance);
stoneShovel_instance->count = 255;
stoneShovel_instance->auxiliary = 0;
stoneShovel_instance->id = 273;
FillingContainer_addItem(filling_container, stoneShovel_instance);
ItemInstance *stonePickaxe_instance = new ItemInstance;
ALLOC_CHECK(stonePickaxe_instance);
stonePickaxe_instance->count = 255;
stonePickaxe_instance->auxiliary = 0;
stonePickaxe_instance->id = 274;
FillingContainer_addItem(filling_container, stonePickaxe_instance);
ItemInstance *stoneAxe_instance = new ItemInstance;
ALLOC_CHECK(stoneAxe_instance);
stoneAxe_instance->count = 255;
stoneAxe_instance->auxiliary = 0;
stoneAxe_instance->id = 275;
FillingContainer_addItem(filling_container, stoneAxe_instance);
ItemInstance *shovelIron_instance = new ItemInstance;
ALLOC_CHECK(shovelIron_instance);
shovelIron_instance->count = 255;
shovelIron_instance->auxiliary = 0;
shovelIron_instance->id = 256;
FillingContainer_addItem(filling_container, shovelIron_instance);
ItemInstance *ironPick_instance = new ItemInstance;
ALLOC_CHECK(ironPick_instance);
ironPick_instance->count = 255;
ironPick_instance->auxiliary = 0;
ironPick_instance->id = 257;
FillingContainer_addItem(filling_container, ironPick_instance);
ItemInstance *ironAxe_instance = new ItemInstance;
ALLOC_CHECK(ironAxe_instance);
ironAxe_instance->count = 255;
ironAxe_instance->auxiliary = 0;
ironAxe_instance->id = 258;
FillingContainer_addItem(filling_container, ironAxe_instance);
ItemInstance *diamondSword_instance = new ItemInstance;
ALLOC_CHECK(diamondSword_instance);
diamondSword_instance->count = 255;
diamondSword_instance->auxiliary = 0;
diamondSword_instance->id = 276;
FillingContainer_addItem(filling_container, diamondSword_instance);
ItemInstance *diamondShovel_instance = new ItemInstance;
ALLOC_CHECK(diamondShovel_instance);
diamondShovel_instance->count = 255;
diamondShovel_instance->auxiliary = 0;
diamondShovel_instance->id = 277;
FillingContainer_addItem(filling_container, diamondShovel_instance);
ItemInstance *diamondPickaxe_instance = new ItemInstance;
ALLOC_CHECK(diamondPickaxe_instance);
diamondPickaxe_instance->count = 255;
diamondPickaxe_instance->auxiliary = 0;
diamondPickaxe_instance->id = 278;
FillingContainer_addItem(filling_container, diamondPickaxe_instance);
ItemInstance *diamondAxe_instance = new ItemInstance;
ALLOC_CHECK(diamondAxe_instance);
diamondAxe_instance->count = 255;
diamondAxe_instance->auxiliary = 0;
diamondAxe_instance->id = 279;
FillingContainer_addItem(filling_container, diamondAxe_instance);
ItemInstance *magicWand_instance = new ItemInstance;
ALLOC_CHECK(magicWand_instance);
magicWand_instance->count = 255;
magicWand_instance->auxiliary = 0;
magicWand_instance->id = 280;
FillingContainer_addItem(filling_container, magicWand_instance);
ItemInstance *bowl_instance = new ItemInstance;
ALLOC_CHECK(bowl_instance);
bowl_instance->count = 255;
bowl_instance->auxiliary = 0;
bowl_instance->id = 281;
FillingContainer_addItem(filling_container, bowl_instance);
ItemInstance *goldSword_instance = new ItemInstance;
ALLOC_CHECK(goldSword_instance);
goldSword_instance->count = 255;
goldSword_instance->auxiliary = 0;
goldSword_instance->id = 283;
FillingContainer_addItem(filling_container, goldSword_instance);
ItemInstance *goldShovel_instance = new ItemInstance;
ALLOC_CHECK(goldShovel_instance);
goldShovel_instance->count = 255;
goldShovel_instance->auxiliary = 0;
goldShovel_instance->id = 284;
FillingContainer_addItem(filling_container, goldShovel_instance);
ItemInstance *goldPickaxe_instance = new ItemInstance;
ALLOC_CHECK(goldPickaxe_instance);
goldPickaxe_instance->count = 255;
goldPickaxe_instance->auxiliary = 0;
goldPickaxe_instance->id = 285;
FillingContainer_addItem(filling_container, goldPickaxe_instance);
ItemInstance *goldAxe_instance = new ItemInstance;
ALLOC_CHECK(goldAxe_instance);
goldAxe_instance->count = 255;
goldAxe_instance->auxiliary = 0;
goldAxe_instance->id = 286;
FillingContainer_addItem(filling_container, goldAxe_instance);
ItemInstance *string_instance = new ItemInstance;
ALLOC_CHECK(string_instance);
string_instance->count = 255;
string_instance->auxiliary = 0;
string_instance->id = 287;
FillingContainer_addItem(filling_container, string_instance);
ItemInstance *feather_instance = new ItemInstance;
ALLOC_CHECK(feather_instance);
feather_instance->count = 255;
feather_instance->auxiliary = 0;
feather_instance->id = 288;
FillingContainer_addItem(filling_container, feather_instance);
ItemInstance *gunpowder_instance = new ItemInstance;
ALLOC_CHECK(gunpowder_instance);
gunpowder_instance->count = 255;
gunpowder_instance->auxiliary = 0;
gunpowder_instance->id = 289;
FillingContainer_addItem(filling_container, gunpowder_instance);
ItemInstance *woodHoe_instance = new ItemInstance;
ALLOC_CHECK(woodHoe_instance);
woodHoe_instance->count = 255;
woodHoe_instance->auxiliary = 0;
woodHoe_instance->id = 290;
FillingContainer_addItem(filling_container, woodHoe_instance);
ItemInstance *stoneHoe_instance = new ItemInstance;
ALLOC_CHECK(stoneHoe_instance);
stoneHoe_instance->count = 255;
stoneHoe_instance->auxiliary = 0;
stoneHoe_instance->id = 291;
FillingContainer_addItem(filling_container, stoneHoe_instance);
ItemInstance *flint1_instance = new ItemInstance;
ALLOC_CHECK(flint1_instance);
flint1_instance->count = 255;
flint1_instance->auxiliary = 0;
flint1_instance->id = 292;
FillingContainer_addItem(filling_container, flint1_instance);
ItemInstance *diamondHoe_instance = new ItemInstance;
ALLOC_CHECK(diamondHoe_instance);
diamondHoe_instance->count = 255;
diamondHoe_instance->auxiliary = 0;
diamondHoe_instance->id = 293;
FillingContainer_addItem(filling_container, diamondHoe_instance);
ItemInstance *goldHoe_instance = new ItemInstance;
ALLOC_CHECK(goldHoe_instance);
goldHoe_instance->count = 255;
goldHoe_instance->auxiliary = 0;
goldHoe_instance->id = 294;
FillingContainer_addItem(filling_container, goldHoe_instance);
ItemInstance *seeds_instance = new ItemInstance;
ALLOC_CHECK(seeds_instance);
seeds_instance->count = 255;
seeds_instance->auxiliary = 0;
seeds_instance->id = 295;
FillingContainer_addItem(filling_container, seeds_instance);
ItemInstance *wheat_instance = new ItemInstance;
ALLOC_CHECK(wheat_instance);
wheat_instance->count = 255;
wheat_instance->auxiliary = 0;
wheat_instance->id = 296;
FillingContainer_addItem(filling_container, wheat_instance);
ItemInstance *bread_instance = new ItemInstance;
ALLOC_CHECK(bread_instance);
bread_instance->count = 255;
bread_instance->auxiliary = 0;
bread_instance->id = 297;
FillingContainer_addItem(filling_container, bread_instance);
ItemInstance *diamondHelm_instance = new ItemInstance;
ALLOC_CHECK(diamondHelm_instance);
diamondHelm_instance->count = 255;
diamondHelm_instance->auxiliary = 0;
diamondHelm_instance->id = 310;
FillingContainer_addItem(filling_container, diamondHelm_instance);
ItemInstance *diamondChest_instance = new ItemInstance;
ALLOC_CHECK(diamondChest_instance);
diamondChest_instance->count = 255;
diamondChest_instance->auxiliary = 0;
diamondChest_instance->id = 311;
FillingContainer_addItem(filling_container, diamondChest_instance);
ItemInstance *diamondLeg_instance = new ItemInstance;
ALLOC_CHECK(diamondLeg_instance);
diamondLeg_instance->count = 255;
diamondLeg_instance->auxiliary = 0;
diamondLeg_instance->id = 312;
FillingContainer_addItem(filling_container, diamondLeg_instance);
ItemInstance *diamondBoot_instance = new ItemInstance;
ALLOC_CHECK(diamondBoot_instance);
diamondBoot_instance->count = 255;
diamondBoot_instance->auxiliary = 0;
diamondBoot_instance->id = 313;
FillingContainer_addItem(filling_container, diamondBoot_instance);
ItemInstance *leatherCap_instance = new ItemInstance;
ALLOC_CHECK(leatherCap_instance);
leatherCap_instance->count = 255;
leatherCap_instance->auxiliary = 0;
leatherCap_instance->id = 298;
FillingContainer_addItem(filling_container, leatherCap_instance);
ItemInstance *leatherShirt_instance = new ItemInstance;
ALLOC_CHECK(leatherShirt_instance);
leatherShirt_instance->count = 255;
leatherShirt_instance->auxiliary = 0;
leatherShirt_instance->id = 299;
FillingContainer_addItem(filling_container, leatherShirt_instance);
ItemInstance *leatherPants_instance = new ItemInstance;
ALLOC_CHECK(leatherPants_instance);
leatherPants_instance->count = 255;
leatherPants_instance->auxiliary = 0;
leatherPants_instance->id = 300;
FillingContainer_addItem(filling_container, leatherPants_instance);
ItemInstance *leatherBoots_instance = new ItemInstance;
ALLOC_CHECK(leatherBoots_instance);
leatherBoots_instance->count = 255;
leatherBoots_instance->auxiliary = 0;
leatherBoots_instance->id = 301;
FillingContainer_addItem(filling_container, leatherBoots_instance);
ItemInstance *chainHelm_instance = new ItemInstance;
ALLOC_CHECK(chainHelm_instance);
chainHelm_instance->count = 255;
chainHelm_instance->auxiliary = 0;
chainHelm_instance->id = 302;
FillingContainer_addItem(filling_container, chainHelm_instance);
ItemInstance *chainShirt_instance = new ItemInstance;
ALLOC_CHECK(chainShirt_instance);
chainShirt_instance->count = 255;
chainShirt_instance->auxiliary = 0;
chainShirt_instance->id = 303;
FillingContainer_addItem(filling_container, chainShirt_instance);
ItemInstance *chainLegs_instance = new ItemInstance;
ALLOC_CHECK(chainLegs_instance);
chainLegs_instance->count = 255;
chainLegs_instance->auxiliary = 0;
chainLegs_instance->id = 304;
FillingContainer_addItem(filling_container, chainLegs_instance);
ItemInstance *chainBoots_instance = new ItemInstance;
ALLOC_CHECK(chainBoots_instance);
chainBoots_instance->count = 255;
chainBoots_instance->auxiliary = 0;
chainBoots_instance->id = 305;
FillingContainer_addItem(filling_container, chainBoots_instance);
ItemInstance *goldHelm_instance = new ItemInstance;
ALLOC_CHECK(goldHelm_instance);
goldHelm_instance->count = 255;
goldHelm_instance->auxiliary = 0;
goldHelm_instance->id = 314;
FillingContainer_addItem(filling_container, goldHelm_instance);
ItemInstance *goldChest_instance = new ItemInstance;
ALLOC_CHECK(goldChest_instance);
goldChest_instance->count = 255;
goldChest_instance->auxiliary = 0;
goldChest_instance->id = 315;
FillingContainer_addItem(filling_container, goldChest_instance);
ItemInstance *goldLegs_instance = new ItemInstance;
ALLOC_CHECK(goldLegs_instance);
goldLegs_instance->count = 255;
goldLegs_instance->auxiliary = 0;
goldLegs_instance->id = 316;
FillingContainer_addItem(filling_container, goldLegs_instance);
ItemInstance *goldBoots_instance = new ItemInstance;
ALLOC_CHECK(goldBoots_instance);
goldBoots_instance->count = 255;
goldBoots_instance->auxiliary = 0;
goldBoots_instance->id = 317;
FillingContainer_addItem(filling_container, goldBoots_instance);
ItemInstance *ironHelm_instance = new ItemInstance;
ALLOC_CHECK(ironHelm_instance);
ironHelm_instance->count = 255;
ironHelm_instance->auxiliary = 0;
ironHelm_instance->id = 306;
FillingContainer_addItem(filling_container, ironHelm_instance);
ItemInstance *ironChest_instance = new ItemInstance;
ALLOC_CHECK(ironChest_instance);
ironChest_instance->count = 255;
ironChest_instance->auxiliary = 0;
ironChest_instance->id = 307;
FillingContainer_addItem(filling_container, ironChest_instance);
ItemInstance *ironLegs_instance = new ItemInstance;
ALLOC_CHECK(ironLegs_instance);
ironLegs_instance->count = 255;
ironLegs_instance->auxiliary = 0;
ironLegs_instance->id = 308;
FillingContainer_addItem(filling_container, ironLegs_instance);
ItemInstance *ironBoots_instance = new ItemInstance;
ALLOC_CHECK(ironBoots_instance);
ironBoots_instance->count = 255;
ironBoots_instance->auxiliary = 0;
ironBoots_instance->id = 309;
FillingContainer_addItem(filling_container, ironBoots_instance);
ItemInstance *flint2_instance = new ItemInstance;
ALLOC_CHECK(flint2_instance);
flint2_instance->count = 255;
flint2_instance->auxiliary = 0;
flint2_instance->id = 318;
FillingContainer_addItem(filling_container, flint2_instance);
ItemInstance *porkRaw_instance = new ItemInstance;
ALLOC_CHECK(porkRaw_instance);
porkRaw_instance->count = 255;
porkRaw_instance->auxiliary = 0;
porkRaw_instance->id = 319;
FillingContainer_addItem(filling_container, porkRaw_instance);
ItemInstance *leather_instance = new ItemInstance;
ALLOC_CHECK(leather_instance);
leather_instance->count = 255;
leather_instance->auxiliary = 0;
leather_instance->id = 334;
FillingContainer_addItem(filling_container, leather_instance);
ItemInstance *clayBrick_instance = new ItemInstance;
ALLOC_CHECK(clayBrick_instance);
clayBrick_instance->count = 255;
clayBrick_instance->auxiliary = 0;
clayBrick_instance->id = 336;
FillingContainer_addItem(filling_container, clayBrick_instance);
ItemInstance *clay_instance = new ItemInstance;
ALLOC_CHECK(clay_instance);
clay_instance->count = 255;
clay_instance->auxiliary = 0;
clay_instance->id = 337;
FillingContainer_addItem(filling_container, clay_instance);
ItemInstance *notepad_instance = new ItemInstance;
ALLOC_CHECK(notepad_instance);
notepad_instance->count = 255;
notepad_instance->auxiliary = 0;
notepad_instance->id = 339;
FillingContainer_addItem(filling_container, notepad_instance);
ItemInstance *book_instance = new ItemInstance;
ALLOC_CHECK(book_instance);
book_instance->count = 255;
book_instance->auxiliary = 0;
book_instance->id = 340;
FillingContainer_addItem(filling_container, book_instance);
ItemInstance *slimeball_instance = new ItemInstance;
ALLOC_CHECK(slimeball_instance);
slimeball_instance->count = 255;
slimeball_instance->auxiliary = 0;
slimeball_instance->id = 341;
FillingContainer_addItem(filling_container, slimeball_instance);
ItemInstance *compass_instance = new ItemInstance;
ALLOC_CHECK(compass_instance);
compass_instance->count = 255;
compass_instance->auxiliary = 0;
compass_instance->id = 345;
FillingContainer_addItem(filling_container, compass_instance);
ItemInstance *clock_instance = new ItemInstance;
ALLOC_CHECK(clock_instance);
clock_instance->count = 255;
clock_instance->auxiliary = 0;
clock_instance->id = 347;
FillingContainer_addItem(filling_container, clock_instance);
ItemInstance *glowDust_instance = new ItemInstance;
ALLOC_CHECK(glowDust_instance);
glowDust_instance->count = 255;
glowDust_instance->auxiliary = 0;
glowDust_instance->id = 348;
FillingContainer_addItem(filling_container, glowDust_instance);
ItemInstance *bone_instance = new ItemInstance;
ALLOC_CHECK(bone_instance);
bone_instance->count = 255;
bone_instance->auxiliary = 0;
bone_instance->id = 352;
FillingContainer_addItem(filling_container, bone_instance);
ItemInstance *sugar_instance = new ItemInstance;
ALLOC_CHECK(sugar_instance);
sugar_instance->count = 255;
sugar_instance->auxiliary = 0;
sugar_instance->id = 353;
FillingContainer_addItem(filling_container, sugar_instance);
ItemInstance *melon_instance = new ItemInstance;
ALLOC_CHECK(melon_instance);
melon_instance->count = 255;
melon_instance->auxiliary = 0;
melon_instance->id = 360;
FillingContainer_addItem(filling_container, melon_instance);
ItemInstance *beefRaw_instance = new ItemInstance;
ALLOC_CHECK(beefRaw_instance);
beefRaw_instance->count = 255;
beefRaw_instance->auxiliary = 0;
beefRaw_instance->id = 363;
FillingContainer_addItem(filling_container, beefRaw_instance);
ItemInstance *chickenRaw_instance = new ItemInstance;
ALLOC_CHECK(chickenRaw_instance);
chickenRaw_instance->count = 255;
chickenRaw_instance->auxiliary = 0;
chickenRaw_instance->id = 365;
FillingContainer_addItem(filling_container, chickenRaw_instance);
}
// Init
__attribute__((constructor)) static void init_expanded_creative() {
INFO("Loading Expanded Creative Mod");
misc_run_on_creative_inventory_setup(Inventory_setupDefault_FillingContainer_addItem_call_injection);
}

15
example-mods/recipes/.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
/out
/debian/tmp
/.vscode
/build*
/CMakeLists.txt.user
*.autosave
/AppImageBuilder.yml
/appimage-builder-cache
/appimage-build
/AppDir
/*.zsync
/*.AppImage
/core*
/qemu_*
/cmake/.prebuilt-armhf-toolchain

View File

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.16.0)
# Build For ARM
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "arm")
# Start Project
project(recipes)
# Include SDK
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cmake")
# Build
add_library(recipes SHARED recipes.cpp)
target_link_libraries(recipes mods reborn-util symbols)

View File

@ -0,0 +1,57 @@
// Headers
#include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#include <mods/misc/misc.h>
// Custom Crafting Recipes
static void Recipes_injection(Recipes *recipes) {
// Add
Recipes_Type type1 = {
.item = 0,
.tile = 0,
.instance = {
.count = 1,
.id = 12,
.auxiliary = 0
},
.letter = 'a'
};
Recipes_Type type2 = {
.item = 0,
.tile = 0,
.instance = {
.count = 1,
.id = 13,
.auxiliary = 0
},
.letter = 'b'
};
ItemInstance result = {
.count = 1,
.id = 344,
.auxiliary = 0
};
std::vector<Recipes_Type> types = {type1, type2};
Recipes_addShapelessRecipe(recipes, &result, &types);
}
// Custom Furnace Recipes
static void FurnaceRecipes_injection(FurnaceRecipes *recipes) {
// Add
ItemInstance result = {
.count = 1,
.id = 246,
.auxiliary = 0
};
FurnaceRecipes_addFurnaceRecipe(recipes, 49, &result);
}
// Init
__attribute__((constructor)) static void init_recipes() {
// Log
INFO("Loading Custom Recipes");
// Setup
misc_run_on_recipes_setup(Recipes_injection);
misc_run_on_furnace_recipes_setup(FurnaceRecipes_injection);
}

31
images/CMakeLists.txt Normal file
View File

@ -0,0 +1,31 @@
project(images)
# Title Background
if(NOT MCPI_HEADLESS_MODE)
install(
FILES "background.png"
DESTINATION "${MCPI_INSTALL_DIR}/data/images/gui"
RENAME "titleBG.png"
)
endif()
# Chest Model
if(NOT MCPI_HEADLESS_MODE)
install(
FILES "chest.png"
DESTINATION "${MCPI_INSTALL_DIR}/data/images/item"
)
endif()
# Icon
install(
FILES "icon.png"
DESTINATION "${MCPI_SHARE_DIR}/icons/hicolor/scalable/apps"
RENAME "${MCPI_APP_ID}.png"
)
# AppImage
if(MCPI_IS_APPIMAGE_BUILD)
install_symlink("${MCPI_SHARE_DIR}/icons/hicolor/scalable/apps/${MCPI_APP_ID}.png" "${MCPI_APP_ID}.png")
install_symlink("${MCPI_APP_ID}.png" ".DirIcon")
endif()

BIN
images/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

BIN
images/chest.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
images/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 164 KiB

View File

@ -1,18 +1,125 @@
project(launcher)
# Launcher
if(BUILD_NATIVE_COMPONENTS)
add_executable(launcher src/bootstrap.c src/ldconfig.cpp)
if(MCPI_SERVER_MODE)
target_sources(launcher PRIVATE src/server/launcher.c)
else()
target_sources(launcher PRIVATE src/client/launcher.cpp)
endif()
target_link_libraries(launcher reborn-headers)
# Install
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")
install_symlink("../../${MCPI_INSTALL_DIR}/launcher" "usr/bin/${MCPI_VARIANT_NAME}")
if(NOT MCPI_SERVER_MODE)
install(DIRECTORY "client-data/" DESTINATION ".")
endif()
add_executable(launcher
src/bootstrap.c
src/patchelf.cpp
src/util.c
src/crash-report.c
src/sdk.c
src/mods.c
)
if(MCPI_SERVER_MODE)
target_sources(launcher PRIVATE src/server/launcher.c)
else()
embed_resource(launcher src/client/available-feature-flags)
target_sources(launcher PRIVATE
src/client/launcher.cpp
src/client/cache.cpp
src/client/available-feature-flags # Show In IDE
)
endif()
target_link_libraries(launcher reborn-util LIB_LIEF)
# RPath
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
# Install
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")
install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_VARIANT_NAME}")
# Install Desktop Entry
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
"[Desktop Entry]\n"
"Name=${MCPI_APP_TITLE}\n"
"Comment=Fun with Blocks\n"
"Icon=${MCPI_APP_ID}\n"
"Exec=${MCPI_VARIANT_NAME}\n"
"Type=Application\n"
"Categories=Game;\n"
)
if(MCPI_HEADLESS_MODE)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
"Terminal=true\n"
"NoDisplay=true\n"
)
else()
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
"Terminal=false\n"
"StartupNotify=false\n"
"StartupWMClass=${MCPI_APP_ID}\n"
)
endif()
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
DESTINATION "${MCPI_SHARE_DIR}/applications"
RENAME "${MCPI_APP_ID}.desktop"
)
# Install AppStream Metadata
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<component type=\"desktop\">\n"
" <id>${MCPI_APP_ID}</id>\n"
" <name>${MCPI_APP_TITLE}</name>\n"
" <metadata_license>CC0-1.0</metadata_license>\n"
" <summary>Fun with Blocks</summary>\n"
" <description>\n"
" <p>Minecraft: Pi Edition Modding Project.</p>\n"
" <p>NOTE: This is not verified by, affiliated with, or supported by Mojang or Microsoft.</p>\n"
" </description>\n"
" <url type=\"homepage\">https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn</url>\n"
" <launchable type=\"desktop-id\">${MCPI_APP_ID}.desktop</launchable>\n"
" <provides>\n"
" <id>com.thebrokenrail.MCPIRebornClient.desktop</id>\n"
" </provides>\n"
" <project_license>LicenseRef-proprietary</project_license>\n"
" <developer_name>TheBrokenRail &amp; Mojang AB</developer_name>\n"
" <content_rating type=\"oars-1.0\">\n"
" <content_attribute id=\"violence-cartoon\">moderate</content_attribute>\n"
" <content_attribute id=\"violence-fantasy\">none</content_attribute>\n"
" <content_attribute id=\"violence-realistic\">none</content_attribute>\n"
" <content_attribute id=\"violence-bloodshed\">none</content_attribute>\n"
" <content_attribute id=\"violence-sexual\">none</content_attribute>\n"
" <content_attribute id=\"drugs-alcohol\">none</content_attribute>\n"
" <content_attribute id=\"drugs-narcotics\">none</content_attribute>\n"
" <content_attribute id=\"drugs-tobacco\">none</content_attribute>\n"
" <content_attribute id=\"sex-nudity\">none</content_attribute>\n"
" <content_attribute id=\"sex-themes\">none</content_attribute>\n"
" <content_attribute id=\"language-profanity\">none</content_attribute>\n"
" <content_attribute id=\"language-humor\">none</content_attribute>\n"
" <content_attribute id=\"language-discrimination\">none</content_attribute>\n"
" <content_attribute id=\"social-chat\">intense</content_attribute>\n"
" <content_attribute id=\"social-info\">none</content_attribute>\n"
" <content_attribute id=\"social-audio\">none</content_attribute>\n"
" <content_attribute id=\"social-location\">none</content_attribute>\n"
" <content_attribute id=\"social-contacts\">none</content_attribute>\n"
" <content_attribute id=\"money-purchasing\">none</content_attribute>\n"
" <content_attribute id=\"money-gambling\">none</content_attribute>\n"
" </content_rating>\n"
" <releases>\n"
" <release version=\"${MCPI_VERSION}\" date=\"${MCPI_VERSION_DATE}\"></release>\n"
" </releases>\n"
)
if(NOT MCPI_HEADLESS_MODE)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
" <screenshots>\n"
" <screenshot type=\"default\">\n"
" <image>https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn/raw/branch/master/images/start.png</image>\n"
" </screenshot>\n"
" </screenshots>\n"
)
endif()
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
"</component>\n"
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
DESTINATION "${MCPI_SHARE_DIR}/metainfo"
RENAME "${MCPI_APP_ID}.appdata.xml"
)
# AppImage
if(MCPI_IS_APPIMAGE_BUILD)
install_symlink("bin/${MCPI_VARIANT_NAME}" "AppRun")
install_symlink("${MCPI_SHARE_DIR}/applications/${MCPI_APP_ID}.desktop" "${MCPI_APP_ID}.desktop")
endif()

View File

@ -1,26 +0,0 @@
TRUE Touch GUI
TRUE Fix Bow & Arrow
TRUE Fix Attacking
FALSE Force Mob Spawning
TRUE Fancy Graphics
TRUE Disable Autojump By Default
TRUE Display Nametags By Default
TRUE Fix Sign Placement
TRUE Show Block Outlines
FALSE Expand Creative Inventory
FALSE Peaceful Mode
TRUE Animated Water
TRUE Remove Invalid Item Background
TRUE Disable "gui_blocks" Atlas
TRUE Smooth Lighting
FALSE 3D Anaglyph
TRUE Fix Camera Rendering
TRUE Implement Chat
TRUE Implement Death Messages
TRUE Implement Game-Mode Switching
TRUE Miscellaneous Input Fixes
TRUE Bind "Q" Key To Item Dropping
TRUE Bind Common Toggleable Options To Function Keys
TRUE Render Selected Item Text
TRUE External Server Support
TRUE Load Language Files

View File

@ -1,10 +0,0 @@
[Desktop Entry]
Name=Minecraft: Pi Edition: Reborn
Comment=Fun with Blocks
Icon=/usr/share/pixmaps/minecraft-pi-reborn-client.png
StartupNotify=false
StartupWMClass=Minecraft: Pi Edition: Reborn
Exec=/usr/bin/minecraft-pi-reborn-client
Terminal=false
Type=Application
Categories=Application;Game;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

View File

@ -1,222 +1,361 @@
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <libreborn/libreborn.h>
#include "util.h"
#include "bootstrap.h"
#include "ldconfig.h"
#include "patchelf.h"
#include "crash-report.h"
// Set Environmental Variable
#define PRESERVE_ENVIRONMENTAL_VARIABLE(name) \
{ \
char *original_env_value = getenv(name); \
if (original_env_value != NULL) { \
setenv("ORIGINAL_" name, original_env_value, 1); \
} \
#define MCPI_BINARY "minecraft-pi"
#define QEMU_BINARY "qemu-arm"
#define REQUIRED_PAGE_SIZE 4096
#define _STR(x) #x
#define STR(x) _STR(x)
// Exit Handler
static void exit_handler(__attribute__((unused)) int signal_id) {
// Pass Signal To Child
murder_children();
while (wait(NULL) > 0) {}
_exit(EXIT_SUCCESS);
}
// Debug Information
static void run_debug_command(const char *const command[], const char *prefix) {
int status = 0;
char *output = run_command(command, &status, NULL);
if (output != NULL) {
// Remove Newline
size_t length = strlen(output);
if (length > 0 && output[length - 1] == '\n') {
output[length - 1] = '\0';
}
// Print
DEBUG("%s: %s", prefix, output);
free(output);
}
static void trim(char **value) {
// Remove Trailing Colon
int length = strlen(*value);
if ((*value)[length - 1] == ':') {
(*value)[length - 1] = '\0';
}
if ((*value)[0] == ':') {
*value = &(*value)[1];
if (!is_exit_status_success(status)) {
ERR("Unable To Gather Debug Information");
}
}
static void set_and_print_env(const char *name, char *value) {
// Set Variable With No Trailing Colon
trim(&value);
static void print_debug_information() {
// System Information
const char *const command[] = {"uname", "-a", NULL};
run_debug_command(command, "System Information");
#ifdef DEBUG
// Print New Value
INFO("Set %s = %s", name, value);
// Version
DEBUG("Reborn Version: v%s", MCPI_VERSION);
// Architecture
const char *arch = "Unknown";
#ifdef __x86_64__
arch = "AMD64";
#elif defined(__aarch64__)
arch = "ARM64";
#elif defined(__arm__)
arch = "ARM32";
#endif
// Set The Value
setenv(name, value, 1);
DEBUG("Reborn Target Architecture: %s", arch);
}
// Get Environmental Variable
static char *get_env_safe(const char *name) {
// Get Variable Or Blank String If Not Set
char *ret = getenv(name);
return ret != NULL ? ret : "";
}
// Pre-Bootstrap
void pre_bootstrap(int argc, char *argv[]) {
// Set Debug Tag
reborn_debug_tag = "(Launcher) ";
// Get All Mods In Folder
static void load(char **ld_preload, char *folder) {
int folder_name_length = strlen(folder);
// Retry Until Successful
while (1) {
// Open Folder
DIR *dp = opendir(folder);
if (dp != NULL) {
// Loop Through Folder
struct dirent *entry = NULL;
errno = 0;
while (1) {
errno = 0;
entry = readdir(dp);
if (entry != NULL) {
// Check If File Is Regular
if (entry->d_type == DT_REG) {
// Get Full Name
int name_length = strlen(entry->d_name);
int total_length = folder_name_length + name_length;
char name[total_length + 1];
// Disable stdout Buffering
setvbuf(stdout, NULL, _IONBF, 0);
// Concatenate Folder Name And File Name
for (int i = 0; i < folder_name_length; i++) {
name[i] = folder[i];
}
for (int i = 0; i < name_length; i++) {
name[folder_name_length + i] = entry->d_name[i];
}
// Add Terminator
name[total_length] = '\0';
// Check If File Is Executable
int result = access(name, R_OK);
if (result == 0) {
// Add To LD_PRELOAD
string_append(ld_preload, ":%s", name);
} else if (result == -1 && errno != 0) {
// Fail
INFO("Unable To Acesss: %s: %s", name, strerror(errno));
errno = 0;
}
}
} else if (errno != 0) {
// Error Reading Contents Of Folder
ERR("Error Reading Directory: %s: %s", folder, strerror(errno));
} else {
// Done!
break;
}
}
// Close Folder
closedir(dp);
// Exit Function
return;
} else if (errno == ENOENT) {
// Folder Doesn't Exists, Attempt Creation
int ret = mkdir(folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (ret != 0) {
// Unable To Create Folder
ERR("Error Creating Directory: %s: %s", folder, strerror(errno));
}
// Continue Retrying
} else {
// Unable To Open Folder
ERR("Error Opening Directory: %s: %s", folder, strerror(errno));
// Print Version
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0) {
// Print
printf("Reborn v%s\n", MCPI_VERSION);
fflush(stdout);
exit(EXIT_SUCCESS);
}
}
}
#define MCPI_NAME "minecraft-pi"
// Setup Logging
setup_log_file();
// --debug
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--debug") == 0) {
set_and_print_env("MCPI_DEBUG", "1");
break;
}
}
// Set Default Native Component Environment
#define set_variable_default(name) set_and_print_env("MCPI_NATIVE_" name, getenv(name));
for_each_special_environmental_variable(set_variable_default);
// GTK Dark Mode
#ifndef MCPI_SERVER_MODE
set_and_print_env("GTK_THEME", "Adwaita:dark");
#endif
// Configure PATH
{
// Get Binary Directory
char *binary_directory = get_binary_directory();
// Add Library Directory
char *new_path = NULL;
safe_asprintf(&new_path, "%s/bin", binary_directory);
// Add Existing PATH
{
char *value = getenv("PATH");
if (value != NULL && strlen(value) > 0) {
string_append(&new_path, ":%s", value);
}
}
// Set And Free
set_and_print_env("PATH", new_path);
free(new_path);
// Free Binary Directory
free(binary_directory);
}
// --copy-sdk
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--copy-sdk") == 0) {
char *binary_directory = get_binary_directory();
copy_sdk(binary_directory, 0);
free(binary_directory);
fflush(stdout);
exit(EXIT_SUCCESS);
}
}
// Setup Crash Reports
setup_crash_report();
// AppImage
#ifdef MCPI_IS_APPIMAGE_BUILD
{
char *owd = getenv("OWD");
if (owd != NULL && chdir(owd) != 0) {
ERR("AppImage: Unable To Fix Current Directory: %s", strerror(errno));
}
}
#endif
// Install Signal Handlers
struct sigaction act_sigint;
memset((void *) &act_sigint, 0, sizeof (struct sigaction));
act_sigint.sa_flags = SA_RESTART;
act_sigint.sa_handler = &exit_handler;
sigaction(SIGINT, &act_sigint, NULL);
struct sigaction act_sigterm;
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
act_sigterm.sa_flags = SA_RESTART;
act_sigterm.sa_handler = &exit_handler;
sigaction(SIGTERM, &act_sigterm, NULL);
// Check Page Size (Not Needed When Using QEMU)
#ifndef MCPI_USE_QEMU
long page_size = sysconf(_SC_PAGESIZE);
if (page_size != REQUIRED_PAGE_SIZE) {
ERR("Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
}
#endif
// Debug Information
print_debug_information();
}
// Bootstrap
void bootstrap(int argc, char *argv[]) {
INFO("%s", "Configuring Game...");
INFO("Configuring Game...");
// Get Binary Directory
char *binary_directory = get_binary_directory();
DEBUG("Binary Directory: %s", binary_directory);
// Configure LD_LIBRARY_PATH
// Copy SDK
copy_sdk(binary_directory, 1);
// Set MCPI_REBORN_ASSETS_PATH
{
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH");
// Add Library Directory
char *new_ld_path;
safe_asprintf(&new_ld_path, "%s/lib", binary_directory);
// Add Existing LD_LIBRAR_PATH
{
char *value = get_env_safe("LD_LIBRARY_PATH");
if (strlen(value) > 0) {
string_append(&new_ld_path, ":%s", value);
}
}
// Load ARM Libraries
#ifdef __ARM_ARCH
string_append(&new_ld_path, "%s", ":/usr/lib/arm-linux-gnueabihf:/usr/arm-linux-gnueabihf/lib");
#endif
// Add Full Library Search Path
{
char *value = get_full_library_search_path();
if (strlen(value) > 0) {
string_append(&new_ld_path, ":%s", value);
}
free(value);
}
// Add Fallback Library Directory
string_append(&new_ld_path, ":%s/fallback-lib", binary_directory);
// Set And Free
set_and_print_env("LD_LIBRARY_PATH", new_ld_path);
free(new_ld_path);
char *assets_path = realpath("/proc/self/exe", NULL);
ALLOC_CHECK(assets_path);
chop_last_component(&assets_path);
string_append(&assets_path, "/data");
set_and_print_env("MCPI_REBORN_ASSETS_PATH", assets_path);
free(assets_path);
}
// Configure LD_PRELOAD
// Resolve Binary Path & Set MCPI_DIRECTORY
char *resolved_path = NULL;
{
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_PRELOAD");
char *new_ld_preload = NULL;
safe_asprintf(&new_ld_preload, "%s", get_env_safe("LD_PRELOAD"));
// Log
DEBUG("Resolving File Paths...");
// Get Mods Folder
char *mods_folder = NULL;
safe_asprintf(&mods_folder, "%s/mods/", binary_directory);
// Load Mods From ./mods
load(&new_ld_preload, mods_folder);
// Free Mods Folder
free(mods_folder);
// Resolve Full Binary Path
char *full_path = NULL;
safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory);
resolved_path = realpath(full_path, NULL);
ALLOC_CHECK(resolved_path);
free(full_path);
}
// Set LD_PRELOAD
set_and_print_env("LD_PRELOAD", new_ld_preload);
free(new_ld_preload);
// Fix MCPI Dependencies
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
{
// Log
DEBUG("Patching ELF Dependencies...");
// Find Linker
char *linker = NULL;
// Select Linker
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
// Use ARM Sysroot Linker
safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory);
#else
// Use Current Linker
linker = patch_get_interpreter();
#endif
// Patch
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker);
// Free Linker Path
if (linker != NULL) {
free(linker);
}
// Verify
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
IMPOSSIBLE();
}
}
// Set MCPI_VANILLA_ASSETS_PATH
{
char *assets_path = strdup(resolved_path);
ALLOC_CHECK(assets_path);
chop_last_component(&assets_path);
string_append(&assets_path, "/data");
set_and_print_env("MCPI_VANILLA_ASSETS_PATH", assets_path);
free(assets_path);
}
// Free Resolved Path
free(resolved_path);
// Configure Library Search Path
{
// Log
DEBUG("Setting Linker Search Paths...");
// Prepare
char *transitive_ld_path = NULL;
char *mcpi_ld_path = NULL;
// Library Search Path For Native Components
{
// Add Native Library Directory
safe_asprintf(&transitive_ld_path, "%s/lib/native", binary_directory);
// Add Host LD_LIBRARY_PATH
{
char *value = getenv("LD_LIBRARY_PATH");
if (value != NULL && strlen(value) > 0) {
string_append(&transitive_ld_path, ":%s", value);
}
}
// Set
set_and_print_env("MCPI_NATIVE_LD_LIBRARY_PATH", transitive_ld_path);
free(transitive_ld_path);
}
// Library Search Path For ARM Components
{
// Add ARM Library Directory
safe_asprintf(&mcpi_ld_path, "%s/lib/arm", binary_directory);
// Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System)
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
string_append(&mcpi_ld_path, ":%s/sysroot/lib:%s/sysroot/lib/arm-linux-gnueabihf:%s/sysroot/usr/lib:%s/sysroot/usr/lib/arm-linux-gnueabihf", binary_directory, binary_directory, binary_directory, binary_directory);
#endif
// Add Host LD_LIBRARY_PATH
{
char *value = getenv("LD_LIBRARY_PATH");
if (value != NULL && strlen(value) > 0) {
string_append(&mcpi_ld_path, ":%s", value);
}
}
// Set
set_and_print_env("MCPI_ARM_LD_LIBRARY_PATH", mcpi_ld_path);
free(mcpi_ld_path);
}
}
// Configure Preloaded Objects
{
// Log
DEBUG("Locating Mods...");
// Native Components
char *host_ld_preload = getenv("LD_PRELOAD");
set_and_print_env("MCPI_NATIVE_LD_PRELOAD", host_ld_preload);
// ARM Components
bootstrap_mods(binary_directory);
}
// Free Binary Directory
free(binary_directory);
// Start Game
INFO("%s", "Starting Game...");
#ifdef __ARM_ARCH
// Create Arguments List
char *new_argv[argc + 1];
for (int i = 1; i <= argc; i++) {
new_argv[i] = argv[i];
}
new_argv[0] = NULL; // Updated By safe_execvpe()
// Run
safe_execvpe_relative_to_binary(MCPI_NAME, new_argv, environ);
#else
// Use Static QEMU So It Isn't Affected By LD_* Variables
#define QEMU_NAME "qemu-arm-static"
// Use Correct LibC
setenv("QEMU_LD_PREFIX", "/usr/arm-linux-gnueabihf", 1);
INFO("Starting Game...");
// Get Binary Directory
binary_directory = get_binary_directory();
// Create Full Path
char *full_path = NULL;
safe_asprintf(&full_path, "%s/" MCPI_NAME, binary_directory);
// Free Binary Directory
free(binary_directory);
// Arguments
int argv_start = 1; // argv = &new_args[argv_start]
const char *new_args[argv_start /* 1 Potential Prefix Argument (QEMU) */ + argc + 1 /* NULL-Terminator */]; //
// Create Arguments List
char *new_argv[argc + 2];
for (int i = 1; i <= argc; i++) {
new_argv[i + 1] = argv[i];
// Copy Existing Arguments
for (int i = 1; i < argc; i++) {
new_args[i + argv_start] = argv[i];
}
new_argv[0] = NULL; // Updated By safe_execvpe()
new_argv[1] = full_path; // Path To MCPI
// Run
safe_execvpe(QEMU_NAME, new_argv, environ);
// NULL-Terminator
new_args[argv_start + argc] = NULL;
// Set Executable Argument
new_args[argv_start] = new_mcpi_exe_path;
// Non-ARM Systems Need QEMU
#ifdef MCPI_USE_QEMU
argv_start--;
new_args[argv_start] = QEMU_BINARY;
// Use 4k Page Size
set_and_print_env("QEMU_PAGESIZE", STR(REQUIRED_PAGE_SIZE));
#endif
// Setup Environment
setup_exec_environment(1);
// Pass LD_* Variables Through QEMU
#ifdef MCPI_USE_QEMU
char *qemu_set_env = NULL;
#define pass_variable_through_qemu(name) string_append(&qemu_set_env, "%s%s=%s", qemu_set_env == NULL ? "" : ",", name, getenv(name));
for_each_special_environmental_variable(pass_variable_through_qemu);
set_and_print_env("QEMU_SET_ENV", qemu_set_env);
free(qemu_set_env);
// Treat QEMU Itself As A Native Component
setup_exec_environment(0);
#endif
// Run
const char **new_argv = &new_args[argv_start];
safe_execvpe(new_argv, (const char *const *) environ);
}

View File

@ -4,7 +4,10 @@
extern "C" {
#endif
void pre_bootstrap(int argc, char *argv[]);
void bootstrap(int argc, char *argv[]);
void copy_sdk(char *binary_directory, int log_with_debug);
void bootstrap_mods(char *binary_directory);
#ifdef __cplusplus
}

View File

@ -0,0 +1,63 @@
FALSE Full Touch GUI
TRUE Fix Bow & Arrow
TRUE Fix Attacking
FALSE Force Mob Spawning
TRUE Disable Autojump By Default
TRUE Display Nametags By Default
TRUE Fix Sign Placement
TRUE Show Block Outlines
FALSE Expand Creative Mode Inventory
FALSE Remove Creative Mode Restrictions
TRUE Animated Water
TRUE Animated Lava
TRUE Animated Fire
TRUE Remove Invalid Item Background
TRUE Disable "gui_blocks" Atlas
TRUE Fix Camera Rendering
TRUE Implement Chat
FALSE Hide Chat Messages
TRUE Implement Death Messages
TRUE Implement Game-Mode Switching
TRUE Allow Joining Survival Mode Servers
TRUE Miscellaneous Input Fixes
TRUE Bind "Q" Key To Item Dropping
TRUE Bind Common Toggleable Options To Function Keys
TRUE Render Selected Item Text
TRUE External Server Support
TRUE Load Language Files
TRUE Implement Sound Engine
TRUE Close Current Screen On Death
FALSE Disable Raw Mouse Motion (Not Recommended)
TRUE Fix Furnace Not Checking Item Auxiliary
TRUE Improved Cursor Rendering
TRUE Disable V-Sync
TRUE Fix Options Screen
TRUE Force Touch GUI Inventory
TRUE Fix Pause Menu
TRUE Add Title Screen Background
TRUE Force Touch GUI Button Behavior
TRUE Improved Button Hover Behavior
TRUE Implement Create World Dialog
FALSE Remove Forced GUI Lag (Can Break Joining Servers)
TRUE Add Buckets
TRUE Classic HUD
TRUE Translucent Toolbar
FALSE Force EGL
TRUE Improved Classic Title Screen
FALSE Disable Speed Bridging
FALSE Disable Creative Mode Mining Delay
FALSE Add Biome Colors To Grass
TRUE Generate Caves
FALSE Disable Block Tinting
TRUE Disable Hostile AI In Creative Mode
TRUE Load Custom Skins
TRUE 3D Chest Model
TRUE Replace Block Highlight With Outline
TRUE Add Cake
TRUE Use Java Beta 1.3 Light Ramp
TRUE Send Full Level When Hosting Game
FALSE Food Overlay
TRUE Add Splashes
TRUE Display Date In Select World Screen
TRUE Optimized Chunk Sorting
TRUE Disable Buggy Held Item Caching

View File

@ -0,0 +1,171 @@
#include <cstdlib>
#include <string>
#include <fstream>
#include <unordered_map>
#include <sstream>
#include <sys/stat.h>
#include <unistd.h>
#include <libreborn/libreborn.h>
#include "launcher.h"
#include "cache.h"
// Get Cache Path
static std::string get_cache_path() {
const char *home = getenv("HOME");
if (home == NULL) {
IMPOSSIBLE();
}
return std::string(home) + HOME_SUBDIRECTORY_FOR_GAME_DATA "/.launcher-cache";
}
// Load
launcher_cache empty_cache = {
.username = DEFAULT_USERNAME,
.render_distance = DEFAULT_RENDER_DISTANCE,
.feature_flags = {}
};
launcher_cache load_cache() {
// Log
DEBUG("Loading Launcher Cache...");
// Return Value
launcher_cache ret = empty_cache;
// Open File
std::ifstream stream(get_cache_path(), std::ios::in | std::ios::binary);
if (!stream) {
// Fail
struct stat s;
// No Warning If File Doesn't Exist
if (stat(get_cache_path().c_str(), &s) == 0) {
WARN("Unable To Open Launcher Cache For Loading");
}
} else {
// Lock File
int lock_fd = lock_file(get_cache_path().c_str());
// Check Version
unsigned char cache_version;
stream.read((char *) &cache_version, 1);
if (stream.eof() || cache_version != (unsigned char) CACHE_VERSION) {
// Fail
if (!stream.eof()) {
WARN("Invalid Launcher Cache Version (Expected: %i, Actual: %i)", (int) CACHE_VERSION, (int) cache_version);
} else {
WARN("Unable To Read Launcher Cache Version");
}
stream.close();
} else {
// Load Username And Render Distance
launcher_cache cache;
std::getline(stream, cache.username, '\0');
std::getline(stream, cache.render_distance, '\0');
// Load Feature Flags
std::string flag;
while (!stream.eof() && std::getline(stream, flag, '\0')) {
if (flag.length() > 0) {
unsigned char is_enabled = 0;
stream.read((char *) &is_enabled, 1);
cache.feature_flags[flag] = is_enabled != (unsigned char) 0;
}
stream.peek();
}
// Finish
stream.close();
if (!stream) {
// Fail
WARN("Failure While Loading Launcher Cache");
} else {
// Success
ret = cache;
}
}
// Unlock File
unlock_file(get_cache_path().c_str(), lock_fd);
}
// Return
return ret;
}
// Save
#define write_env_to_stream(stream, env) \
{ \
const char *env_value = getenv(env); \
if (env == NULL) { \
IMPOSSIBLE(); \
} \
stream.write(env_value, strlen(env_value) + 1); \
}
void save_cache() {
// Log
DEBUG("Saving Launcher Cache...");
// Open File
std::ofstream stream(get_cache_path(), std::ios::out | std::ios::binary);
if (!stream) {
// Fail
WARN("Unable To Open Launcher Cache For Saving");
} else {
// Lock File
int lock_fd = lock_file(get_cache_path().c_str());
// Save Cache Version
unsigned char cache_version = (unsigned char) CACHE_VERSION;
stream.write((const char *) &cache_version, 1);
// Save Username And Render Distance
write_env_to_stream(stream, "MCPI_USERNAME");
write_env_to_stream(stream, "MCPI_RENDER_DISTANCE");
// Save Feature Flags
std::unordered_map<std::string, bool> flags;
load_available_feature_flags([&flags](std::string flag) {
std::string stripped_flag = strip_feature_flag_default(flag, NULL);
flags[stripped_flag] = false;
});
{
const char *enabled_flags = getenv("MCPI_FEATURE_FLAGS");
if (enabled_flags == NULL) {
IMPOSSIBLE();
}
std::istringstream enabled_flags_stream(enabled_flags);
std::string flag;
while (std::getline(enabled_flags_stream, flag, '|')) {
if (flag.length() > 0) {
flags[flag] = true;
}
}
}
for (auto &it : flags) {
stream.write(it.first.c_str(), it.first.size() + 1);
unsigned char val = it.second ? (unsigned char) 1 : (unsigned char) 0;
stream.write((const char *) &val, 1);
}
// Finish
stream.close();
if (!stream.good()) {
WARN("Failure While Saving Launcher Cache");
}
// Unlock File
unlock_file(get_cache_path().c_str(), lock_fd);
}
}
// Wipe Cache
void wipe_cache() {
// Log
INFO("Wiping Launcher Cache...");
// Unlink File
if (unlink(get_cache_path().c_str()) != 0) {
WARN("Failure While Wiping Cache: %s", strerror(errno));
}
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <string>
#include <unordered_map>
// Cache Version
#define CACHE_VERSION 0
// Load Cache
typedef struct {
std::string username;
std::string render_distance;
std::unordered_map<std::string, bool> feature_flags;
} launcher_cache;
extern launcher_cache empty_cache;
launcher_cache load_cache();
// Save Cache
void save_cache();
// Wipe Cache
void wipe_cache();

View File

@ -1,89 +1,92 @@
#include <fstream>
#include <sstream>
#include <cstring>
#include <cerrno>
#include <sys/wait.h>
#include <sys/stat.h>
#include <vector>
#include <functional>
#include <algorithm>
#include <libreborn/libreborn.h>
#include "../util.h"
#include "../bootstrap.h"
#include "launcher.h"
#include "cache.h"
// Strip Feature Flag Default
std::string strip_feature_flag_default(std::string flag, bool *default_ret) {
// Valid Values
std::string true_str = "TRUE ";
std::string false_str = "FALSE ";
// Test
if (flag.rfind(true_str, 0) == 0) {
// Enabled By Default
if (default_ret != NULL) {
*default_ret = true;
}
return flag.substr(true_str.length(), std::string::npos);
} else if (flag.rfind(false_str, 0) == 0) {
// Disabled By Default
if (default_ret != NULL) {
*default_ret = false;
}
return flag.substr(false_str.length(), std::string::npos);
} else {
// Invalid
ERR("Invalid Feature Flag Default");
}
}
// Load Available Feature Flags
static void load_available_feature_flags(std::function<void(std::string)> callback) {
extern unsigned char available_feature_flags[];
extern size_t available_feature_flags_len;
void load_available_feature_flags(std::function<void(std::string)> callback) {
// Get Path
char *binary_directory = get_binary_directory();
std::string path = std::string(binary_directory) + "/available-feature-flags";
free(binary_directory);
// Load File
std::ifstream stream(path);
if (stream && stream.good()) {
std::string data(available_feature_flags, available_feature_flags + available_feature_flags_len);
std::stringstream stream(data);
// Store Lines
std::vector<std::string> lines;
// Read File
{
std::string line;
while (std::getline(stream, line)) {
if (line.length() > 0) {
// Verify Line
if (line.find('|') == std::string::npos) {
callback(line);
lines.push_back(line);
} else {
// Invalid Line
ERR("%s", "Feature Flag Contains Invalid '|'");
ERR("Feature Flag Contains Invalid '|'");
}
}
}
stream.close();
} else {
ERR("%s", "Unable To Load Available Feature Flags");
}
// Sort
std::sort(lines.begin(), lines.end(), [](std::string a, std::string b) {
// Strip Defaults
std::string stripped_a = strip_feature_flag_default(a, NULL);
std::string stripped_b = strip_feature_flag_default(b, NULL);
// Sort
return stripped_a < stripped_b;
});
// Run Callbacks
for (std::string &line : lines) {
callback(line);
}
}
// Run Command And Get Output
static char *run_command(char *command[], int *return_code) {
// Store Output
int output_pipe[2];
safe_pipe2(output_pipe, 0);
// Run
pid_t ret = fork();
if (ret == -1) {
ERR("Unable To Run Command: %s", strerror(errno));
} else if (ret == 0) {
// Child Process
// Pipe stdout
dup2(output_pipe[1], STDOUT_FILENO);
close(output_pipe[0]);
close(output_pipe[1]);
// Run
safe_execvpe(command[0], command, environ);
} else {
// Parent Process
// Read stdout
close(output_pipe[1]);
char *output = NULL;
char c;
int bytes_read = 0;
while ((bytes_read = read(output_pipe[0], (void *) &c, 1)) > 0) {
string_append(&output, "%c", c);
}
close(output_pipe[0]);
// Get Return Code
int status;
waitpid(ret, &status, 0);
*return_code = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
// Return
return output;
}
}
// Run Command And Set Environmental Variable
static void run_command_and_set_env(const char *env_name, char *command[]) {
static void run_command_and_set_env(const char *env_name, const char *command[]) {
// Only Run If Environmental Variable Is NULL
if (getenv(env_name) == NULL) {
// Run
int return_code;
char *output = run_command(command, &return_code);
char *output = run_command(command, &return_code, NULL);
if (output != NULL) {
// Trim
int length = strlen(output);
@ -91,22 +94,28 @@ static void run_command_and_set_env(const char *env_name, char *command[]) {
output[length - 1] = '\0';
}
// Set
setenv(env_name, output, 1);
set_and_print_env(env_name, output);
// Free
free(output);
}
// Check Return Code
if (return_code != 0) {
ERR("%s", "Launch Interrupted");
if (!is_exit_status_success(return_code)) {
// Launch Interrupted
exit(EXIT_SUCCESS);
}
}
}
// Use Zenity To Set Environmental Variable
#define DIALOG_TITLE "Launcher"
static void run_zenity_and_set_env(const char *env_name, std::vector<std::string> command) {
// Create Full Command
std::vector<std::string> full_command;
full_command.push_back("zenity");
full_command.push_back("--class");
full_command.push_back("Minecraft: Pi Edition: Reborn");
full_command.push_back("--title");
full_command.push_back(DIALOG_TITLE);
full_command.push_back("--name");
full_command.push_back(MCPI_APP_ID);
full_command.insert(full_command.end(), command.begin(), command.end());
// Convert To C Array
const char *full_command_array[full_command.size() + 1];
@ -115,11 +124,39 @@ static void run_zenity_and_set_env(const char *env_name, std::vector<std::string
}
full_command_array[full_command.size()] = NULL;
// Run
run_command_and_set_env(env_name, (char **) full_command_array);
run_command_and_set_env(env_name, full_command_array);
}
// Set Variable If Not Already Set
static void set_env_if_unset(const char *env_name, std::function<std::string()> callback) {
if (getenv(env_name) == NULL) {
char *value = strdup(callback().c_str());
ALLOC_CHECK(value);
set_and_print_env(env_name, value);
free(value);
}
}
// Launch
#define LIST_DIALOG_SIZE "400"
int main(int argc, char *argv[]) {
// Don't Run As Root
if (getenv("_MCPI_SKIP_ROOT_CHECK") == NULL && (getuid() == 0 || geteuid() == 0)) {
ERR("Don't Run As Root");
}
// Ensure HOME
if (getenv("HOME") == NULL) {
ERR("$HOME Isn't Set");
}
// Check For Display
#ifndef MCPI_HEADLESS_MODE
if (getenv("DISPLAY") == NULL && getenv("WAYLAND_DISPLAY") == NULL) {
ERR("No display attached! Make sure $DISPLAY or $WAYLAND_DISPLAY is set.");
}
#endif
// Print Features
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--print-available-feature-flags") == 0) {
@ -132,52 +169,103 @@ int main(int argc, char *argv[]) {
}
}
// Pre-Bootstrap
pre_bootstrap(argc, argv);
// Create ~/.minecraft-pi If Needed
// Minecraft Folder
{
char *minecraft_folder = NULL;
asprintf(&minecraft_folder, "%s/.minecraft-pi", getenv("HOME"));
ALLOC_CHECK(minecraft_folder);
{
// Check Minecraft Folder
struct stat obj;
if (stat(minecraft_folder, &obj) != 0 || !S_ISDIR(obj.st_mode)) {
// Create Minecraft Folder
int ret = mkdir(minecraft_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (ret != 0) {
// Unable To Create Folder
ERR("Error Creating Directory: %s: %s", minecraft_folder, strerror(errno));
}
}
}
safe_asprintf(&minecraft_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA, getenv("HOME"));
const char *const command[] = {"mkdir", "-p", minecraft_folder, NULL};
run_simple_command(command, "Unable To Create Data Directory");
free(minecraft_folder);
}
// --wipe-cache
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--wipe-cache") == 0) {
wipe_cache();
break;
}
}
// --no-cache
bool no_cache = false;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--no-cache") == 0) {
no_cache = true;
break;
}
}
// Load Cache
launcher_cache cache = no_cache ? empty_cache : load_cache();
// --default
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--default") == 0) {
// Use Default Feature Flags
set_env_if_unset("MCPI_FEATURE_FLAGS", [&cache]() {
std::string feature_flags = "";
load_available_feature_flags([&feature_flags, &cache](std::string flag) {
bool value;
// Strip Default Value
std::string stripped_flag = strip_feature_flag_default(flag, &value);
// Use Cache
if (cache.feature_flags.count(stripped_flag) > 0) {
value = cache.feature_flags[stripped_flag];
}
// Specify Default Value
if (value) {
// Enabled By Default
feature_flags += stripped_flag + '|';
}
});
if (feature_flags.length() > 0 && feature_flags[feature_flags.length() - 1] == '|') {
feature_flags.pop_back();
}
return feature_flags;
});
set_env_if_unset("MCPI_RENDER_DISTANCE", [&cache]() {
return cache.render_distance;
});
set_env_if_unset("MCPI_USERNAME", [&cache]() {
return cache.username;
});
break;
}
}
// Setup MCPI_FEATURE_FLAGS
{
std::vector<std::string> command;
command.push_back("--list");
command.push_back("--checklist");
command.push_back("--width");
command.push_back("400");
command.push_back(LIST_DIALOG_SIZE);
command.push_back("--height");
command.push_back("400");
command.push_back(LIST_DIALOG_SIZE);
command.push_back("--column");
command.push_back("Enabled");
command.push_back("--column");
command.push_back("Feature");
load_available_feature_flags([&command](std::string line) {
if (line.rfind("TRUE ", 0) == 0) {
load_available_feature_flags([&command, &cache](std::string flag) {
bool value;
// Strip Default Value
std::string stripped_flag = strip_feature_flag_default(flag, &value);
// Use Cache
if (cache.feature_flags.count(stripped_flag) > 0) {
value = cache.feature_flags[stripped_flag];
}
// Specify Default Value
if (value) {
// Enabled By Default
command.push_back("TRUE");
command.push_back(line.substr(5, std::string::npos));
} else if (line.rfind("FALSE ", 0) == 0) {
} else {
// Disabled By Default
command.push_back("FALSE");
command.push_back(line.substr(6, std::string::npos));
} else {
ERR("%s", "Invalid Feature Flag Default");
}
// Specify Name
command.push_back(stripped_flag);
});
// Run
run_zenity_and_set_env("MCPI_FEATURE_FLAGS", command);
@ -188,23 +276,20 @@ int main(int argc, char *argv[]) {
command.push_back("--list");
command.push_back("--radiolist");
command.push_back("--width");
command.push_back("400");
command.push_back(LIST_DIALOG_SIZE);
command.push_back("--height");
command.push_back("400");
command.push_back(LIST_DIALOG_SIZE);
command.push_back("--text");
command.push_back("Minecraft Render Distance:");
command.push_back("Select Minecraft Render Distance:");
command.push_back("--column");
command.push_back("Selected");
command.push_back("--column");
command.push_back("Name");
command.push_back("FALSE");
command.push_back("Far");
command.push_back("FALSE");
command.push_back("Normal");
command.push_back("TRUE");
command.push_back("Short");
command.push_back("FALSE");
command.push_back("Tiny");
std::string render_distances[] = {"Far", "Normal", "Short", "Tiny"};
for (std::string &render_distance : render_distances) {
command.push_back(render_distance.compare(cache.render_distance) == 0 ? "TRUE" : "FALSE");
command.push_back(render_distance);
}
// Run
run_zenity_and_set_env("MCPI_RENDER_DISTANCE", command);
}
@ -213,13 +298,18 @@ int main(int argc, char *argv[]) {
std::vector<std::string> command;
command.push_back("--entry");
command.push_back("--text");
command.push_back("Minecraft Username:");
command.push_back("Enter Minecraft Username:");
command.push_back("--entry-text");
command.push_back("StevePi");
command.push_back(cache.username);
// Run
run_zenity_and_set_env("MCPI_USERNAME", command);
}
// Save Cache
if (!no_cache) {
save_cache();
}
// Bootstrap
bootstrap(argc, argv);
}

View File

@ -0,0 +1,12 @@
#pragma once
#include <string>
#include <functional>
// Defaults
#define DEFAULT_USERNAME "StevePi"
#define DEFAULT_RENDER_DISTANCE "Short"
// Feature Flags
std::string strip_feature_flag_default(std::string flag, bool *default_ret);
void load_available_feature_flags(std::function<void(std::string)> callback);

260
launcher/src/crash-report.c Normal file
View File

@ -0,0 +1,260 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <signal.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <libreborn/libreborn.h>
#include "crash-report.h"
// Show Crash Report Dialog
#ifndef MCPI_HEADLESS_MODE
#define DIALOG_TITLE "Crash Report"
#define CRASH_REPORT_DIALOG_WIDTH "640"
#define CRASH_REPORT_DIALOG_HEIGHT "480"
static void show_report(const char *log_filename) {
// Fork
pid_t pid = fork();
if (pid == 0) {
// Child
setsid();
ALLOC_CHECK(freopen("/dev/null", "w", stdout));
ALLOC_CHECK(freopen("/dev/null", "w", stderr));
ALLOC_CHECK(freopen("/dev/null", "r", stdin));
const char *command[] = {
"zenity",
"--title", DIALOG_TITLE,
"--name", MCPI_APP_ID,
"--width", CRASH_REPORT_DIALOG_WIDTH,
"--height", CRASH_REPORT_DIALOG_HEIGHT,
"--text-info",
"--text", MCPI_APP_BASE_TITLE " has crashed!\n\nNeed help? Consider asking on the <a href=\"https://discord.com/invite/aDqejQGMMy\">Discord server</a>! <i>If you believe this is a problem with " MCPI_APP_BASE_TITLE " itself, please upload this crash report to the #bugs Discord channel.</i>",
"--filename", log_filename,
"--no-wrap",
"--font", "Monospace",
"--save-filename", MCPI_VARIANT_NAME "-crash-report.log",
"--ok-label", "Exit",
NULL
};
safe_execvpe(command, (const char *const *) environ);
}
}
#endif
// Exit Handler
static void exit_handler(__attribute__((unused)) int signal) {
// Murder
murder_children();
}
// Setup
#define PIPE_READ 0
#define PIPE_WRITE 1
#define MCPI_LOGS_DIR "/tmp/.minecraft-pi-logs"
static char log_filename[] = MCPI_LOGS_DIR "/XXXXXX";
static int log_file_fd = -1;
void setup_log_file() {
// Ensure Temporary Directory
{
// Check If It Exists
struct stat tmp_stat;
int exists = stat(MCPI_LOGS_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode);
if (!exists) {
// Doesn't Exist
if (mkdir(MCPI_LOGS_DIR, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
ERR("Unable To Create Temporary Folder: %s", strerror(errno));
}
}
}
// Create Temporary File
log_file_fd = mkstemp(log_filename);
if (log_file_fd == -1) {
ERR("Unable To Create Log File: %s", strerror(errno));
}
// Setup Environment
char *log_file_fd_env = NULL;
safe_asprintf(&log_file_fd_env, "%i", log_file_fd);
set_and_print_env("MCPI_LOG_FILE_FD", log_file_fd_env);
free(log_file_fd_env);
}
void setup_crash_report() {
// Store Output
int output_pipe[2];
safe_pipe2(output_pipe, 0);
int error_pipe[2];
safe_pipe2(error_pipe, 0);
int input_pipe[2];
safe_pipe2(input_pipe, 0);
// Fork
pid_t ret = fork();
if (ret == -1) {
ERR("Unable To Fork: %s", strerror(errno));
} else if (ret == 0) {
// Child Process
// Pipe stdio
dup2(output_pipe[PIPE_WRITE], STDOUT_FILENO);
close(output_pipe[PIPE_READ]);
close(output_pipe[PIPE_WRITE]);
dup2(error_pipe[PIPE_WRITE], STDERR_FILENO);
close(error_pipe[PIPE_READ]);
close(error_pipe[PIPE_WRITE]);
dup2(input_pipe[PIPE_READ], STDIN_FILENO);
close(input_pipe[PIPE_READ]);
close(input_pipe[PIPE_WRITE]);
// Create New Process Group
setpgid(0, 0);
// Continue Execution
} else {
// Parent Process
track_child(ret);
// Install Signal Handlers
struct sigaction act_sigint;
memset((void *) &act_sigint, 0, sizeof (struct sigaction));
act_sigint.sa_flags = SA_RESTART;
act_sigint.sa_handler = &exit_handler;
sigaction(SIGINT, &act_sigint, NULL);
struct sigaction act_sigterm;
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
act_sigterm.sa_flags = SA_RESTART;
act_sigterm.sa_handler = &exit_handler;
sigaction(SIGTERM, &act_sigterm, NULL);
atexit(murder_children);
// Close Unneeded File Descriptors
close(output_pipe[PIPE_WRITE]);
close(error_pipe[PIPE_WRITE]);
close(input_pipe[PIPE_READ]);
// Set Debug Tag
reborn_debug_tag = "(Crash Reporter) ";
// Setup Logging
#define BUFFER_SIZE 1024
char buf[BUFFER_SIZE];
// Setup Polling
int number_fds = 3;
struct pollfd poll_fds[number_fds];
poll_fds[0].fd = output_pipe[PIPE_READ];
poll_fds[1].fd = error_pipe[PIPE_READ];
poll_fds[2].fd = STDIN_FILENO;
for (int i = 0; i < number_fds; i++) {
poll_fds[i].events = POLLIN;
}
// Poll Data
int status;
while (waitpid(ret, &status, WNOHANG) != ret) {
int poll_ret = poll(poll_fds, number_fds, -1);
if (poll_ret == -1) {
if (errno == EINTR) {
continue;
} else {
ERR("Unable To Poll Data: %s", strerror(errno));
}
}
// Handle Data
for (int i = 0; i < number_fds; i++) {
if (poll_fds[i].revents != 0) {
if (poll_fds[i].revents & POLLIN) {
if (poll_fds[i].fd == STDIN_FILENO) {
// Data Available From stdin
int bytes_available;
if (ioctl(fileno(stdin), FIONREAD, &bytes_available) == -1) {
bytes_available = 0;
}
// Read
ssize_t bytes_read = read(poll_fds[i].fd, (void *) buf, BUFFER_SIZE);
if (bytes_read == -1) {
ERR("Unable To Read Log Data: %s", strerror(errno));
}
// Write To Child
if (write(input_pipe[PIPE_WRITE], (void *) buf, bytes_read) == -1) {
ERR("Unable To Write Input To Child: %s", strerror(errno));
}
} else {
// Data Available From Child's stdout/stderr
ssize_t bytes_read = read(poll_fds[i].fd, (void *) buf, BUFFER_SIZE - 1 /* Account For NULL-Terminator */);
if (bytes_read == -1) {
ERR("Unable To Read Log Data: %s", strerror(errno));
}
// Print To Terminal
buf[bytes_read] = '\0';
fprintf(poll_fds[i].fd == output_pipe[PIPE_READ] ? stdout : stderr, "%s", buf);
// Write To log
if (write(log_file_fd, (void *) buf, bytes_read) == -1) {
ERR("Unable To Write Log Data: %s", strerror(errno));
}
}
} else {
// File Descriptor No Longer Accessible
poll_fds[i].events = 0;
}
}
}
}
// Untrack Process
untrack_child(ret);
// Close Pipes
close(output_pipe[PIPE_READ]);
close(error_pipe[PIPE_READ]);
close(input_pipe[PIPE_WRITE]);
// Check If Is Crash
int is_crash = !is_exit_status_success(status);
// Log Exit Code To log If Crash
if (is_crash) {
// Create Exit Code Log Line
char *exit_status = NULL;
get_exit_status_string(status, &exit_status);
char *exit_code_line = NULL;
safe_asprintf(&exit_code_line, "[CRASH]: Terminated%s\n", exit_status);
free(exit_status);
// Print Exit Code Log Line
fprintf(stderr, "%s", exit_code_line);
// Write Exit Code Log Line
if (write(log_file_fd, (void *) exit_code_line, strlen(exit_code_line)) == -1) {
ERR("Unable To Write Exit Code To Log: %s", strerror(errno));
}
// Free Exit Code Log Line
free(exit_code_line);
}
// Close Log File FD
if (close(log_file_fd) == -1) {
ERR("Unable To Close Log File Descriptor: %s", strerror(errno));
}
// Show Crash Log
#ifndef MCPI_HEADLESS_MODE
if (is_crash) {
show_report(log_filename);
}
#endif
// Exit
exit(WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE);
}
}

View File

@ -4,7 +4,8 @@
extern "C" {
#endif
char *version_get();
void setup_log_file();
void setup_crash_report();
#ifdef __cplusplus
}

View File

@ -1,45 +0,0 @@
#include <unistd.h>
#include <string>
#include <cstring>
#include <cstdio>
#include <libreborn/libreborn.h>
#include "ldconfig.h"
char *get_full_library_search_path() {
std::string output;
// Run
FILE *file = popen("ldconfig -NXv 2> /dev/null", "r");
// Read
int running = 1;
while (running) {
char *line = NULL;
size_t length = 0;
if (getline(&line, &length, file) != -1) {
// Convert to C++ String
std::string str(line);
// Remove Newline
if (str.size() > 0 && str[str.size() - 1] == '\n') {
str.pop_back();
}
// Interpret
if (str.size() >= 2 && str[0] != '\t' && str[str.size() - 1] == ':') {
output.append(str);
}
} else {
running = 0;
}
free(line);
}
// Remove Colon
if (output.size() > 0 && output[output.size() - 1] == ':') {
output.pop_back();
}
// Close Process
pclose(file);
// Return
char *output_str = strdup(output.c_str());
ALLOC_CHECK(output_str);
return output_str;
}

110
launcher/src/mods.c Normal file
View File

@ -0,0 +1,110 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libreborn/libreborn.h>
#include "bootstrap.h"
// Get All Mods In Folder
static void load(char **ld_preload, const char *folder) {
int folder_name_length = strlen(folder);
// Open Folder
DIR *dp = opendir(folder);
if (dp != NULL) {
// Loop Through Folder
struct dirent *entry = NULL;
errno = 0;
while (1) {
errno = 0;
entry = readdir(dp);
if (entry != NULL) {
// Check If File Is Regular
if (entry->d_type == DT_REG) {
// Get Full Name
int name_length = strlen(entry->d_name);
int total_length = folder_name_length + name_length;
char name[total_length + 1];
// Concatenate Folder Name And File Name
for (int i = 0; i < folder_name_length; i++) {
name[i] = folder[i];
}
for (int i = 0; i < name_length; i++) {
name[folder_name_length + i] = entry->d_name[i];
}
// Add Terminator
name[total_length] = '\0';
// Check If File Is Accessible
int result = access(name, R_OK);
if (result == 0) {
// Add To LD_PRELOAD
string_append(ld_preload, "%s%s", *ld_preload == NULL ? "" : ":", name);
} else if (result == -1 && errno != 0) {
// Fail
WARN("Unable To Access: %s: %s", name, strerror(errno));
errno = 0;
}
}
} else if (errno != 0) {
// Error Reading Contents Of Folder
ERR("Error Reading Directory: %s: %s", folder, strerror(errno));
} else {
// Done!
break;
}
}
// Close Folder
closedir(dp);
} else if (errno == ENOENT) {
// Folder Doesn't Exist
} else {
// Unable To Open Folder
ERR("Error Opening Directory: %s: %s", folder, strerror(errno));
}
}
// Bootstrap Mods
void bootstrap_mods(char *binary_directory) {
// Prepare
char *preload = NULL;
// ~/.minecraft-pi/mods
{
// Get Mods Folder
char *mods_folder = NULL;
safe_asprintf(&mods_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA "/mods/", getenv("HOME"));
// Load Mods From ./mods
load(&preload, mods_folder);
// Free Mods Folder
free(mods_folder);
}
// Built-In Mods
{
// Get Mods Folder
char *mods_folder = NULL;
safe_asprintf(&mods_folder, "%s/mods/", binary_directory);
// Load Mods From ./mods
load(&preload, mods_folder);
// Free Mods Folder
free(mods_folder);
}
// Add LD_PRELOAD
{
char *value = getenv("LD_PRELOAD");
if (value != NULL && strlen(value) > 0) {
string_append(&preload, ":%s", value);
}
}
// Set
set_and_print_env("MCPI_ARM_LD_PRELOAD", preload);
free(preload);
}

94
launcher/src/patchelf.cpp Normal file
View File

@ -0,0 +1,94 @@
#include <cstdlib>
#include <sys/stat.h>
#include <LIEF/ELF.hpp>
#include <dlfcn.h>
#include <link.h>
#include <libreborn/libreborn.h>
#include "patchelf.h"
// Duplicate MCPI Executable Into /tmp
static void duplicate_mcpi_executable(char *new_path) {
// Ensure Temporary Directory
{
// Check If It Exists
struct stat tmp_stat;
int exists = stat(MCPI_PATCHED_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode);
if (!exists) {
// Doesn't Exist
if (mkdir(MCPI_PATCHED_DIR, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
ERR("Unable To Create Temporary Folder: %s", strerror(errno));
}
}
}
// Generate New File
int new_file_fd = mkstemp(new_path);
if (new_file_fd == -1) {
ERR("Unable To Create Temporary File: %s", strerror(errno));
}
close(new_file_fd);
}
// Fix MCPI Dependencies
static const char *libraries_to_remove[] = {
"libbcm_host.so",
"libX11.so.6",
"libEGL.so",
"libGLESv2.so",
"libSDL-1.2.so.0"
};
static const char *libraries_to_add[] = {
"libmedia-layer-core.so"
};
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, const char *linker) {
// Duplicate MCPI executable into /tmp so it can be modified.
duplicate_mcpi_executable(new_path);
// Patch File
{
std::unique_ptr<LIEF::ELF::Binary> binary = LIEF::ELF::Parser::parse(original_path);
if (linker != NULL) {
binary->interpreter(linker);
}
for (size_t i = 0; i < (sizeof (libraries_to_remove) / sizeof (const char *)); i++) {
binary->remove_library(libraries_to_remove[i]);
}
for (size_t i = 0; i < (sizeof (libraries_to_add) / sizeof (const char *)); i++) {
binary->add_library(libraries_to_add[i]);
}
LIEF::ELF::Builder builder{*binary};
builder.build();
builder.write(new_path);
}
// Fix Permissions
if (chmod(new_path, S_IRUSR | S_IXUSR) != 0) {
ERR("Unable To Set File Permissions: %s: %s", new_path, strerror(errno));
}
}
// Get Interpreter
static int dl_iterate_callback(struct dl_phdr_info *info, __attribute__((unused)) size_t size, void *data) {
// Only Search Current Program
if (strcmp(info->dlpi_name, "") == 0) {
for (int i = 0; i < info->dlpi_phnum; i++) {
if (info->dlpi_phdr[i].p_type == PT_INTERP) {
// Callback
*(char **) data = (char *) (info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
}
}
}
return 0;
}
char *patch_get_interpreter() {
char *interpreter = NULL;
dl_iterate_phdr(dl_iterate_callback, &interpreter);
if (interpreter != NULL) {
interpreter = strdup(interpreter);
}
return interpreter;
}

14
launcher/src/patchelf.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched"
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, const char *linker);
char *patch_get_interpreter();
#ifdef __cplusplus
}
#endif

67
launcher/src/sdk.c Normal file
View File

@ -0,0 +1,67 @@
#include <libreborn/libreborn.h>
#include "bootstrap.h"
#include "util.h"
// Log
#define LOG(is_debug, ...) \
{ \
if (is_debug) { \
DEBUG(__VA_ARGS__); \
} else { \
INFO(__VA_ARGS__); \
} \
}
// Copy SDK Into ~/.minecraft-pi
#define HOME_SUBDIRECTORY_FOR_SDK HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk"
void copy_sdk(char *binary_directory, int log_with_debug) {
// Ensure SDK Directory
{
char *sdk_path = NULL;
safe_asprintf(&sdk_path, "%s" HOME_SUBDIRECTORY_FOR_SDK, getenv("HOME"));
const char *const command[] = {"mkdir", "-p", sdk_path, NULL};
run_simple_command(command, "Unable To Create SDK Directory");
}
// Lock File
char *lock_file_path = NULL;
safe_asprintf(&lock_file_path, "%s" HOME_SUBDIRECTORY_FOR_SDK "/.lock", getenv("HOME"));
int lock_file_fd = lock_file(lock_file_path);
// Output Directory
char *output = NULL;
safe_asprintf(&output, "%s" HOME_SUBDIRECTORY_FOR_SDK "/" MCPI_SDK_DIR, getenv("HOME"));
// Source Directory
char *source = NULL;
safe_asprintf(&source, "%s/sdk/.", binary_directory);
// Clean
{
const char *const command[] = {"rm", "-rf", output, NULL};
run_simple_command(command, "Unable To Clean SDK Output Directory");
}
// Make Directory
{
const char *const command[] = {"mkdir", "-p", output, NULL};
run_simple_command(command, "Unable To Create SDK Output Directory");
}
// Copy
{
const char *const command[] = {"cp", "-ar", source, output, NULL};
run_simple_command(command, "Unable To Copy SDK");
}
// Log
LOG(log_with_debug, "Copied SDK To: %s", output);
// Free
free(output);
free(source);
// Unlock File
unlock_file(lock_file_path, lock_file_fd);
free(lock_file_path);
}

View File

@ -1,6 +1,19 @@
#include <stdlib.h>
#include <unistd.h>
#include <libreborn/libreborn.h>
#include "../bootstrap.h"
int main(int argc, char *argv[]) {
// Pre-Bootstrap
pre_bootstrap(argc, argv);
// Set Home To Current Directory, So World Data Is Stored There
char *launch_directory = getcwd(NULL, 0);
set_and_print_env("HOME", launch_directory);
free(launch_directory);
// Bootstrap
bootstrap(argc, argv);
}

39
launcher/src/util.c Normal file
View File

@ -0,0 +1,39 @@
#include <libreborn/libreborn.h>
#include "util.h"
// Simpler Version Of run_command()
void run_simple_command(const char *const command[], const char *error) {
int status = 0;
char *output = run_command(command, &status, NULL);
if (output != NULL) {
free(output);
}
if (!is_exit_status_success(status)) {
ERR("%s", error);
}
}
// Chop Off Last Component
void chop_last_component(char **str) {
size_t length = strlen(*str);
for (size_t i = 0; i < length; i++) {
size_t j = length - i - 1;
if ((*str)[j] == '/') {
(*str)[j] = '\0';
break;
}
}
}
// Get Binary Directory (Remember To Free)
char *get_binary_directory() {
// Get Path To Current Executable
char *exe = realpath("/proc/self/exe", NULL);
ALLOC_CHECK(exe);
// Chop Off Last Component
chop_last_component(&exe);
// Return
return exe;
}

Some files were not shown because too many files have changed in this diff Show More