Compare commits

..

515 Commits

Author SHA1 Message Date
6f5f405327 Fix Build 2025-01-05 13:09:10 -05:00
489615d47f More Changes 2025-01-04 05:38:38 -05:00
00fee9c410 Basic AppImage Updater 2025-01-03 15:03:30 -05:00
b055980103 JS-Ify Dependency Installation 2025-01-03 10:20:33 -05:00
b767b9d4ec Update Build Script 2025-01-03 08:25:09 -05:00
c5f9a519c5 Basic About 2025-01-03 05:36:28 -05:00
9428a5a1e1 Work On Using Multi-Config 2024-12-22 03:34:31 -05:00
013c1db336 Use CMAKE_BUILD_TYPE Less 2024-12-21 05:10:13 -05:00
a80b5fb5c2 Skip Unnecessary SDK Copying 2024-12-21 04:46:31 -05:00
bf24ace78e Generate SDK Hash 2024-12-19 03:44:36 -05:00
2568b05053 Fix Held Item Poking Through Screen Overlay 2024-12-19 01:28:48 -05:00
dcafeb5c44 Fix Furnace Fix 2024-12-18 21:08:06 -05:00
3771666a14 Batch Font Rendering 2024-12-18 03:04:36 -05:00
b71c089fb3 Fix Hanging When No Valid Spawn Point Exists 2024-12-18 02:44:51 -05:00
71946d2087 Some Fixes 2024-12-18 02:20:07 -05:00
b2ec2728e3 Update Symbol Processor 2024-12-18 01:19:44 -05:00
71042da861 Fix Crash On NVIDIA + Improve Splash Oscillation 2024-12-17 21:17:45 -05:00
5d8aa28113 Make Biome-Tinted Grass Not Suck 2024-12-17 09:22:48 -05:00
aea31dd4c8 Fix Example Mod 2024-12-17 05:55:28 -05:00
f0005ff002 Some Fixes 2024-12-17 05:50:20 -05:00
587ba38ffe Store Server List In Launcher Cache 2024-12-14 03:08:19 -05:00
c6048ec4fb Start Logger After Launcher UI 2024-12-08 15:34:03 -05:00
0ccf578478 Embrace Integer Scaling 2024-11-30 05:33:50 -05:00
814217a259 Better UI Scaling 2024-11-28 05:25:22 -05:00
cfac7d0a12 WIP UI Scale Slider 2024-11-28 02:42:22 -05:00
c531e7ba7d Add Servers Tab To Launcher 2024-11-26 06:47:48 -05:00
bddc299664 Fix GLAD CI Build 2024-11-24 21:31:26 -05:00
cc060accaf Use Legacy GLAD 2024-11-24 21:01:00 -05:00
09c8af0396 Simplify Cache Loading 2024-11-24 19:57:52 -05:00
a740814354 Fix Bug When Resizing ImGui 2024-11-24 18:59:23 -05:00
890bd537b2 Use GLAD 2024-11-24 17:49:17 -05:00
983e474b33 Partly Fix CI 2024-11-23 08:03:10 -05:00
2c3bb41293 Third Time's The Charm! 2024-11-23 00:01:27 -05:00
3d89fb691a Some Fixes 2024-11-22 22:02:55 -05:00
4e1476bcfd Fixing The CI: Take 2 2024-11-22 04:41:53 -05:00
8ed425392a Fix CI (Hopefully) 2024-11-22 04:32:06 -05:00
b2c13c8257 Tweak Camera 2024-11-22 04:20:22 -05:00
2eb6a1c5be Rename GUI Flags To UI 2024-11-22 03:35:26 -05:00
ef3292c5e0 Change Flag Grouping 2024-11-22 03:30:34 -05:00
67ceb4ad00 More Feature Flags! 2024-11-22 03:07:54 -05:00
e1d9fc492b Remove Some Macros 2024-11-22 01:09:54 -05:00
acec86b9b5 Update Example Mods 2024-11-22 00:54:34 -05:00
66d2e43f55 Move Some Stuff Around 2024-11-22 00:47:38 -05:00
596ff01f75 Remove libreborn.h: Part 3 2024-11-22 00:22:49 -05:00
57aed4d0b3 Remove libreborn.h: Part 2 2024-11-21 23:46:23 -05:00
fd26000fd4 Remove libreborn.h: Part 1 2024-11-21 22:36:05 -05:00
454734ab68 Improve feature_has 2024-11-21 22:07:50 -05:00
d3b70878be New Crash Report UI 2024-11-21 21:45:57 -05:00
7f9d1d843e Small Fix 2024-11-21 17:41:24 -05:00
900169a728 Add "Revert" Button 2024-11-21 16:16:53 -05:00
633b165af0 Tweak UI 2024-11-21 14:50:26 -05:00
86e8c0dd67 Update GLFW 2024-11-21 14:06:43 -05:00
332acd49fb Better extend_struct 2024-11-21 14:03:59 -05:00
c2750bbaec More Color Tweaking 2024-11-21 04:29:05 -05:00
70ef421780 Move Reset Button 2024-11-21 04:07:50 -05:00
ed59e19c52 Add Reset Button 2024-11-21 03:53:01 -05:00
dd760cc6f2 Disable Obsolete ImGui Functions 2024-11-21 03:29:37 -05:00
00f90afc2a Color UI 2024-11-21 03:16:11 -05:00
4a91937b0a New Launcher UI 2024-11-21 02:16:25 -05:00
a6cc0b88b5 Leaner ImGui Build 2024-11-20 12:36:34 -05:00
0b542701c5 ImGui Hello World 2024-11-20 12:22:36 -05:00
fc7ecd528a Embed ImGui Fonts 2024-11-20 10:16:50 -05:00
2785e3f138 Build ImGui 2024-11-19 22:48:50 -05:00
386f52a85f CMake Refactor 2024-11-19 19:57:43 -05:00
871288ee12 Fix Example Mod (Again) 2024-11-18 20:15:15 -05:00
5d7056645d Some Fixes 2024-11-18 18:47:13 -05:00
ecbbcef203 Some Renaming/Moving 2024-11-18 01:56:11 -05:00
bbae01a471 Small Tweaks 2024-11-17 22:55:25 -05:00
6b5105e74d Remove OpenGL Occlusion Functions 2024-11-17 22:50:15 -05:00
57503d6a31 More C++ Refactors 2024-11-17 22:48:25 -05:00
58a6706cf9 Some Updates 2024-11-15 15:26:33 -05:00
f501f9a7c9 Please Just Work 2024-11-10 19:05:44 -05:00
203d46c849 Update Archives 2024-11-10 18:52:42 -05:00
58efe19609 Fix CMake 2024-11-10 05:42:56 -05:00
23b3cbe72f Update Runtime 2024-11-10 05:26:41 -05:00
b339b53f42 Revert That, It Sucked 2024-11-09 00:21:41 -05:00
a8d0962491 Occlusion Checking 2024-11-09 00:17:25 -05:00
a63125f335 Add OpenGL Query Functions 2024-11-08 21:40:12 -05:00
eeace9cf14 Small Rename 2024-11-08 20:50:34 -05:00
dd25805af9 Fancy New API! 2024-11-08 02:34:58 -05:00
a6dad72778 Fix Sugar Position In Hand 2024-11-03 20:04:19 -05:00
9ae6cd17cf Convert API Chat Posts To CP-437 2024-11-03 01:41:28 -04:00
644e9e421b Finally Fix Dumb Method Names 2024-11-03 00:02:13 -04:00
419ad9c98c Minor Tweaks 2024-10-30 00:22:02 -04:00
a0a566f594 F3 Tweak 2024-10-29 22:48:23 -04:00
e6deab9664 Fix Headless Bug 2024-10-27 00:56:04 -04:00
69fcc6cdb3 800th Commit! Regenerating gui_blocks And Performance Fixes 2024-10-26 18:03:16 -04:00
ee44a0ce88 Fix Compiling On Older GCC 2024-10-20 18:10:17 -04:00
62d3512a38 Fix Lighting In ArmorScreen 2024-10-20 17:19:37 -04:00
d011d76f20 Fix Shadow In ArmorScreen 2024-10-20 17:15:06 -04:00
dc7d3a5b8f Downgrade LIEF To Fix CMake 2024-10-20 17:09:15 -04:00
0f5d8730b0 Media Layer + Launching Tweaks 2024-10-20 01:19:08 -04:00
f5da0f60e5 Fix Baby Shadows 2024-10-19 18:44:22 -04:00
fbb3152a70 Get Lighting Working! 2024-10-19 05:19:08 -04:00
18f7d64405 Entities Have Shading! 2024-10-18 15:14:18 -04:00
1001427309 Rest Of The Tesselator 2024-10-18 01:41:59 -04:00
b2db67b4bf Custom Tesselator 2024-10-18 01:09:13 -04:00
d289f40a5e Small Changes 2024-10-17 18:49:36 -04:00
e7b0932f60 Increase Render Chunk Size 2024-10-17 18:02:46 -04:00
8bc335b479 Update Changelog 2024-10-15 14:03:16 -04:00
73b3cd10af Vignette 2024-10-15 13:38:22 -04:00
463ede508e Reduce Code Duplication 2024-10-09 10:43:44 -04:00
0c92551e8a Improve HOOK() 2024-10-07 10:18:16 -04:00
6388663b6c Switch To Desktop OpenGL 1.5 2024-10-05 23:52:44 -04:00
5668dcc852 Render Entity Shadows 2024-10-03 20:29:24 -04:00
d4ab0099f0 Tweak 3D Items 2024-10-03 16:22:53 -04:00
3d8525a321 3D Items! 2024-10-03 05:17:12 -04:00
b11cc95e50 Fix ChatPacket Reading 2024-10-01 20:44:50 -04:00
661cfd02ad Expand Debug Info 2024-09-30 22:00:19 -04:00
66f4f11a68 Tweak Debug Screen 2024-09-30 13:13:02 -04:00
52ca5bb734 Show Seed In Debug Info 2024-09-30 00:45:53 -04:00
916902ab68 Changes Needed For Hodgepodge 2024-09-30 00:03:52 -04:00
9bdde40f3f Click Buttons On Mouse Down 2024-09-29 00:49:03 -04:00
cbca78ec16 Try To Fix server.properties Generation 2024-09-23 21:35:20 -04:00
65190afe73 Fix Rare Segfault 2024-09-23 21:22:43 -04:00
be3ccae7c1 Hide Block Outline When GUI Is Hidden 2024-09-23 18:52:15 -04:00
00d193e732 Fix Bad Error 2024-09-22 22:22:32 -04:00
65ee4d8a78 Shrink Icon For Flatpak 2024-09-22 21:21:53 -04:00
3598fbc922 Revert Bad Idea 2024-09-22 20:25:59 -04:00
b5e9a91f75 Test Crafting Remainder 2024-09-22 20:02:40 -04:00
18c6247e0c Fix Button Hovering 2024-09-22 19:39:42 -04:00
c525d69dc3 New Logo + Background! 2024-09-22 19:28:51 -04:00
72eb1945cf Update Processor 2024-09-21 02:54:11 -04:00
5ca2a63b5e Allow Custom Commands 2024-09-21 02:30:06 -04:00
72e2c4947d Update Runtime 2024-09-21 01:55:10 -04:00
be1f3bf50e Fix Chat Example Mod 2024-09-21 01:49:47 -04:00
e2c82071c7 Server Changes 2024-09-21 01:46:52 -04:00
9bb6b86c73 Some Tweaks 2024-09-21 00:23:30 -04:00
c0156336df Modding Changes 2024-09-20 21:30:47 -04:00
f1fe1c140c More Feature Flags! 2024-08-25 18:14:30 -04:00
8ef6e0885a Split Up misc.cpp 2024-08-25 17:06:12 -04:00
c5937e6794 Way Too Many Changes 2024-08-24 00:30:06 -04:00
07f5e188f7 Bug Fixes & Improvements 2024-08-23 05:18:20 -04:00
18b25486e7 Fix Door Item Issues 2024-08-22 23:43:32 -04:00
72372c7457 Small Fixes 2024-08-21 18:19:07 -04:00
63e2525ee9 Improve Build Time 2024-08-02 01:03:20 -04:00
98c4ee306d It Works! 2024-07-17 06:42:58 -04:00
5f2923b789 Merge PR + WIP Refactor
Co-authored-by: Bigjango13 <bigjango13@gmail.com>
2024-07-17 03:44:44 -04:00
036d0a0653 Tweak 2024-07-16 13:46:37 -04:00
e837610380 Fix Example Mods (Again) 2024-07-15 03:09:19 -04:00
88f59d951a References! References Everywhere! 2024-07-15 03:05:05 -04:00
0521b540fd Fix Example Mods 2024-07-14 22:12:08 -04:00
d2b07f7661 minecraft.h/.cpp Changes 2024-07-14 05:06:27 -04:00
688bee1aaa Use PerformanceTestChunkSource In Benchmark 2024-07-11 00:29:53 -04:00
d4c0f54245 Multidraw 2024-07-10 23:15:58 -04:00
f08afbf654 Allow Skipping Page-Size Check 2024-07-05 03:24:27 -04:00
f7bc756063 Bug Fixes + F3 2024-07-05 02:33:29 -04:00
7718fe5b12 Small Bug Fix 2024-06-21 01:32:11 -04:00
6a2ecb23ed Remove overwrite() 2024-06-21 01:22:33 -04:00
5e229fb6a8 Some Modernization 2024-06-21 01:19:37 -04:00
cecd61ed72 Another Small Update 2024-06-18 18:15:06 -04:00
57df81e425 Update 2024-06-18 18:03:02 -04:00
a830f66c41 Attempt #3 2024-06-17 20:10:03 -04:00
6fb1c8d59a Icon Fix Attempt #2 2024-06-17 19:10:25 -04:00
6740eb595e Fix Icon Path 2024-06-17 18:40:07 -04:00
99a7407404 Some Docs Changes 2024-06-17 18:35:38 -04:00
0977f557b8 Rename Header 2024-06-17 18:17:24 -04:00
3b5149abff Environmental Variable & Logging Refactor 2024-06-17 18:09:30 -04:00
b2db6bcfd2 Some Clean Up 2024-06-16 00:49:03 -04:00
36fe263ede Revert servers.txt Change 2024-06-16 00:04:42 -04:00
74ee75e12f Some Fixes 2024-06-15 10:19:18 -04:00
38d7dda1a7 The Great Unification 2024-06-15 08:52:15 -04:00
460cd38ddf Oops! 2024-06-14 03:26:23 -04:00
b71f6c7008 Test On RPI! 2024-06-14 03:22:01 -04:00
8bc90dae04 More Tweaks 2024-06-12 02:33:29 -04:00
1bf19268f0 Fix Benchmark Rotation 2024-06-10 18:55:22 -04:00
69a9613e4f Small Fixes 2024-06-08 18:00:30 -04:00
a0f32a15a7 Finally At A Nice Point 2024-06-08 16:30:39 -04:00
d52c16e722 Concessions To Reality 2024-06-08 04:34:46 -04:00
2d9659f273 This is a commit message. 2024-06-08 04:23:15 -04:00
3414fb817c More WIP 2024-06-08 03:55:13 -04:00
c60428c600 WIP 2024-06-08 03:09:55 -04:00
4e2437dbd6 Pipe (Part 2); This Needs Work 2024-06-05 21:19:39 -04:00
a1ea91ad89 It Works... Slowly 2024-06-05 00:17:53 -04:00
f9e0f54620 WIP Trampoline Changes 2024-06-04 18:29:13 -04:00
804c9da179 Fix Artifacts v4 2024-05-30 22:22:30 -04:00
cdc1a82142 CI Badge! 2024-05-30 21:52:15 -04:00
04b9ad5efd Update Dependencies 2024-05-27 03:47:04 -04:00
8203e20971 Revert Change, I Did Bad Math 2024-05-24 22:23:58 -04:00
4dc69885f2 Fix 2024-05-24 17:52:54 -04:00
36cb84b672 Tweak QEMU Base 2024-05-24 17:42:42 -04:00
f53f405bdd The Compiler Strikes Back! 2024-05-24 04:44:53 -04:00
60a5accff2 Fix Another Link 2024-05-22 02:57:00 -04:00
c9fafd6cd4 Use Different Discord URL 2024-05-22 02:29:54 -04:00
668552e354 Mention Discord In Docs 2024-05-22 02:23:15 -04:00
fedc006a4b Remove Reference To Deleted File 2024-05-22 02:15:21 -04:00
1dc23fe615 Remove Line 2024-05-22 02:04:44 -04:00
ef3f8da720 One More Tweak 2024-05-22 01:56:35 -04:00
eca42150cb Improve Getting Started (Thanks ChatGPT!) 2024-05-22 01:53:36 -04:00
db45df1e52 Update Documentation 2024-05-22 01:32:52 -04:00
0e44bb5f06 Add Welcome Screen 2024-05-21 19:16:19 -04:00
3088a13725 Tweak Loading 2024-05-20 16:37:55 -04:00
56d93f0150 Tweak Text Wrapping 2024-05-19 00:19:01 -04:00
3132f9442d Better Error Message 2024-05-18 21:25:11 -04:00
b129f0a503 Attack Of The Templates! 2024-05-18 18:58:39 -04:00
97bc124d72 Better Static Properties 2024-05-17 02:52:55 -04:00
b23f7f1618 Remove alloc_*() Functions 2024-05-17 00:36:28 -04:00
bbaa69edeb Tweak Reborn Info Screen 2024-05-16 21:59:51 -04:00
6cfc1a7e20 Small Tweaks 2024-05-16 04:07:02 -04:00
f25a2adcef Update More Methods! 2024-05-15 05:08:39 -04:00
6ae475785e Fix Newlines 2024-05-15 05:06:36 -04:00
51bbad15f4 Use New Method Call Style 2024-05-15 05:02:19 -04:00
73454adc22 Refactor Logging 2024-05-14 01:23:16 -04:00
4d54a9d28c Refactor Launcher 2024-05-12 03:19:01 -04:00
d7616419bc Fix Server Build 2024-05-11 22:06:37 -04:00
823495a811 Fix QEMU Build 2024-05-11 21:43:28 -04:00
03c7c50d48 Trampoline 2024-05-11 21:14:14 -04:00
f15625ff79 UI Tweaks 2024-05-10 19:50:28 -04:00
e2d32cad21 Add QEMU Patch 2024-05-10 18:58:39 -04:00
eeef63d9ef Improve Creative Restrictions Mod 2024-05-09 19:03:48 -04:00
e1f0787e48 Fix Layering Iverwrites 2024-05-09 17:50:02 -04:00
37e1abbdd3 Fix Splash Animation 2024-05-09 04:19:08 -04:00
c88db307d7 Reduce Code Duplication 2024-05-09 02:55:30 -04:00
75fc48da24 One Last Fix 2024-05-09 02:20:09 -04:00
cd39733177 Update Changelog & Fix Flatpak Detection In Info Screen 2024-05-09 02:06:24 -04:00
592d6c4e63 Simplify CMake 2024-05-09 01:38:57 -04:00
d519142a8a Fancy Info Screen 2024-05-09 01:25:53 -04:00
09bae1cf3e Split Up Options Mod 2024-05-08 20:18:50 -04:00
4523935d62 Fix Example Mod (Again) 2024-05-05 02:17:46 -04:00
Bigjango13
f3f8e342d8 More chunk symbols 2024-05-05 01:06:47 -04:00
Bigjango13
f010e51c3a Add ChunkSource vtable 2024-05-05 01:03:44 -04:00
Bigjango13
91ee97f005 Fix HOOKing mods 2024-05-05 01:03:43 -04:00
Bigjango13
a6b01da677 Fix Tile_lightEmission 2024-05-05 01:02:05 -04:00
Bigjango13
2549670ee4 Add TileRenderer_tesselateTorch 2024-05-05 01:00:51 -04:00
Bigjango13
d0954a22f3 More symbols, remove Entity_moveTo 2024-05-05 01:00:50 -04:00
49a54a7396 Update Symbol Processor 2024-05-05 00:44:37 -04:00
a305cf9e38 More Changes! 2024-05-04 20:46:15 -04:00
cf6989bed2 I need to sleep, here be dragons 2024-04-03 03:19:12 -04:00
b2a7fe3eaf C++-Ification! 2024-04-02 19:22:01 -04:00
7739fb6b9b Update Dependency 2024-04-02 15:21:35 -04:00
f3755387e8 Improve Mouse Sensitivity On Wayland 2024-03-19 00:25:50 -04:00
b1b28defd5 Small Change 2024-03-19 00:12:26 -04:00
18c5d34974 Ignore CLion Files 2024-03-19 00:12:26 -04:00
Bigjango13
76a66a0ba5 Sneak in Level_setTileEntity 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
d74d1501ce Update Sound Warning 2024-03-02 17:16:16 -05:00
fb84bcc06b GLFW 3.4! 2024-02-23 20:54:07 -05:00
117c5d2702 Better HiDPI Support 2024-02-23 20:50:56 -05:00
9556d13791 Minor Tweaks 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
b033912633 Also Scan .data.rel.ro 2024-02-12 00:55:50 -05:00
a2b3bb128b Bug Fixes & Low-Level Improvements 2024-02-12 00:44:38 -05:00
180ba9dcaf Small Changes 2024-02-11 20:35:41 -05:00
71cc24104c Add More Splashes 2024-02-08 00:59:57 -05:00
6951ebe620 Improve Performance 2024-02-08 00:34:43 -05:00
28dbb2eacd Some CMake Cleanup 2024-02-07 22:12:02 -05:00
d86018717e Split Splash Loading Into Own Function 2024-02-07 21:40:26 -05:00
db22caa50f Add Splash Text From MCPIL 2024-02-07 21:15:48 -05:00
ecbcfb2922 Split Up Animated Textures Into Three Flags 2024-02-07 19:00:55 -05:00
781377005e Update Dependencies 2024-02-07 18:04:53 -05:00
6e306e500d I Have Made This Typo Countless Times 2024-02-07 02:01:43 -05:00
7e300a6e1b Update Changelog 2024-02-07 01:58:21 -05:00
f5a680af7b Add Cake (#81)
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 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
90a2b0ac85 Call Ninja Directly 2024-02-06 19:35:44 -05:00
Bigjango13
2d9d4a638a Move food overlay to after classic HUD 2024-02-06 18:16:21 -05:00
Bigjango13
8c265a69d9 Add Food Overlay 2024-02-06 17:53:21 -05:00
b5e9486460 Fix Script Bug 2024-02-04 03:40:59 -05:00
7fc5638143 Fix CI (Again) 2024-02-04 02:33:35 -05:00
7ba9daa84e Fix CI 2024-02-04 01:31:41 -05:00
930d0120f3 More CI Improvements 2024-02-04 00:43:25 -05:00
31fcff13e9 CI Improvements 2024-02-04 00:36:58 -05:00
41fcc942fa JS-Based Build Script 2024-02-03 21:07:53 -05:00
ddd9226e9e Fix Button Hover 2024-02-02 22:28:57 -05:00
a336cd1c7b Improve Key Handling 2024-02-02 22:25:22 -05:00
eaf6dd2fe2 Add Peaceful Mode To Options Screen 2024-02-02 14:49:47 -05:00
99b43ddb5a Create World Screen + Scrolling Text Boxes! 2024-02-02 04:20:34 -05:00
4f32cfab45 Send Button In Chat 2024-02-01 14:56:16 -05:00
69211eb31d Improve Markdown Formatting 2024-02-01 03:18:47 -05:00
58713976d4 In-Game Chat 2024-02-01 03:12:24 -05:00
d175f692e0 Put Sending Full Level Behind Flag 2024-01-31 23:52:29 -05:00
6d4ff44092 Java Light Ramp (Also From ReMCPE) 2024-01-31 23:44:04 -05:00
1771919cc1 Port Fire/Lava Textures From ReMCPE 2024-01-31 22:13:20 -05:00
522cee2d3b Fix overwrite_calls_within Macro 2024-01-30 01:30:11 -05:00
ccc7e5b190 Fix MCPI Ignoring ♪ 2024-01-28 21:48:51 -05:00
7c9d16d662 Fix Mistake 2024-01-27 17:47:43 -05:00
49f56bd90d Fix Benchmark 2024-01-23 23:00:22 -05:00
0b252faa5f Simplify Some Code 2024-01-23 21:58:18 -05:00
Bigjango13
233e8d691b Fix Tesselator instance symbols 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
46241c9aa0 Expose Some Properties 2024-01-23 20:51:36 -05:00
f7be586a4c Build On Bullseye 2024-01-23 18:20:14 -05:00
Bigjango13
5c5538df2f Move worldgen desync patch to misc, for LAN games 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 2024-01-20 08:24:35 +00:00
Bigjango13
be5bcf24c4 More symbols, mostly item rendering related 2024-01-20 08:24:35 +00:00
91ff082c97 Create AppImages Using CPack 2024-01-20 02:10:18 -05:00
40cd1b0a14 Improve CMake Superbuild 2024-01-16 03:08:34 -05:00
5c607d96b8 Simplify CMake 2024-01-16 01:45:52 -05:00
6e9b364f81 Organize Symbols 2024-01-11 22:10:30 -05:00
67a0d3017b Fix Furnace Visual Bug 2024-01-07 04:57:16 -05:00
e4d9ee4f20 Code Style Changes 2024-01-07 03:23:43 -05:00
d32fa2d265 Add Some Symbols From MCPI-Addons 2024-01-07 02:59:04 -05:00
34c24378f3 Update Example Mods 2024-01-06 20:36:59 -05:00
b7b60876d8 Fix Item Dropping When Killing Players From The Server Console 2024-01-06 18:15:52 -05:00
4dff667749 Fix Server Build 2024-01-06 18:03:48 -05:00
aa92da6fdd WIP New Modding API 2024-01-06 06:30:23 -05:00
0be1f4fce8 Tweak Outline Color 2023-12-26 19:22:50 -05:00
631cbc07d0 Simplify Scripts 2023-12-26 17:45:53 -05:00
5f8c700081 Fix CI 2023-12-26 17:29:45 -05:00
ac55d7d6b3 2.5.3 2023-12-26 02:31:22 -05:00
ef29e4fc0e Remove GL Stubs From Headless Mode 2023-12-25 17:29:30 -05:00
35c6adf94b Fix Bug On X11 2023-12-06 12:54:21 -05:00
1d08b8a29e Update Example Mods 2023-12-04 20:08:48 -05:00
7296fcee83 Update Documentation 2023-12-02 14:25:58 -05:00
97b46ad01a Fix AppImage updating, which has apparently been broken for *years*. Why didn't anyone tell me???? 2023-11-25 18:22:43 -05:00
17d11647e7 Fix CI (Hopefully) 2023-11-25 02:39:19 -05:00
48137f9665 Final Tweaks 2023-11-24 22:16:13 -05:00
c956151603 CI Fixes 2023-11-24 18:53:16 -05:00
73b51be43f Try Fancy CI 2023-11-24 18:37:08 -05:00
71b11b314b Animated Chests 2023-11-24 17:57:39 -05:00
168b825bf4 Clean Up CI 2023-11-24 12:09:21 -05:00
edca3ad394 Fix ARM Build 2023-11-24 03:43:15 -05:00
1aed33a48b Improve Flatpak Build [skip ci] 2023-11-24 03:28:17 -05:00
177c5262a6 2.5.2 2023-11-24 03:07:06 -05:00
7969fb2127 3D Chest Model 2023-11-23 23:54:36 -05:00
b0aac13057 Ȩ̴̛̛̛̝͉̬͙͕̯̬̙̥̬̺̫̭͉̱͈̭͕͍͈̲̯̀̔͒̑̈͛̂̃̑̓̄̊͌͆̎̉͐́̀̇͒̋̒́͊̈́͊̓̈̓̍̑͛̑̃͒̌͗̐̈́̈̈̒̏̀́͌̿̂͂̽́̂̉̅̽̀͌́̔̔̾̃͆̓͗͊͌̃͘̚̚̕̚̕͝͠͝͝ê̴̢̨̧̢̧̛̛͖̲̠̞͓̪͕͙̖̟̯͕̭̘͖̤͕̲̬͔͎̞͇̩̦̳̲̺͎͍̱̯͔̼͙̯͙̮͔̼͎̫͇̯͚̳̭̇̂̃̃̓̅͐́̆̀͑̅͌̓͑̏̄̆͊̅̀̒́̌̄̌̈́͆̋̔͐͊̓͒̈́̋̉͆̑͑̿̈͑̓̾͗̿̈̏͘̕͝͠͠ͅͅḩ̵̛̘̣͖̤̪͉̦͓͖̈́̎́̌̂̈͌̍̍͋͒̊͊́̑̓̓͘͘͘̚͜͝͝͝†̷̧̨̨̨̩̩̺͔̖̼̺͙̰̞͚̻̙̙̜͙̯̪͉̻͈̲͎͔͉̟̻̱̦̝̱̝͍̩̣̞͍̘̥̪̺̺̜̯̹̬̮̱͚̥̦̲̙̪̮̠̩̞̫̞͙̰̪̤͖̙̖̼̖͇͚̆̋̋̀̃͒̑̌͛̍̿̄̏͜͠ ̵̢̛̲͈̩̭͙͙̺̠͇̲̣̗̗͕͍͚̼̯̣̮̌̾̉̓͐̄͐̓̇̂̔͂̔̒̈́͌̏̓̔̾͆̈́͌̑̄͋̃̎͑͛̈́̃̋͑͑̍̍̀̂͆͛͂̇͒͂̃͐͊̈́̍̆͆̐͊̈́̓͑́̐̾͐̈́̒̔̓̾̈́̄̔̚͘̚̕̚͘͝͠͠ͅñ̸̨̢̡̳̙͔̗͕̙̩̝̖̹̪̺̟̼̝͓̬̻͓̮̣̜̖̤̯͖͕̗̝͖̩̬͎̳͚͙̤͙̞̺͉͇̱̩̪̞̭͙̱̫̯͚͓͌̋̄̃̔́̐̀̐̍̈́̽̑͋̋̉̽̌̅̈̅̓̇̓̈̚͘͘͜͝͝͝ð̷̡̧͈̭̤̙̦͇̺̝͖͖͈̤̦̤̗̐̅̓̓̓͐͒̐͗̓̃̈̿̾̒̈̈́̂̇̂̅̽̈̈́͊́͛̅̾̔̀̎̈̽̒̓̎̎̂̀̏̽̃̌̎̎̏́̒̓͗͐̾̍͒̓̏̽̚̕̕̕̕͝þ̴̨̢͕̙̯͈͉͈̳͔̪̥̲̯̥̞̜̪̬̺͖͈͉̼̟̠̥͈̮̻̼̤̤͎̘̪̻̗͐̉͌́̎͑̊́̇̈́͑͐͆̋̆̾͂̈̉̑̈̊́̾̈́̈͂̀͛͂̂͊̓̂̆̉̀͌̒͊͊́͆͛̿͑͌͗̏̽̎̋̚̚̚͘̕͜͜͝͝͠͝͝͝͝͝ͅµ̴̡̨̛̤̭͇̫̹̳͇̞̼̳̣̙̘̫͇͖͈͕̮̀̉̒̎̈̀̓͒̽͊̎͋̆́͂͒̎̉̎̒̑͆͌̒̂̎̂͋̇͌̄͛̑̏́͂̾̎͂̅͋͗̄́̿͌̔͌͘͘ ̶̧̧̧̮̩̜̝͈͙͖̼̦͕̥̻̬̣̜̣̣͉͙͕͔͓̟͚̩͎͍̣̟͔͚͚̼̦̥̯̠͎̩͎̣͈̦̯̰͎̦̜͚̀̇̄̎̀͑́͆̽̓̋̀̎̾̃̅̏͌͑̇̏͗̅́̽̈́͐̑͊͂̃́͐̈͐̀̍̽̔͗̊̓̓̾̉̄͗̈́̓͗̇̈́͛͗͒͑̏̈́̿͗̂̀͒̾̽́̀͒̓̔́̕̕̕͘͘͘͝͠͠͝͝͠͠͝ͅͅͅͅL̵̢̡̧̧̢̨̨̨̛͉̺̖͍̻͉̟̯͔͚͎͚̝̻̞̠͓̻̰͉̲̺̦̤͍̫͙̲̺̣̬̜͖̮̬̪̣͙̩̮̭̪͖͖̱̺͚͍̳̙͚̣̬̥̫̳͔̬͇͙̣̍̓̆͊͐̂̀̔̾͌̔͐͂̃̍̍̊̈̈̐̌̈́̔͂̎͊̅̏̍̽̚̚͜͝͝͝͝ͅͅl̴̢̧̢̩͍̩̫̙̤̦͇̟̪̩̙̠̮͖̩͇̘̼̫̼̲̣̟̩̘̟̳͇̜̠͔̗͈̯͙̞͓͛́̍͂́͑͛̇͂͌͆̇͂̾̐͑̒̌́̒̑̒̈́̃̉́͑̈́͋̓̒͒̽̉̔̆̈́͑͆̍͒̂͆͊̚̚͘͘͝å̶̡̢̢̢̡̨̨̡̢̛̮̰͚͕̹̘̼͈͖̠̲̗̰̥͈̪̲̱͕̦̘͎̖͇̗̜͇̬̤̞̱̯̟͎̲̦̩̜̳̮̟͈͇̫͎̯̗͙͔̼̒̊̐͊̍̂̈͑̑̎͊̒͑̊͋̽̂̉͜͜͝ͅͅͅ¢̶̡̧̧̛̜̲͕͇̮͙̹͎̘̦̖̺͕̪͔͈͉̝͓̖͖̫͖̥̌͛̅̀͆̎́̈́͒̃͑̋͘̕ͅ ̴̨̨̛̛̛̛̛̛̰͈͔̪̥̲̲̮͖̗̺͕͚͚̦̞͕̩̙̲̫̘͚̙͚̖̳̙͈̮͉̬̹̯̞̥͉̼̦̣̠̠̹͚̗̫̝̤̩͓̪̜͒̆͗̀̐̊̔̿̈͆̍͌̾̀̓̅͑͑̄́͂̓̋͆̇͆͆͑̎̑̆̽́̒͊͂̄͊̅͗̅͌͋͑͑̎̈́́̈́̆̿̏̈́̍̊̍́̄͋̀̉̿͛̏̌̉̊͌̒̌̑̌̚͘̚̕͜͜͠͝͠Ì̷̡̧̧̛̻̟̻̤̗̙̻̻̠̖̰̞͍̤̥̙̳̮͉̱͉̳͚̉͒̎̎͌̓̈́̐̓̅̍̈́̍̂̀͒̾͑̈̚͜͠,̴̡̢̨̡̨̡̧̧̛̰͉̫͎̼͍̬̠̬̳̠̫̳̼̻̜̞̪͔̖͓͇͉͖̥̩͚̫͇̱̤́̃͆̄̒͆̒͌̉̄̓̂̂̎̂̌̇̓̈́͌́̃̌̓̈́̋͐́̀͂̓̒̀̄͗̒͂̾̂̈́̍̌̎͂͌̏̊͘͘̕̕͠͝͝͠͠͝ ̷̡̨̛͍̗̙̹̻̳͖͉̟͇͖̙̖̹̙̰̩̘̗͉̗͇͙͔̝̗̯̫̭̬̰̩͉̥͖̪̤̮̟̖̯͖͔̫̦̰̞͍̹̠͔͇̠̣͉͙̖̙̪͔̪͎̍͐̌̀̎͑́̉̈́̐͗̋̅̄͗̈́̉͆̿̓̈́̑̓͐̋̈̇̽̑̈́̓͐͛͐̓̏͒̈́͋͂̎́͐̈́͌̏̓̎̉̾̚̚͘͝͝ͅͅͅÌ̵̢̧̧̨̢̛̛̛̼̙̩̖͓̫̥͎̳͖̟͍̙̦̟͔̲̯̱̮̣̻͙̪̹̭̞̻̠̠̟͔̭̘͔̝̯̮̳̺̗̪͇͇̳̼̦͎̺̩͈̑́͋̌̋̄͌̇̍̓͂̋̆̎̔͌̀͋͆̏̈́́̍̇̈́̿͐͊̅̇̒͐̾̽̌̇́̅̑̒̄͌̿́̈̏͌̂͌̽̿̌̽͛̏͗̋̾̍̈̈́̽͐̏̒̇̈́̂̃̚͘̕̚̚͜͠͝͝͠͝͝͠þ̸̧̧̨̢̨̛̱̲̜͍̤̺̭̮̫̯̼͕͈͍̮͎̥̫̖̙͙͍̞̱̳̜͕̙̯͈̯̣̬̹̰̘̤̣̫̯̙̲͔̝̲͇͙̖̗̬̪̭̱̯̙͈̰͓̱̲̯̈̑̿͌͜͜ͅͅÇ̸̧̢̨̡̨̨̡̛̛̛̛̛̛̲̜͎̙̖̞̪̝͉̹̣̙͙̠̣͈̭̥̺̰͇̤̰̹͔͍̹̥̱̬̫̠̙͖̱̙̞̮̘̟͇̥̹̺̺̝͇̲̣͖̭̭̥͋́̃̓̉̈́̒̂̏̀̉́̾́͆͛̐̂̏́́̇͂̀̏̇̆̓̓͑͐͊̾̾͌̂͑̀͛̏͐̂͒̏̎͆̋͒͛̐͊̃͋̇̈́̓̈́̈̆̚̚̕͜͜͜͜͠͠͝͝͝M̶̡̢̧̨̡̢̛̲̥̯͉̗̥̙̲̬̫͚̼̜̝̲̲͓̖̬͔̖̦͕̫̗͈̼̹̥̣̙͚̮̣̘̟͕̰͍̬̘̮̱̲̘̜̫͚̹̤̘̥̲̮̦̱̲͍͔̝̤̣̣͕̯͕͍̞̘̰̲̮͗̎̓̀́̀̾͐́͋̍̐̽̂͌͑̅̒̏̾̇̋̓̋̈́̈́̐̅͌̈́̀̿̏̈́̒͊̃̽̐̎̆̽̄̄́̊͗̉͋̅͗͒̔̀̐́̈́͌͗̑̀̑̋̍́͂̓̏̈́̐̓̚̕͘͜͝͠͝͝͝͝ͅͅ ̸̧̢̛̛̗̣̺̩̤̬͓͈̦̙̠͉͕̲͚͕͉̩̺̬̣̳͇͍̞͈̬̉̏̔͊̔͂̋̌͒̔̎̊͂͆̓͆̄͌̓̊̈́̐̀̋̅͗͋͊͌͑̿͋̊̈͒̅́͌͒͒́̋̈́̂͌͂̇͒̈̽̔͛̉̔̀͘̚̚͝͠†̷̨̨̡̡̡̨̢̡̥͖̫͕̭͕̣̜̹̺͍̤̞̩̤̮̙̟̞̝̱͇͖͕̗̪̺̝̳͈̘̬̰͉̳̭̼̗̝̞͚̫͕̺̬̪͎̤͉̣̱̩̜́̂͂̽͑̀̀̃̇̽͑̾̈́͑͐̂͝͝͝ͅͅḁ̶̢̡̢̨̧̭̳̺̼̪͔̻̯̗͎̠̪̥̟̙͔̬̳̤͎̪͍̥̳͈̤̱̩̦͇͈̳̻͉̻̥̺͉͓̣̟̝̺̱̣̰̙̱̹̞̱̣̘͍̜̩̥̳̥̭̻̠̥̬͚̤̫̩̮̯̜͍̊̌̀͊́͂̓̒̀̈́̎͑̌́͆̒̇̽̂̿̋̓͊͂̑̌͂͛̿̊͌̈́̈̅̎͋͂͐͑̏̊̑̉͒̎͑̃̎̾̌̈̀̅͐̿̎̒̄̐̌̃̿̈́̎̉̿͋̑̌̂̑́̌̂̇͛̾̕̕̚̚͜͠͝͝͝ȩ̸̢̛̲͖̳̦̖̝͈͉̬̟͚̲͍͚̬̲̥̳͙̰͖̺̙̥̜͈̹̪͚̗̰̹͍̘͓͙̞̬̤̫̞͉̤̲͔̘̭̻̯͍̂͑͊̇̾̀͐̐́̅̒̋̃̑̅͋̀̌͒̆̇́̾̾͂̀̒́̍̒̄̏̓͗̄͑̓̏́̇͒͑͊͑̾̐͗̉͆̅̓̔͗̾̍̏͆͂̾̅͊̽̆̄͌̕̚̚͜͝͝͠͝͠͠͝ͅͅͅͅr̴̢̡̨̡̡̢̧̡̢̨̛̛̛̗͙͖̱̖̣̣̰̻̘̮̻͉̳̙͈̳͚͓̟̦͚͕͓͈̬̥͚̪̰̘̗̮͖̯̬̯̲̠͎͍͔̯̩̱͕̲̺̖̥͈̼͍̤̗͕̻̗̘̙̥̦̼͔̘̰̹̱̰̫̜͇͎͚̞̥̝̉͂̈͐̃̒̔̑̈́̉̒̃̄̀̈́̃̔͆̄̓͋͐̓̍̊̉̍̈́́̒̓̍͛͌̾̎͘͜͜͝͝͝ͅͅģ̶̧̡̧̧̨̧̡̡̨̛̛̹̻̥̱͕̥͙̮̣̻̖̭̪͚͍͖̬̲̠̞̭͈̼̙̼̼̺͍͚̟̭̫̯̦̬̭̤̙̺̪̹̣̦̘̭̠̞͕̳̻͙̟̼͉̘̞̥̭̪̺͔̼̠͖̫̥̬̦̳͈̱̱̳̀͊̅͛̎̆̓̑͒̉̀́̎̔̇̈̂̓̓̏̈̔̇͛̏̑̊͐̈́̀͊̎̏̆̿͗̂̓̊͂͒̌̄̄̔̈̔̏̔͊͊̏̂̅̄͒̀̇̚̚͜͝͝͝͝͝ ̷̢̧̡̢̢̧̺̗̙͉̠̺̤̝̲͔̠̹̬̬͎̪̖̜̘̪̪͚̹̜̥̖̻̙̩̝͕̥͚̜̣̞̫͎͚̪̰̣̭̻̠̲̮͙͙͈̜̣̲̫̺͖̤͉͙̤̻̲͖̙͗͜͜͜͜H̵̨̧̡̡̨̧̛̛̛̛̛̫͈͔̲̭̠̮̪͕̳̼̞̞͈̪̲̺̤̗͓͙̠̬̪͈̩͇͈͎̤̼̳̣̰͉̯̻̋͂̌͂̋͒̂̎̂̑͂̑͐̌̈́̌͑́͐̀̆̏̎̀͌͗̅̉̇̾̆̋̂͒̋̈́̾̓̏͌̈̏͐̈́̇̓̅́̓́͗͋̀̓͑̿̑̅̀̎͊͋̌̀͆͛̕͘̚̕̚͜͝͠͝͝͝ð̶̨̧̨̧̛͇̟͔̮͉̹̻̘͔̞͇̬̹͚̞̗͓̘̠̺̹͚̝̳̗͚͚̝͈̣̠͖̦͙̰̹͍̬̘͙͚͙̺̘̩̙̰̖͇̤̺̎́͛̍̓̊̒̈́̈́̋̈́̋̋̓̾͋̈́͐̈̓͋͋̄̑̒͛̑̄̉̅͋̽̓̋͑̉́̋͑͗̽̂͊͆̊̉̀͑̍̊̑̏̒̄́̆̊̆͒͌̒̾̌̓̐͛̄́̆̇̿̅̃͗̈̄̈́̄̓̎͐͘̚͘̚͘͘͘̕͠͝͝͠͝ͅͅ!̸̢͇̺̲͙̣͚̮͙̝͖͚̒̽̌͂̓́̌̒̓̋̓͐͑̐͋̐̀̔̊̍̂̎̍̆̓̅̒͋̆̇͂̑̀̔͊̏̕͘͝ 2023-11-13 17:45:05 -05:00
80c0f24a5d J̶̨̡̨̨̧̧̧̧̨̢̢̢̧̡̨̢̨̢̢̧̧̢̡̡̧̨̤̩̱̗̣̗̱̮͇͇̻͕͉͇̗̭͕̻̝̼̻̤̞͍̫̣͔̗̠̠̪͕̮̙̤͓̯̦̙̬̫͙̖̙͙̬̜̗̙̬̩͔̹̱̠̩͎̞̪͖̯̹̲͙̥͈͕̼̜̪̙͔̖͈̞̣̝̦̤̺̺͓̮͓̮̝̤͙̗͉̗̞̟͈̞̼͕̩̻̥͖̤͇̪̪͍̗̥̼̲̝͇̜̥͚͍͕̞̝̖͔̜̦̮̫͍̜̬̥̲̮̜͈̠͙̭̱͇̥͈͇̩͖̝̱̪̹̜͕͈̫̦̭͉̞̪̤̗͙͚̰̙̝͚̹̝̫̪̤͇̠̮̤̜̭̰̞͚̝̫̭͉͕̠̻̤͕̫̳͓̳̯͍̣̭̘̤͚̯̖͓̼͕̥̞̘̤̣͔̥̮͉͍̝̣͇̳͇͎͈͖̤͎̯̬̬̭̗̫͚̹̫͉̮͋̕͜͜ͅͅͅu̶̢̡̢̧̧̡̡̨̡̧̢̧̨̢̢̧̧͚̟̥̘̭͇͈̳͔̠͓͔͉̱͙͓̪̱͚͉̬͎͉͚̹̩̪̥̤͍̖̜̼̦͍͎̫͇͉͔͔̙̪̝̱̥̭̠̭͈̙̗͓̲͙̰̻̲̬̪͖̤̹̘̬̻̜͙̫͇͎͚̺̩̬̬̰̬̣̲̯͓̝̝̹͖̼͓̹̺̯̱͚̗̩̱̠̠̺͎̮̮̪̤̝͇͚̫̹̼̗̺̻̗͓̠͕̯̯̱̘͎̳̱͉̙̪͇͓̼̯̙̘̪̲̳̭̝̹̦̮̳̗͔͈̪̰͇̖̥͕͓̺͇͔̝̲̫͉̣̭̥̹̼͖̺̰̳̪̠͕͉͚͎̪̪͎̪̩͍͛̊̈́̾͒̈̂͐̑̿͑̀̾̎̋͗̒͋̄̑͐͗́̈́̎̆̉͛̎̋̐͗͒̄̑͌͆̀̉̐̓͐̆͂̂̿̓̇̽͒̀̀̍̓͒͛͆̇̂͒́̄̔͛̎́̓͆̈͐͒͛̽̕͘͘̚̚̕͘̕͘͜͜͜͝͠͠͝͝͠͝͠͠͠ͅͅͅͅͅͅͅͅͅs̷̡̧̨̡̢̢̨̧̨̧̢̢̡̨̡̧̢̨̢̡̨̢̢̨̧̡̛̛̛̛̛̛̛̥̹̳̬͚̠̼̲̬̞̺̤͈̪̲͓̣̤̬̘̰̮̪̟͍̪̗̦̲̺͉̦̤̟̖̲̲̠͉̙̜͇̞͓̻̣̞͉̝̪̺̰͓̝̥͙̘͎̘̭͎̺̮̼̥̩͓̘̠̺̪͚̝̯͈͚̬̦̯̦͕͖̰̭̠͇̣̙͉̻̘̜̟̤͔̳̣̖̻͚͚̻̺̦̳̣̘̣̩͉͈̳͎̫̯͕̪̠͕̲͚̜̗̗̫̫̱͎̯̙̣̗̫̭͎̩̫̟͚̦̟̙̤͉̜͔͙̙͙̫̣̮̱͙̳̺̺̗̼̻͍̣͍͙̯̝̼͕̭̦͖̻̝͍̝̪̮͇̯͔̼̣̩͕͕̘̭͕̖͓̭̉͒̂̌̐̂͑̋͂͋̈͐̈́̄̂̅͗͋̾̓͌̈̀̇̂̇̃̉̎́̀̏̐̐̽̿̏̈́͗͑̓̇̊̊̇̓̈́̒̀̅̈͗̓̌̄͂̽͆̇̓̄̿̃̀͛͊̽̉̑̉̑̆̅̽̎͒̔̔̒̍͆̑̐̽̄͛̐̀́̓̈́͋̍̿́͂͊̃͐͐͋̊̌̒̾͗̓͊͐̋́̔̍́̐̑̌̏̆̓͋̐͗̀͋̆̓̃̇͂͗̎̅̈́͒͗͗̔̆̈̃͋̆̒̇̄͗̋̓̔͛̉̈́̑̂̉̐̋̎̅̅̆͒̈̀͂̾̂̐̂̊͋͋̔̃͋͆̑̇̂̾̆̎̈́̉̍̽͊͊̏̎̏͐͋͂́̾̀̓̽̐̀̓̉͂̅̂̋̅̇̚̚͘̕̕͘̚̚̚͘͘̕͜͜͜͜͜͜͜͜͜͜͝͝͝͠͝͝͝͠͝͠͠͝͝ͅͅͅt̵̡̧̛̛̛̛̛͙͉͍̱̰̘͍̻̬̝̦͎̣̖̙̠̬̻̝͔̣̲̩͍̱̑͒̍͊̊̎́̊̂̂̄̽̿̀̍͌̏̽̿́̍̆͆͗̔̈́́͊͂̆̾̿̐̓̈́̓͑̑̋͗̀͐͛̐͐́́̒͂̆̒̉͌̇̄̀̃̆̂͛̽͐͌̓͗̾̔̊͐̎͐̄͌͋̐̅͋͋͒̋̊̊̀͂̇͛̅̂̐̀͒̒̉̇̃̒̔̔̍͌̒̌̌͊͐͂̑͒̾̽͊̈́͑̐̈̑̉̽̇̆̓͂̋͌́̿̓̇̀̏̾̈́̏̌̔̉̐̽̃̿̈̈̉̈͌͐̊́̾̊̔̉͆̄͆̈́̈́̍̈̃̽̊̉͌̆͑͆̊̽̽̒̒̿̏͋́̀̅̍̏̑̈̿̋̃̈̄̏̋̋̈́̎͆̍͛̀̈̂̀̀̀̈́̐͑͌͑͒́̀̎͛̒̍͗̊̉̒͋͋͒͐̌̏̆̑̓̈́̾̒͂̆͌͆̀͊̐̎̂̅̾̋̔̂̀̍̏̓́̇̽̾̅̚̚̚̚̕̚̚̕̕͘̕̚̚͘̕͘͘̚̕͘̚̚̚͜͜͝͝͝͝͝͠͝͝͝͠͠͝͠͠͠͝͝͝ͅ ̸̡̧̡̡̧̧̧̧̡̨̡̨̨̧̧̢̛̛̛̛̛̛̘̰͓̼͍̗̥̮͕̝̞̟͇̞̙̻͙̯͕̗̺̠̺̗̭̰̗̺̗̲̥̯͎̫̻͔͓̩̜̦̘͓̬̳̟̻͈͔̯̩͕̙̩̝̬͇̣͓͇̱̹̼̹̹̩̰̣̹͈͈̬̜̳̪̹̠͓̥͎̩̥̥̳̱̩̹̝̘͕̗̘̲͓̺̱̹̫̱̟̜̺̹̥͎̳̺̹̘̞̼̟̪͉̝̼̣̤͓̮̩͍̜͍͖̻̺͈̤̹̙͇͙̭̙̜̰̻͙̣͕̼̘̠͓͉̲̻̟̻̦̺͕͍̦̩͖̰̥̩̱̱͚̩̹̰̹̙̫̟̣̗̝̹̝͉̻͉̟̗̙̫͖͈͖̬̜̬̞͍̭̻̤̣̪̭͍̗̠̬̘͕̠͈̖̥̓̀̈̉́̆̌̅̈͊̊̔͗̀͆͒̓͗̽͋̉̒̈́̃͛̾̄̄̀̍̑̀͗͋͛̓̈́̓̈̓̊̅̔̀̓̾̄̈̓̂͊͛́̾̉̉̎̍̆̅͆̀̇̈́͆̌̔̓̈́͌̄̈́̋͌̍̅̓̈͐́̉̀̓̊̍̽͗̂͑̐̔̅͆̀̎̓͊̽̔͑̽̂̓̇̓͐̎͑͛̽̄̈́̉̾͒̍̑̀̐̓̀̇̿̈́̎̊͂͑̇̎͆̇̄͒͋̀̿̓̐͆̈́̂̿̏͂̍̈͌̏̆̿͋̈͂́͗̎͊͒̅̈́̋̃̉̽̀̿̎̈̅̇̽̒́̐̈́̎̑̄̂͗͛̌̄͊̀̓͋͘̕̕͘̚͘͘̕̕̚̕̕̚͘̚͜͜͜͜͜͝͝͠͝͠͠͝͠͝͠͝͝͝͝͠͠͝͝͝͠͠͝͝͠͝͝ͅͅͅͅͅͅͅF̷̢̨̧̨̡̧̢̛̛̛̛͓͈̱̯̬̭͖̫̞̻͖̲̭̝͕̤̤̜̬̖̺̹͎̺͚͎͙̮̟̖̗̻͚͕̙̦̱͚̝̯̜̙̩͈̱̙͖̞̞̰̳͕̦̬̙̉̏̈́̑̎͛͑̆̆̽̉͂̏̑̅̌̿̔͛̿͌̏̿͋̈̐̾̃̈́̾̃̃̀͒̈́͋̅̇̐͒͆̿̄͋̉̋̏́̅͊͑̆̔̽͌͗̒̀̽̍͗́͋̔͆̎͊̊͌͑̾̈̂̑̿͆͛̅̒̇̈́̆́̉͊̆͐̀̋̊͛̌͌̈́͑̿̓̐̈́̅͌̑̅̒͋̒̈́̈́̃̈́̃̂̍̐̏̾͒̀̉̌̀́̂͐̌̒̇̉̅͗̓̈́̽̍̇̂̉̅̿̒̓̾͂̾̿̈́̂̔͋̆̈́̈͌̃̍̈́̎̈̑͆̅̓͗͆͋̈́̂̀́̏͑̃̂̍̐̃͆̓̕̕̕̕̕̕͘̕͘̕̕͘͘͜͜͜͜͝͠͝͝͝͝͝͠͝͝͝͝͝ͅͅͅi̵̢̧̢̨̢̨̧̛̛̛̥̣͕̤̤̥̺̪̝͖̫̪̻̠̲̹̞̟͖̲͕͓̝̲͉͇̙̻̞̤̩̟̣͈̜̞͈̠͇͈͍̜͔̙̦͚͔̣̙̪͙̩̝̮͇̪͙͉͖̪͈͖͖̳̗̯̠͉̭̋͗̄̾̂͆̆̐͛͗́͆͌̃̉̂̋̓̇͑̈́̓̊̀̂͆̒̾͛͗̉̌̍̅̑̀͊͑͛̐͋͆̽̎̑̂̎͑̑̌̓́̈́̒̂͌͛͐̐̿̽̈́̐̀́͆̐̌͊͊́͒̌̂͑̏̔̎͂̍̏͑̇̍̑͊͊̀̂͂̈́̎̅̔̍̅̑̅̽̃͑͒͗̿̑̔̒̑͋͂̂̑̍̄̇͒̐̌̽̀͊̔̊͋͒̾̂̿̏́̀̃̇͐̔̈́́̊̽̄̉̅̓̈̾̀̓̄͂͛̂́̍̉͆͂̓̀̂̓̎̉̎̔̓̐̂̂́̌̕̚̕̕̚̚͘͘͘̚̕̚̚͘͘̚͜͜͝͝͝͝͝͝͝͝͝͝͠ͅͅͅx̶̢̨̢̧̧̧̨̧̧̢̧̧̨̛̛̛̛̛̛̮͎̜̳̻͕̥̰͇̺̝̤͖̬̲͓̫̗͇͎̻̯͍͙̺͉̱͔̤̫̻͚̣̹̥̰̼̫̱̫͖̱̙͓̭̞͇̪̯̘̠̯̩͙͕̙̼̣̪̻̻̥̹͍̹̭̫͓̱̻̖̮̹̮̥̥͕̲͉̝͈̥̗̪̥͚͚͚͕̺̠̹͔̫̤̰̘̯͕̳͈̭͖̣͖̹͖̩̼͙̯̭̣͈̣͇͈̘̫̖̠̞͍̬̫̲̳̻̹̱̳̞͙͔̠̱͕̮̯͉̩̪͎̯̪̻̜͒̇̋̂̋̽͗̔́̐̂̂̾͆̑͗̏̐̈́̃͐̊͌̓̓̐̌̈̇̽̋͛̐͋̄̏͑͋̿̿͆̈́̐̾̈́͗͌́͑́͗̍͒̌̒̅̇͌̽̊̈́̾̒͒͒͆̅̾͌̑͛͑͒́̍̉̏̊́͂̌̇̔͛̾̾̓̽̑̌̾̏̔͋̾̈̊̑̎͋̈́̄̾̄̅͋͐̿̆̋̈̄̐͊̆͋̋̽̂̌́͆͆̎̇̄̃͊̈́̉̔̍̓͆͑̃̋͂̀̉̏̉̓͊̽́͊̓̈́͑̂̑̎̉́̈̈̋̂̈́̒̽̓̑̐́̇͒̊̿̎̔̑͊̿̈̀̈̅̈́̑̊͒̎̏̄͆̈́̇̄́̈́̑̓͗̒̃͒̀̈́̅́̑͑̂̃̂̿̆͌̎͆͌͋̅͑͋͊̈́̓̾̂̏̀̾̔̅̐́̏̓̈͊͋̇͐̅̽͌̂̀̓̏̒̿͌̿͗͗̎̾̀̈́̓̈́̊̚̚͘̚̚̚̚̚͘̕̚̚̚͘̚͜͜͜͜͜͜͜͠͝͝͝͠͝͝͝͠͝͠͝͝͠͝͝͠͝ͅͅͅͅͅͅͅͅ ̸̡̨̧̢̧̢̢̨̧̢̡̢̧̧̨̡̧̨̛̪̜̼̟̤͚̯͓̪̦̥͎̯͕̟͍͚̼̩̩̤̖̥̤̤̳̻͕̼̣͍̜͙̙̭͙̗͇̣͎̦̭͔͙̥̯̬̭̯̞̼͓̳͙͉̲͍͚̲̺͕͕̟̼̻͇͔̺̼͙̦̣̝̖͍̻͍͎̣̹̻̯̲̗̝̤̞̗͍̭̮̮͕̣̗͋̅́̍̍͌̉̊̃̓̓̂̈́͐̓̇̉̋͋̅̊̔͆͗̅̑̓̀̂̍̆̈́̈́̉̃̃̾̏̀͗́̒̌̈͌̅̿̏͆͒̌̀͛̓̐̋̾̀̈́́̾̇̈́̿̀̈́̊́́͛̽̀͌̔̈͆̉͌͋̑̌̈́̽̈́̉̀͛̓͋͗̚͘̚̚͜͜͜͠͝͝͝͠͝͠͠ͅT̴̢̢̡̢̨̡̧̡̢̧̧̡̡̡̨̨̛̛̛̛̛͖̻̯̼̗̫͕̥̝̦̹̪̙̖̩̯̮̦̗̤͚͙͙̬̣̙͈̥͓̬̰̗̤̞͖̞̪̣͎̬͈̹͕͔̦̤̙̝̣̗̜̘͎͙͕͇̟̟̠̮̹̪͖̟͎̼̯̻̮̭͕̬̖͖̼̺̟̠̫̳̖̜̳̖͕̫͔̺̼̯̫̯̫̘̙͔̰͍͎̜̭͎̖͎͚̬̘͔̯̞̝̞̜̣̥̼̙͔̤̦̭̲͍̝̩̼̦̣͇̘̟̦̳͚͔͔̟̣̼̺͎̮̟̖̠̞̗͍̪̯̠̱̭̬̰͍͓̝̲̯̙̭̯̤͕͓̲̹̣̼̦̳̝̞̰͔͍͂̿̓̔͗͌̋̆̓̋̈́̽͑͒̓̈̎̇͗͂̒͐̅̽͗͂̂̇̓̀̍̈́͗̐͂̇̇̽͑̾̏̊̑̓̋̒̒̿͐̐̿̓̅͋̑̋͛͋͗͌̌̑͂̐̏̇̽̑͛̓͗̓̃̂̈́͛̈́̆̌̆̓̋̆̏̊̾́͊̀̐͛̿̅̃̑͑̔̀͂̾̇͑̿̎̐͌͌͌̿̈̽̃́̃̆̆̈̋͑͊̍̈͛͊̐̐̀̍́͊̿̂̌͗͑̃̐̍̊̐̑̈́͛̔̏́̋̈́̑̔͆̎͋̏̒͗̍͗̋͑͂͑̐̑̏̿̃̅͆͒̽̈́͋̋̀̈́̽̑͗̂̿̑̓͐́̊͋̾̄͑̂͐͗̓͛͆̀̏̈́̊́̈́̍̈́̽̂̊̈́̆͊͗̽̈́̓͊̂̅́͗͌́̾̑̀̊͋̀͘̚̚͘̕̚͘̕̚̕̕̕̚̚͘̕͘̚̚͘͜͜͜͜͜͜͜͝͠͠͠͠͝͠͝͠͝͝͝͝͝͠͠͝͝ͅͅͅͅͅͅḧ̵̢̨̨̡̢̡̡̢̡̨̧̡̨̡̢̧̧̨̨̧̢̨̛̛̛̛̛̛̹̞̥͇̘̰̭͖͙͖̥̙̗̹̘͔̞̬̟̠͓͔̪͇̗͈̠̭̱̘̘͎̲̭̼̯̺̘̤̖̲̜̪͔̻̘͕̞͙̜̻͙̦̞̰͉͓̖̞̖͇̺̗̜̩̩̪̺̣̹̺̥͇̘͍͎̫̦͇̻͓̲̗̼͖̙͍̪̙͉̬͓̝̹̳͈̠͎̤̥̯̩̬͙̫̮͕̦͕̻̫̞̙̲͈̤͉͙̤͔̰̗̜̲̹͔̫͈̜̲̦̮͎̗͔̥̤̣̯͈̲͇̝͎͔̺̙̗̲̫̭̟̓̏͋̎̑̂̈́̀̄̉̾͋̍̒̑́̐̈͊͗͊̾̾͛̽̎̊͒̑̈́̀̑͌̌͗̑͋̍̔̎̍͋͗͂́̌̆̏͊͌͒͐͊̈́́͋̈́̒̅͒́̓̉̓́͌̐̓̎̀͂̄̉͌͂̍̌̒́̌͌̃̀̇̂̒̓́́́̃̾̉́̒̆̈̒͒̌͛͋̋̂̒̈͊͐̀͐̾͐̄͋͌̈̐̓͑̍̅͋́̀͂͛͐̉̿͒͌̈́̅̈́̆̉͊̑͊̈́͒͐̌̆́̈́̔͐͋́͐́̆͌͂͂͗̀̋͊̎̏̑̑͛͋̈́̌̿̾̂͋́̅͂̌͌̅́̄͌̎̇͋̾̀̓̀̑̚̕͘̕͘̕̕͘̕̕͜͜͜͠͝͝͝͝͝͝͝͝͝͠͝͠͝͝͠͠͠͠͝͝ͅͅͅͅͅȩ̸̢̢̡̧̨̡̡̨̨̡̛̛̛̛̛̩̪̫̲̣̹̦̝̠̺̬͖̥̬̝̞̥̦̣̤͍̘͈͉̤̘̬͉̖̫̼̘̬͕̗̲̞̟͈͖̥͖̞͔̞̣̘̙̙͖̱̮̙͉̬̤͎̲̙̦̲̱̹͓͉͕̞̰̳̤̰͍̠̻͕̥̺͙̹͇̳͈̻͌́́̀̋͂͒͗̉̏̌̆̒͒͆͒͋͌̀͒͆̂̔́̈̈́͂̾͂̓͗̓͒̆͋̏͛͒̐̈́̋̐̈́͛̉́͆̅͆̾̂̉̄͊̓͆̊͑͐̔̒͂̒̏̆̀̌̉̓̃̔̈̓͛͗̍́̀̉̅͌̀͋͋̒̿̍̒̍̈́̆̐̐͋͆̉̆͒͑̉̅͂̓̿͛́̌͊̍̊̽̽́̓̈́̿̍͑̔́̑̆͗̎͛̅̐̿̑͆͌̉̓̊̑̈́̋́̎̇͂͒̑̇̾͆͘̚͘̕̕̕̕͘͝͠͠͝͝͝ͅͅͅ ̴̡̡̨̨̧̧̢̡̧̡̡̢̡̡̢̡̨̧̧̡̢̛̛̛̛͔̝̦͉̜̭̹̫͕̻̫̳̩̰̖̤̮̮̬̱̖̱͕͙̲̹̞͎͚̻͎͎̜̗̻̪̥̥͈̖͖̖̗͎̖̼̺͖̫̪͙̻͚̱͙͚̤̞̮̯͉̲̰̼̥̙͔̱̹̭̗͙͖̥̥͕̙͎̖̮̼̤̻̙̟̹̣̞̼̫̗̳͇̖̮͍̪̹̞̦̙̹̮̭̫͍̭̹̯̗͍̣͕̱̭͓̩̗̭͍̰̱̦̮̤͓̲̮̞̖̘̲͚̗̜̲̯̱̠͍̠̺̰̳̙͎͉͉̟̮̲̩̖̤͙̰̖̙̤̹͙̭͎̹̺͙̼̠̻͉̯̪̪̫̳̰͇̘̣̻̪̙̗̠̝̤̩̤̣͚̦̹͖͚͖̜̳̦̝̺̳̻̼̩̹͖̥̞̗̥̩̱͐̓̂̊́̄̃̈́̏͋̿̿͂̐̎̈́͊̈̌͒̇͐͊̆̽̅̔̓̎̃̀͗̾̓͋͆̃̌̀̾̋̽̇͛̿̀͒̄́̉́̀̉͛̅̎̀̽͋͑͋͗̊̀͋̾͛̈́̇̐̓̏̄̂̅͘͘̚̚͘̕̕͘͜͠͠͠͝͠͝͝͝ͅͅB̴̨̧̨̢̡̨̨̨̡̨̧̡̡̢̢̡̡̛̛̲͕̹̠̮̠͖͇̮̩̰͎̱͕̳͈̱̫̹̮̗̠̙͓̮̖̻̫̟̣̗͕̫͇̗̥͔͔̩̳̥͙͔͙̥̻͙͉̣̯̮̰̩̹̼͎͓̜͈̜̖̰̣̹͕͚͔̜̹̭̗̖͍̪͔̙̭͖̹̹̮̜̮̤̜͔̜̺͕̮̯̦̣̱̖͍̭͎̦̣͎͔͚̙̩͇͓̫͎̼̻͖̼̮͖͓̼͈̞̘̤͇͈̺̞̗͔̩̮̪̱̠̬̼̺̬̲̤̖͕͍̣̤̦̘̻̹̠̘͖̥̜̮̤̰̬̖͈̤̀̈́̉̇̑̇̈̄̑̀͊̓̈́͌̾̀͊̾̀͆͑́̂͛̋̓̅͌̆̓̌̇̈͒̾̾̽̇̈̅͛̐͊̓̉̌͂̂̅͗̆͛̀̋͋̂̌͛̈͌͊͆̀͐̊̑͒̃͂̌̾̏̂͛̉͌̉̄̈́̄̀̈́̉̌͋̈́̅̀̐̀̾̈́̓̽͑̃̏͒̄̓̍̌́̀̿̐̿͒̈́̌̃̏̈́̏̈́̅͗̂̾́̆͌̏͒́̈́́̑̾̆͒̄̓̈́́̈́̀̇̒̒͋̇̈̔́̀̽̎͌̎̌̊̚̚̚͘̚̚̚̕̕͘͜͜͜͜͝͠͝͝͝͝͠͠͝͠͠͠͝͠͝͠͠͠ͅͅͅͅư̵̢̧̡̨̡̢̡̧̨̢̧̡̡̨̡̛̛̛̛̛̭̮͕̳̜̬̠̟͎͎̘̜̹̣̥̦͎̰̺̼̹̣͕̰̖͔̣̳͉͙͚̫͎̹̫͍̟̫̺͈̫͔̺̗̬̖̳̖̯͖̲̤̦̙̹̠̬̭̺̥̲̦͇̳͖̤͖͉̮͉͇̟͍͔̟͍͕͍͕̙̱̘̜̺̲̠̞̹̟͚̦͈̘̦̼̠̟̳̳̝͎̟̟̣̮̙͚̱̱̝͈̭͍̟͐̑͋̍̂̆͂̓̽̈́́̈́̑̅͊̔͑͐̓͋͆̄̅̔͒̇̋̒̓́̏̀̉̒̀̿̐̈́͗̃̏̅̾͊͗̎̏̀͆̄̈́̇̈̔̔̏̇́̀̈́̒͐̑̏̾̌̐̉̒̏̏͌̄̒̇̍̃̊̏̅̓̃͐͗̓̽̌͌͌̌̓̑̓́̂̽̓͛̂̀͌̾̄͆̀̅̌̒̆͗̐̊͆͒̀̔͆̔̏̀͒̍͋̀̅͛̒̂͂̅̉͋̿̿͌͛̍͗͑́̀̃̀̏͋̃̓̿̆̈́͘̚͘̕͘͘͘̕̚͜͜͠͝͠͝͝͝͝͝͠͝͝͠ͅͅͅį̵̛̛̛̲̫̯̟͔͖̟͇̦̠͓̘̪̻͋̾̀̿̌̀̑̿̍̈́͋̒̔̄̑̏̄̏̒͐͋̏̍̏̋̈́̃́̇̋̀̃̆̈́͒̒̅͑̈́͑̈̾̌̀̒̾̈́̊͂̅͋̃̽̃̑͋̄̍̎̑̃͒̐͂̋̊͒̌̋͌̈́̂̇̋̑͆̄͒̀͑̿͐͗̈͑̈̇̓̇̈́͋̌̄̉̂̀̀̈́̀͂̆̆͗̋̄̅̈́̔́̀̂̾̇̊͗̿͊̀̋̾̎͐̑̉͛̉̓̾̐͌̊̆̍͆̈́̆͊͂́͊̒̀͆́̌̋̾͛̈́̾̍͋̍̉͛̽̽͆̊̀̄͗̃͒͆̐̓̈͐̔̓̅̓͌̋̕̚̚̕͘̕̚̕͘̚̚͘͜͝͝͝͝͠͝͠͝͝͝͠͝͝͝͠͝͠͝͝l̸̢̨̨̧̢̢̨̡̧̧̨̢̡̢̡̡̡̢̡̡̡̨̨̛̛̛̝̰̜͎̹͉͔͓̹̱̞̥̦̘̯̩̣͈̤̙̘͈̗͖̺͇̳͙͔̩̯̱͍̱̝͖̮̭̼̬̬̙̘̜̼͉̺͔͔͇̜͖̞͔̱̱̱̘̝̦̻̘͚̤̤͈̞̟̟͚̠̯̪͖͉͖̪͔̻̖͍͖̘̟͖̳̦̻͖̮͍̬̥͚̼͔̩̯̳̯̗͚̭͚̤̩͖͍̱̻̮̦͈̪̱̹͇̬͕͉̬̦̝̜̳̣͉̘̑͐͐̅́̾͌̄͋̋̀̊͒̓̅̑̿͑͗͌̃̈́́̑̔̀̑͆͛̆̐͛͊͆̍̐͋̔̋͋̈͗̃̃̓͊̀̆͆͒̀̑̒̃́̅̆̒̈́̽̈́̒̽͌̐̌́̓̽̾͑̓̅̂̇̐̊̈́̏̾̾̀̉͒̃̾͛͐͊͆̇͌̅̈́̔͛͐̄̈̊̓̋̈́̾͑̈́̀̆̎͑́͊̀̎̐͌̋̋̅͒̒͆͋́́̈́̏̔̾͋͂̄̕̚̕̚͜͜͜͜͝͝͝͝͝͠͠͝͠͠ͅͅd̴̢̢̡̛̛̛̛̛̛̛̛̪͔̖͇͚͓̩̪͔̜͓̣͍̫̳̺̳͇̖͖̟͉̹̟̪̫̖̜̩͙̗͕̳̹̥̭̩̙̹͔͙̟͔̥̰̙̆̂̈́̍̔̌̈́̃̿̒̏̓͐͆̎̎́͗̈̽͌̆̆̑͂͛̃̆̈́͗̇͐̿̈́͒̽̌͗̾̌̐̓̈́̽͗̾̇̑̔̂́̓̓͛͋̏́̏̑̓̍̑̓̃̂̀̀̏̆͋̉̇̀͂͗̄͐̊̈̓͊̈́̽͑́̽̅̽̓̑̈́̂̈́͋́͗̑̇͋̒̋̎͛̈́̿̃̔̐͂̍̀̃̔̀̏͂̅͋̆͆̇͒̈́̾̽͂̎͊̀̄͛́́͋̉͗̓͒͌̈́̏͑̆͒̏̓̃̓͐̏̈́̋͛́́̂̈́̓̋̐̅̏͗̓̓̅͋̔́͋̏͑̑̀̓͐͒͌̀͛̔̐̓̈́̉̈̈́̍̋̄̈́͋̇̆͑̂͗̾̂̒̉̍̈̐̐͑͑̂̾͋̀̐͆̔̌̆̍̽̅͆̓͋̀̽̔̈̽̀̃͑̉̂̈̄͆̌͗̃̎̈́̇̓̍̈́̌̃̋̚̚̕̕̕̕̚̕̕̕͘̕͘̕̕̚̚̚̕̕͘͜͠͝͝͝͝͝͠͝͝͝͠͝͝͝͠͠͝͝͝͠͠͝ͅ ̵̡̨̨̧̨̧̧̨̛̛̛̪͍͖̜̟̫̬͚̦̮̪͚͓͈͙͕̺̮̬͍̯̼̞̤̙̬͚͚̖̳̹̙̤̦͙̖̼̜̫̟̘̺͖͖̰̗̦͔̫̟̗̞̹͇̣͕̫͇͔̪̬̯̩̥̭̗̫̤͉̖̻̳͔͎̤̪̻̜̦̬̫̩̟͚̺̼̩͎̖͚̩̫͖̰͐͋͑̎̎́̊͒̈́͗͆͗͑̀͌̐̎͂̑̏̾̈̈́̈́̃͌́̄̈̿̍̊͊̉̇̀̾͌͐̐̄̐̂̈́̏̒̈̀̀̎̊͋͐̈̏̅̾̈̎̆̂̍̅̈̀͌̒͌̈́̇͑̇͌͂̅̈́͐́̇͌̓͊͑̃͐̓̉̈́̊̒̀̎̔̾̉̌̓̊͌̓͋͒̏̒̀̈́͒́̓̂̂̌̄̈́̀̊̐̈́͂̓̈́͊͛̃̾̈̿̆̿̍̔̈́̽͌̊̅͆̎̊͑̉́͛̌͑̏̒̈́̈̍̔̿̊̀̂̊̾̌̃́̈̈́̐̃͆̽̒̅͊̓̿́͋̀͊́̂̍̿̐̀͋̀̂̈͑̄̍̔͌́̆͑̑̎̌̊̈́͊̿̈́́̂̇̉̋̆̌̕͘͘͘͘̚͘͘̕̚̚̕̕͜͜͜͝͠͝͠͝͝͠͝͝͝͝͠ͅͅ(̴̢̧̡̧̛̘̭̗̥̙͉̮̯͉̦̯̦̫̙̹͚̜̜̥͙̰̯͇̖̩̼̲̙͚̣͍̳̲̬͖̜̼͙̤͓̫̟̺̻̹̲̖̗̺̥̫̘͓̻̗͎̪͎̖̩̩̦̦͈̣̣̺͉̺̥͎̠̯̦͚̝͈̬̲̭̻͍͚̲̯̍̈́̈͊̾͗̊̀̓͌͌̒̎́̒̎́̅̓̅̅̈́͆̃̄̊̊́͂͒̈́̒̉̓̓̾͗̑̔̐̈́̇͗͐̈́́̅̈̄̓̓̎́̓̂̋͆̈́̂̑̑̽̈́͆͛̒̅̑̊̋̔́̎͂̈̔͋̈́̃̀̑̒̍̆̌̎͋̀͒͒͊̈̂͐̈́̽̀͌̆͐͌̈́͆͂̆̐̓͂̈̌̀́͐̑̅̋̈͐̽̂̐̇̏̐͐̄̅̔̚͘̚̚̚͘̚̕͜͜͜͝͝͝͝͠͝͠͠͝ͅͅH̵̡̢̡̧̛̛͖̤͈̣̺͉̳͈̖̜̘͖̪̼̣͇̮̜́̆̐͌̓͗̾̇̈́̏̎̊̋͑̍̌̒̉̐̐̄̓͂̽̐̅̑̀̅͗̅̀̓̓͐̅̌̉͛̀̐̓̈́̔͌̉͌̽̉͆̿̊͊̓̈́͋̓̀̇̓̂̒̓̉̀̆̊͛͆̽̽͐͐͛̇́́̀̐̓̄̾̉̎͋̑̿̐͋́́͐̿̈́̍͋͂͑̀̒͛͋̐́̿͛̓̋̏̓̓̋̎̽̉̔̈́̓̒͋͐̄͗̈̊̀̇̑͋͒̾͊̈̄́̽͘̕̕͘̕̕͘̚̚̕̚͘̚͜͠͝͝͝͠͝ͅǫ̵̡̢̨̧̧̧̨̨̧̨̧̨̡̧̧̧̨̡̧̡̨̨̡̛̛̛̛̫͇͓̗̠͈̬̼̖̗̤͕͈̠̙̼͕̪̮̜̠̻̲̺̯̣͎͙̥̯̖̳̤̞̮̞͕̭̮͓̻͕͖̝͈̟̰̱̪̤̣̰̤͉̠̰͚͇̼̯̫͍̣͚͎̭͙͍̱̳̪͈̞͈̹͚̲̞͔̙̪̞̗͈̩̹͇̠͇̩̲̟̳̖̻͍̤̜̙̜̥̪͕̤͔̮̤̗̜̪̺̺̙͕̜̞̘̳̪̹̰̺̠̩̻̤̤͍̦͚͖̩̟̖̻͕͇͕͇̲̘͎͈̪̬̜̻̜͓͓͚̮̠͚̠̼̳͎̖̜̣̘̙̹͓̮̗͕̟̭̘͉̥̩̳̱͚̣̣̱̗̩̭̦̗̦̞̦̱͙͍̰̟̱̩̠͖̮̟̱͖̰͈̖̺̣̮̗͇̦̣̬͓̳͙̰͉̖̹͖̜̫̭̥̗̦͍̘̫̯̯̗̼̩̮̟͔͖͍̞̽̅̓́̈̀̂͛̈̑̂͋̒̆̌͂̀̎̋̋͌̌́̀̌͊͊̏͋̃́̋́̈̎̎̒̌́̒͋̾̈́͊̃̃́̍͛̄̾̐̆̅͐͗͒́͋͛̌̅́͌̀́͒̇̔͂̌͗̐͛̽̀̀͗̾̂͂̃̈̐͋̒͐̐͗͗̍̿̏̀̈̾́͌̔͌̃̅̄̀̈̂̍͒̈͊̂̾́̈̋̈́͌̐͊̈̓́̒̓́̍͊̾̾̂͂̍́͌͛̆͐̓̈́́̽́̂̂͗͛͌͆̀̍̑̊̿̋̏͛͗̍̀̆͆̀̐̈́̀̒̎̐́̽͊̃̏͊͊̋͒͆̈̅̀͒̕̚̕̕͘̚̕͘͘̕̕̕͜͜͜͜͜͜͜͜͝͠͝͝͠͝͝͝͝͝͝͝͝͠͠͝͠͠ͅͅͅͅͅp̵̧̢̧̢̨̛̛̛̝̻̗̳̝̜͈̖͎̠̩̳̝̺͕̫̯͖̱͙̦̦͚͕̘̖̺̠̠̩͙̜̪͇̼̺̖̆̎̾̽̑̉̽͐͒͌͌͐̀́̿͗͊̒̇̿̇͛͂̀̊͆̈́̂́̒͑͛͂̇̃̑̉̈́͊̈́̌͌̽́́̃͊̂̓̓̐̽̊͌̈̈́͌͑͛̍͂̏͑̎̉̀̍̾͒͂̉̉͊̇͌̓̈́̀̅̇́̿͌̈́̉̂͌͌̐͑̐̐́̔̽̋̀̔͗̽͑̏̊̔̈̀͗̈̓̒̍̏͑̒͑̉̆̊̈́̈́̈́̈́̈́̓̈́̎̾̈́̂̆̊̆̏̀̄͐͒̉̈̈́̚̚̕͘͘̚̚̕͘͠͠͝͠͝͝͠ͅͅę̷̧̡̢̨̢̨̧̢̢̡̛̛̛̛̛͚̩̙̠͇͕̲͇̗͕̤͓̘͚̬̣͖̞͖̬̪͕̼̪͈̺̙̼̳̩̰̪̥̭̼̠̩͓̗͉͖̦͎̮̱̰̺̙̯̯̺̣̲͙͉̘͍͇͕̻͉͇͕̪̥̳̦̼̜̥̟̖͚͖̼͎̦̺̖̲̯͍͓̯̣̪͓̝͉̦̗̬̦̩̜͎͉̗̗͍̜͓͚̲̤̩̖̳͖͔̜̝̰͕̹̻̤̖̮͎͎̱͉̮̗͕̙̞̘͎̰͎̣̗̼̬̻͓̺̬̟̬͓̥͉̱̖̤̣͕̰̱́̾̎̉͆̆̀͛̈́̉͐̅̆̋̾̌̋́̅̊͂̀͒̓̿̆͊͐̈́̐́̎̃̔͆̈́̒̒̋̓̓̐̽̔̌̈͒͒̐̀͊̇͂͂̈̓͊̽̎̅̐̈̔̒̌̅͑̒͗̔́͛̃̈́̊͛̈́̾̅̓͑͗͐̀̌̇̈̾͌̌̄̃̈́̐͗̅̈́̈́̾̈́̓̊̃̿̆̀͐̒͆̃̂̀͗̈̈̍̿͒̉̉̒̅̇̅̄͌͂̀͋̑͂̍̊̔̌͌̈́̓̄̋̔̃̍̿͑̉̿̾̍̄͛̈̀̇̐́̅̈́͆̎̈́̂̽̂̑̏̃̏͂͌́͌́̿̀̒̂́̅́̓͂̂̈́͋̏̇́̈́̄̽̉͛̂̽̀̈̍̀̀̐̉͌̇̑̓̆̇̍̄̐̊́̅̊̈́̿̀̍̑́̇̾͒͌͂̎͆͐͗̆̇̇̄̅̀͘͘̚̚̚͘̕̚̕̕̚̚̕̚͘̚̕̚͘̚͜͜͜͜͝͝͠͠͝͠͠͝͝͝͝͠͝͝͠͠ͅͅͅͅͅf̸̢̡̡̨̢̢̢̡̧̢̢̡̢̢̨̡̢̢̢̨̢̧̧̨̛̛̛̛̛̤̭͖͇̯͍̣̜̖̟̭̭͍̰͙̯̥̱͕̤͕͇̯̩̫͈̯͚̗͇̘̦̠̦̻̟̗̳̩̥̜̱͓̬̺̦̭̥͕̖̪̻͖̳̭̮̠̘̜͈͙̤͉͚̬̞̲̳͖̦̯̞͚̜̘̯̭̥̹̯͕̱̞͙̝̳̗̰͓͙̲͇̹͍͚̣̺̮̖̤͇͉̫͉͙͇̺̦̳͉̟̫̘̹̦̮͈̟͕̫͚̤̫̱̙͍̫̲͎̪̙͔̣̮̺͉̳̫̪͇̹̜̹̺͍̟̜̼̩͇̮͍͙͙̫͕̳̣͖̬̟͓̙̗̟̪͖͕̜̰̳̼̱͈̳̩͓͙͍̖̼͔͔̬̼͓͖̯͉͖͎̻̘͙̤̯͇̠̗͈̦̈́́̐͂̀̐̆̌̇̂̊̑̅̈͐̆͗̒̑͋̅͊͂͛̀́͐̌̍͐͆̋́̏̍̓̒̎̎̍̉͂͐̐͗̀͒͆̈́͆͋̈̍̐̆̿̔̉́̀̾̃͂͗͑̋̈́̽͆͋̽̔̔͛̈̊̿̔͗̂͛͗̉̈́̉̀͊̓̒̆̔́̓̐̎̀̂͌̎̈́̀̓̀͒̈́͑͒̿̏̑͒̉̍͗̓̌̋̋͗̈̿̇̐̈́̇̍̂̓̊́̊̈́̈́̒͋̈́͆͋̽̔̓̅͂̇̽͑̃̅̀̓͗̌̐͛̓̊̀̉͛̽̅͒̌̀́̽̋̄̈̏̽̕̕̕̚̚̚̕͘̕̕͘̕͘̕͘͜͜͜͜͜͜͜͠͠͝͝͝͠͝͠͝͠͝͝͝͝͠͝͝͝͝͝ͅͅͅͅͅͅͅͅͅͅų̷̡̨̡̡̡̫̣̜̬̮͇͖̙͎͖̣͙̻̹̼̭̣̜͉̥̩͚̩̲̼̼̩̣̳͓̣͎̩̼͔̬̤̣̩̘̤̱̟̭̘̙̪̫̞͕̘̤̩̥̹̣̱̾̌͂͊̋̃̒͗́͊̈͑̒͋͘͜͠ͅͅl̸̢̢̨̡̢̡̧̡̛̛̛̛̛̛̛̛̥̯̳̬̥̺͙̰͎̭̞̘̫̼͉̫̜͖͕͔͚͇̯̮̪͖͓̥̺̦̟̪̠̣̻̣̗͖̻̲͚̮͕͈̹̺̣̮̣̘̠̜̻̘̬̹̘̠̼̳̬͕͍͇͉̲̞̪̦̰͚̘̙̺̫̻͎̦̟̹̣̠͍̭̗̖̤̫̣̣̞̱̦͇̫͚͚͇͖̯̬̤͕̪͇͈̳̠̣̻͍͖̼̹̱͕̹̟̀͂̎̈́̑͋͋̇͊͛͑̎̈̐͌͆̐̊̀̅̂̾̄͛̐̽̔́̏̀̈́̿͆̇͊̓̎̈̎̎͐̈̾̌̄̐̃̋̈̇̅͗̑̊̈́̽̌̃̈́̽̋̊̆̅̽̍̔̇̉̒̊͂́̇̃̒͆͊̌̓͌̅͊̄͆̅̂̈́͆̄̈̀̊͗̎̉͌̿͛́̂̌̊̎̎͒͊͛͗̍̀̋́̇̎͛̈́͂͐̂̆͒̈̆̑͐̾͗̆̊͐͊́̓̔͐̅̋̐̈͆͐̓̆̑̑̌̄͋̿̀͋͋̽̄͒̾͌̅͛͊̒͌͂̎̃͌̇̃̿͆̉̇͂̀͆͗̎̊͌́̀͗̽̚͘̚͘̕͘̚̕̚̚̕̚̚̕̕̕̕̚͜͜͜͠͝͝͝͝͠͝͝͠͠͝͝͠͠͝ͅͅl̶̡̧̧̧̧̡̡̨̨̨̢̢̢̡̧̨̢̧̨̡̨̡̢̛̜̳̩̪͈̰̣̤͓̙͔̗̣̗̹͉̞͉̠͖̪̭̗̲̰͇̠̱̯̟͖̯̝̠̳͍̬̳̬͔̠̟͍̬͓̜̪̭͚̟̝̺̫̩͈̩̼͕̘̜͔̹͇͙͍̪̪͔͇̩̠̟̲̝͕̖̥̣̣͕̮̣̤̙̥̼̫͓͍̥̘̩͍̯̺͍̪̠̮̟͔̠̟̮̣̞̻̥̠̯̣̯̮̬̘̦̖̝̩̥̝̪̫̱͍̥̺͙̺̹̱̤͇͕̜̻̮̞̫͖̠̳͚̪̘̖̟̭͔͙͈̜̟̰͖̪͚̖̤͕͓̘̮͚̼̰̜̺̪͖̥̠̮̯͉̙͕̹̙̲͈̫̮͓͍̣̥̥͉̹͎̥̣̫͉̞͍̲͔̣̰̳̠͈̤̣͔̠̥̥̓̆̊͋̔̆͋̊̾̃͒̉̀͛̾̍̃̋̈́̎̚͜͜͜͜͜͜͜͝ͅy̴̨̢̡̧̧̢̨̡̛̭̲͎̜̯̪̳͔͔̳̳̠͚̼͙̰̥͙̟̳͈͚͚͚̟̜̥̣̠͇̳̬͍͔͚͕͙͇͍͈͎̖̟̭̝͈͈͔͍̞͈͈͉̮̙̥͖̖̣̤͈̘̲͈͆͒͊̄̓̓͆́͛̇̍́͂́̒̿̈́͐̄̀̽͗̅̑̀͆̊̀͋̀͐̆̒͌͑̀̃͗͑̀̔̌͆̓͛̾̌̂̃̓̃̓͂̀͋̆͊̊͌̊̈́͋͐͆̾͐͛̏̏͂̀̀͐͋̇̎͗̑͛̅́́̈́̊͆̑̽̀͗̂͂̇́̎̈́̎̎́̌͐̋͋̑̎̀̐̐̐̀̉̈́̍̅̌̀̑̊̈́̍̏̾̀̊̐͊̄̅̌̅̈́̑̔̒̌̈́̄͆͒̇̒̍̓͊̀̎́̐̎̎̓̉̋̉̍̾̏͗̾̿̓̎̾̏͊̆̓̋̽̊̉̐̈̔́̈́̿͌͐̓̄̽́̓͒̀̃̀̄̇͒́̅̀̊̓̌̅͌͒̓̀̀͗̂̓̆̇͒̂̇͗̿̉́̃̉̈́͌͊̔́̽̍́̓̇̽̓̅̏̒̍̚̕͘̕̚̚̚̚͘͘͘͘͜͝͝͠͠͠͝͠͠͝͠͠͝͠͝͝͝͝͝͠͝͠͝͝ͅͅͅ)̴̨̧̡̢̢̢̢̡̡̨̢̧̢̨̨̡̡̧̰̠̣̤͕͕̳͓̲͉͎̮̳̼̟͇̲̳̺̳͚̟̙̫͈̱̮̲͈̬͓̝͙͖̝͚͕̟͎͎̪̱̹̗̼̹͙̫̰̬̮̥̦̻̪͍̮̝͓̪̤̜̹̹̝̻͓̠̗̪͚̜̭̝͉̜̣͈̹͉̪͎̜͙̗̫̺̘͙̘̼̜͕̰̠̟̮͓̳͚̬̝̼͖͕̘͚̱̜͓͉͉̮̟͕̰̮̩̬̩͓̪͓̪͓͎̻̲̙͉͚̺̻̩̮̟̬̗̖̩̝̮͖͖̺̩̝̙͓̜̪̺̩͚͓͕̙̭̯͇̪̣̭̦̼̥̥̱͔̹̤̝̗͉̙͖͕͈̪̟̗̟̞̣͖̤̪̮̹͈̰̱̬͔̗͓̫͎̦͍̬̭̲̩͉͍̺̱͇̻̟̥̞̼̫̜̯̮̗̣͙͈͛̒͋̿̾̃̾͐̓̓̌̇́̋̀͒̂͌̓͋́̂̓͜͝͝͝͝ͅͅͅͅͅ ̶̧̧̨̧̧̨̨̛̛̗̘̝̼̙͍̖̗̼̪̠͙̜̺̰̼͖̬͉̥̺͔̖͖̯̜̬͕̖̭̭̭̯̖̝̜̱͉͕̩͚̥̪̥̮̼̦̫͓̣̱̬̖̼͓͚̳͇̗̞͚̞͖̗̳͎͉̠͚̥̝͔͈̬̖͔͍̠̗̟̥̳͕͍̺͙̖̯̯̗̙̼̘͇͖͚͍̩̱͈̙̫̻̝͉̤̻̼̪̯̈́̈́̌̀͂̈́͌̋͛͋̏̿̀́̈̿̄̀͛͆̑́́͑̑͑͛͌͊̕͘͜͜͜͜͜͝ͅͅͅͅͅ(̷̢̨̢̨̢̧̡̡̡̨̟̗̖̯͕̞̞̭̰̮̫̘͓̼͇̻̝͚̬̤̻̱̫͇̳̪̼̫̼͈̮̹̮̱̗̖͇̤̱̠͙̼͚̻̞̣̳͎̩͍̭̖̩̫̖̭̬̰͚̖͓̝̟̦̫͎̩̖̩̬̖̝̬̦͚̹̞̪̪͇̭̯̘̝̹̞͉̖̘̱̣̤̖͊͌͐̔̏͛̓͆͆͐̄̑̾̌̇̆̉̌̊͆̂̅͛̀̄̇̽̋͊͒͆̐̀̾̓̌̾̑͊̌̒͗̾̈͛̍͂̈̓͘͘͘͘͘̕̕͜͠͝͝͝ͅM̴̡̨̧̨̧̡̡̨̧̧̧̛̛̛̛̛̛̛̫͇̘̬̥͎̘͓͓̮̦̗̹̭̼̭̟̩̝̣͓͚̘̥͔̲͙͈̖̤͔̯͉͕̬̰͈͍̰̭͍̗͇̦̟̙͉̦͕͍̤̯̼̹͖̜͕͉͖͔̩̝̠̘̪̠͕̯̪̲̘̭͓̬̮̰̙̥̰̝͈͍̩̜͍̥̘̮̯̞̠̲̲̯̬̝̥͎͇̼̝͇̜̰̳̯̝͖̫̪͔̝͖̯̩͕͕̮̬̠͇̻̗͉͔̖̟̙̬̞̪͇͇̠͇͚̫̯̖̝̝̱͖͉̣̙͎̥̯̗̺̜̖̜̭͚͇͈͉̖͋̎͒̈́̍̄̊̈́̒̿͊̀̔͑̈͂̉̍͛̏͗̈́̐̃̐͂̀͊̊̑̈́͌͋͆̆̆̒͋̋̊͆͌͂̇̅̽̐̀̿͋͋̌͒̓͒̈́̾͂̂͗̔́̓̋̈́͑̏̎͛̊̈́̓͋͑͛͒̌́̀̀̽̈̌̍̀̆̋̌̇͆̀́́̊̿́́̎̀̇͛̌̊̆́̌͋̅͒͂͋͑̇͌͛̈́͌͗̀͂͑͂̄͐̿͌̈́̒̐̃̄̃͂͂͛̀͌̉̍͊͊͐̊̚͘̕̕̚̚̕̕͘̚̚̚͘͜͜͜͜͜͠͠͠͝͠͝͝͠͝͝͠͝͠͠ͅͅǎ̵̡̢̧̡̧̧̧̨̢̡̨̧̨̢̡̡̨̨̢̢̧̢̛̛̛̛̛̛̪̭͙̩̥͔̪̞̣̘̩͈͎̲̹͇̟̰̖͇̙̩̹̣͎̜͕̣̙͇̲̙͇̯̖̺̘͇̹̝̪̱̭͚̜̻̻̳̹͇̺̰̬̠̞͓̟̥̣͇̗̮͈̜͈̰̲͉̰̩̩̯̯̻̻̣͈͙̜̙͙̜̝̻̼̪̳͇̲̥̞͎͉͈̙̣͕̗̩̼͎̦̹͚̣̥̲͙̣̦̤̳̮̹͔̤̝̩̜̰̤̺͓̮͔͉̞͇̣̞̪̞̫̘̻̫͚̳̤̙̜̩̦͔̘̪̠̺̪̼̤̫͎͚̳̪̥̗̰͇̻̺͕̦͖͈̤̗̭̜͔̘̝͚͔̥̹̫̻̩͈̫͔͍̲̬̲̻̦̼̮̜͕̬͖̹͎͖̭̝͍͕͓̤͈̠̹̪̣̰̟̬̖͍͖͍̥̘̰̦͚̤̙͔͕̱͚̩̫̙̳̗̣̺͚̹̜͖͉̬͙͔̎̌̊͆̃̀͗͊̂̉͂̈̍̄̏͛̾͂̊̍͑̌͌̈́̈́͂̇̀̾̋̑͑̏̈́̅̐͑̑̂̈́̒͊̿̇̈́̅́̓̎̐͌̓̀̓̾͆̉̄̑̇̈̓̋́̿́̏̈́̽͗́͗̾̌̂͊̂̈́͛͂͆̈̒̂̂̔͂̓̈́͗͒̐̾͐͌̋̐͐́̋̎̃̀́̑̅̾̇͑̽́̄̃̉́͌͆́͗͑͐͛̉̓̓̌̈́̓̔̀̍̌̃͗͗͐̂͐͊̇̈́̆͑̓͋̀́̈́̾̂̔̈̑͊͑̍́̈͗̉̋͂̍̀̔̑͆̃̔͑̍̅̄̒͒̂̐̐̈̿̑͛̄̍̒̈́̔͋̈́̚̕͘̚͘͘̚̚̕̚̕͘̚̚̚͜͜͜͜͜͜͜͜͜͜͜͠͝͠͝͝͠͝͝͝͝͠͝͝͠͠͝ͅͅͅͅͅỳ̵̧̡̧̨̡̧̧̢̢̡̧̡̢̡̡̡̨̡̧̢̧̛͉͉͕̘̳̲͚̘͙̬͓͙͎̺̗̺̘̬̠̲̳͔̥͎̟̯̮̦̰̯͔͈̮̤̗͖̩̣̥̻̹̱̟͖̥̱̰̗͓͉̟̤̰̠͓̺̘͈̻͎̜͍̞̗̫̫̼̤̤̤̮̤̮̥̳̫̝̫̞̗̲̹͈̫̼̮̬̯̻̼̖̣̺̳͇̲̠̥̳͔͖͇̟̣̩̭̥͚̟̖̯̠̥͉̭̫̹̖͇̩͉̥͉͇̪̱̠͔̟̗̞͔̙͍̙͙̺̰̖͍̱̹̦̬̳̠͇̙͉͕̗̤͕̦̯̳̘̘̖̙̺̫̝͔̱̘͍͚͎͕͔͕̹̩̼̳̝̮̤͎̪͉̫̺̪̼̠̦͚͈̿͆͐̿̊͒͋̒͗̓̀̓̾̂̏̈̊̆̎̑͊̊̽͐̄̊͌̑̽̇͗̂̋̔́͒̄͆̈́͛̃̂̎͂̈́̋͋̎́̚͘̕̚͜͜͜͜͜͜͜͜͜͜ͅͅͅb̶̡̧̧̨̨̡̡̧̧̢̧̡̢̧̡̧̧̢̢̨̢̧̡̨̛͈̘͙͙̦̘̙̞͙͉͎̱̱̹̭͈̘͚̰̠͕̦̣͇͇̠̘̘̭͓̠̻͈̙͚͔̟͚̟̪̲͇̳̼̮̤̫͉̭̬̬̺̼̼͍͓͕̱͓̝͙̺̞̯̳̣̩̯̺̙͇̣̩̣͉͔͙̗̪̺͔͓͈̮̜̱̭̩̼͉̠̹͓͕̬̳̻̱̥̦̖̯̻͔̟̻̤̞̼͎͇̲̩̻̣̠̤͙̝͎̘͇͚̗̗̞͕̼͔̮͕̥̖̹̮͎̱͎̰͙͖̤͖̝̳͉͎̪̖̬̙̖̯̖̫̝͇̣̱̩̝̲̪̺̭͎͖̫͍̯̱̥̤̪̣̫͖̞̠̖̩̞̝̟͉̠̲̦̭͖͓͈̣̳̮̟͙̯͇̹̮͍̙̩̖͚̬̺͎̬̙̜̺̞͕͙͖̬̬̖͍̝͍͈̗̘̰̪͓̣̳̱̺͇̾͛̾̏͆̇̒̈̂͛̐̀̀͂̈̍̋́̌͑̌̿̂́̆͒͋͒͐̽̈́̐̒̀͐͂̈́̾̍̇́̾̚̚͜͜͜͜͜͝͝ͅͅͅͅͅͅͅͅͅͅͅͅͅě̴̡̧̨̡̨̨̡̢̡̢̛̛̛̛̥̗͈̘̬̙̺̥̞͔̹̱̬̙̹̠͖̙̫͈̖̳̪̙͙̼͎̮̗͙̹̙̯͈̞̲̩̮̞̠̲͔̝͓̥̟̮̪̘̥͕̠̲̯̫͓͍̻͎̠̞̟̤͓͍̥͙̙̯̯̮̳̹͍̼̪̗̀͒̾̋͌̀̀͗͂͌̏̄̓͗̓͐̔̏̓̅̾͂̓̂͌̌̉̂̍̽͌̓̓͛̔̓͂͒̂͋̅̾̀̍̅͑̇̽̋̔̉̑́͗̓̂̔̄̿̾̈́̀̓͑̈́͂̾̓́̈̎̇̿̈́͋̀̀͋̎̈̀̎̈́̏͐͌̄̀̈́̾̌́͗̀͊̒̑̾̐̈́̒̊̐̍̾̏́̇͌͑̔̇̿͋̃͒́̑̆̀́̑̏̎̄̃́̋̄͑͂̈́͆̆̓̏̋̒̀̑̑̀́̈́̿̑̑̓̃̆̇͆͛̽̑̍̅̔̊͊̅̀̅́̈́̎̑̈́̈̕̚͘̕̚͘̕͘̕̚̕̚̕̕͘͜͝͝͝͝͝͝͝͝͝͝͝͝͝͠͝͝ͅͅ)̸̨̡̨̨̢̧̢̡̧̡̧̨̡̡̛̛̛̛̛̛̛̛̺̪̱̬͇̣͇̬̟͇̖̣͎̙͕̯̫͈̫̘̦͖̹̱̼̮̟̯̙͚̮̲̖̬̲̗̩̩͉̯̘̻̙̞̳̝̜̝̙̳̱͙̲͚̞̫̝̜̭͙̘̟̱͈͎̹̪̰͓͈̹̩̜̘̱̦̮̲̰̻̜̭̗̘̣̙̳͖͍̦̣̙̜̯̙͎̥̯̹̣͎̲̙̲͖̻̺̲̪͙̗̻̱̰͕̳̤͖̝̫̦̣͍̮͍̺̻͚̮̙͉͙͚̜̥̭̠̘̫͎̜̯̺͎͖͖͇̪̼͈͙̰̖̜͇̼̣̝̮̮̺̝̬̫̮͎̩̘̭͈͔̞̤͇̥̤͕̄͌̏̾̉̍̔͑͑̔̔͑̀̎́̽̀͑̽̀̍̃̇̅͆̈́̈́́̌̂̐̇̎̍̀̆̏̓̈́̀̓͛̾͋̃͊̿̉̀̄̀̎̓̅̍͆͒̈̿̀̐̏̍̀́̔̇̑̏͗̽͂̑̆̌̎́̉̋̎̈́͗̑̊́̑̈́̒͊̀̀͋͂͒̔̃̋̋̊͗̉̈́͛͗̇̋̐̔͆́́́̈́̈́͂̎̏́͒̾͗͊̑̑̆͒̂̽͛̏́̊̑̄̍̈̈́̍̔̽͛̋́̒̓̀̋͐̓͌̅̿̍͂̎̈́̀̍̆͒̀́͒͂͊̌́̆̓̊̀͆̈́͗͛̓͒̑̓͐̋͌͑́͐͒̊̋̈͆̕͘̚̕̕͘̚̚̕̕̚̕̕͘͜͜͜͜͜͜͝͝͠͝͝͝͠͠͝͝͝͝͠͝͝͝͝͝ͅͅͅͅͅͅ 2023-11-13 10:25:57 -05:00
0f9da6148b (Esimorp I) (Niaga) Dliub Xif Ot Tpmetta 2023-11-13 01:41:52 -05:00
ea48728a68 Fix ARM Build 2023-11-11 19:22:07 -05:00
3e7037f621 Remove iconv 2023-11-11 01:33:19 -05:00
11230c120d Remove LibPNG + Clean Up 2023-11-11 00:44:26 -05:00
1f05424651 Include Compiler Check In SDK 2023-11-09 18:41:10 -05:00
98db527a13 Older CMake Compatibility 2023-10-21 19:27:22 -04:00
85e04fbcc6 2.5.1 2023-10-21 16:36:54 -04:00
018e506c80 Include More Dependencies 2023-10-19 21:50:39 -04:00
945ce81fe1 Skip CI On Flatpak Tag 2023-10-19 21:14:52 -04:00
fab66319ea Merge pull request 'Update ARM GNU toolchain to version 12.3-rel1' (#64) from taylorthemushroom/minecraft-pi-reborn:master into master
Reviewed-on: minecraft-pi-reborn/minecraft-pi-reborn#64
2023-10-19 21:13:00 -04:00
99424546f8 Remove old toolchain URLs 2023-10-19 21:13:00 -04:00
cef22a5325 Oops
Forgot to update a few lines of code in the previous commit. Sorry!
2023-10-19 21:13:00 -04:00
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
588eb5feb0 Update ARM GNU toolchain URLs and hope nothing breaks :) 2023-10-19 21:13:00 -04:00
c711c8b019 2.5.0 2023-10-19 21:03:01 -04:00
864c096785 Use Official Skin Server 2023-10-19 20:53:38 -04:00
9ef0868889 Update Dependencies 2023-10-19 02:11:41 -04:00
5b792fbf3a Add Feature Flag For Custom Skins 2023-10-19 01:56:09 -04:00
c908d46d54 Fix "Sleeping Beauty" Bug 2023-10-19 01:46:09 -04:00
db03d964de WIP Custom Skin Support 2023-10-19 01:23:34 -04:00
c0cd9b8b1f Nicer Release Formatting 2023-09-21 12:57:59 -04:00
a8835153b0 CI Fix Attempt #2 2023-09-21 00:25:47 -04:00
e1f2867d78 Attempt To Fix CI 2023-09-20 22:34:19 -04:00
7a5fef7024 Try Gitea Releases 2023-09-20 20:54:07 -04:00
da9edee160 2.4.9 2023-09-17 15:53:34 -04:00
9e517f5e60 The Return Of ES2 Support 2023-09-07 21:38:14 -04:00
85e3cb6228 Fix CMake (Again) (Again) 2023-08-05 17:26:36 -04:00
1dd0526197 Fix CMake (Again) 2023-08-05 01:42:47 -04:00
7ecc6cb00b Fix CMake 2023-08-04 23:32:25 -04:00
4189f3fd1d Use Newer GLES Compatibility Layer 2023-08-04 22:52:30 -04:00
de18189b44 Fix Graphical Glitches On Some NVIDIA GPUs And Fix Crash When Taking Large Screenshots 2023-08-02 01:08:31 -04:00
a622858a18 Better Fog Shader 2023-06-12 19:14:37 -04:00
b005106b44 [Gitea Actions] Clone Submodules 2023-06-04 00:58:26 -04:00
61add936cc Fix Workflow Name 2023-06-04 00:03:15 -04:00
d3b78acbef Gitea Actions Attempt #2 2023-06-03 23:53:26 -04:00
07a27d4dd9 Try Gitea Actions 2023-06-03 23:48:28 -04:00
6779905830 Reference New AUR Package 2023-05-28 02:58:28 -04:00
c3fda82642 2.4.8 2023-05-28 00:50:08 -04:00
e0ab968fa3 2.4.7 2023-05-18 18:38:35 -04:00
45b93534fa Revert "Add Night Vision"
This reverts commit 5273d6cdf9007058c2545a86ea7da405e54e15c7.
2023-02-25 19:36:35 -05:00
5273d6cdf9 Add Night Vision 2023-02-25 04:05:20 -05:00
06af8c821f Add Cave Generation 2023-02-25 00:26:45 -05:00
7b4729b8ec Add Biome Colors To Grass 2023-02-24 19:53:41 -05:00
ffad36224e Improve Server Performance 2023-02-24 17:41:49 -05:00
236f7e385d Update Dependencies 2022-10-31 19:27:02 -04:00
f506b10051 Add Minecraft::handleBack Safety Check 2022-10-20 23:58:40 -04:00
9b4a9994ba 2.4.6 2022-10-08 16:33:12 -04:00
32cd0c426f Workaround GLFW Joystick Bugs 2022-10-08 16:27:04 -04:00
5690df3ebe Formatting Tweaks 2022-10-08 16:27:04 -04:00
b4bebfb701 More Fixes 2022-10-08 16:27:04 -04:00
1fa444f810 Fix Controls Documentation 2022-10-08 16:27:04 -04:00
f3dc145d4a Allow Opening Crafting With Controller 2022-10-08 16:27:03 -04:00
5d65b4092f Move Code Around 2022-10-08 16:27:03 -04:00
81aa01daf9 Fix Silly Typo 2022-10-08 16:27:03 -04:00
2edfa62c25 Fix Holding Left-Click When Attacking 2022-10-08 16:26:57 -04:00
4870afcc7f Document Controls 2022-10-02 01:23:46 -04:00
c178e5e5eb Logging Improvements 2022-10-02 00:47:11 -04:00
57b0bce12c Fix For ARMHF 2022-10-01 19:29:11 -04:00
95345a5f1b Minimal Controller Support + Input Fixes 2022-10-01 01:37:20 -04:00
717b4a11a7 2.4.5 2022-09-26 22:19:27 -04:00
40a527bb23 Bundle QEMU 2022-09-26 20:59:46 -04:00
2766611878 Small Fixes 2022-09-25 20:56:45 -04:00
8532e7707f 2.4.4 2022-09-25 19:53:19 -04:00
703ced337b Use File Locking 2022-09-25 19:35:51 -04:00
bedd5ea53a Replace PatcheLF With LIEF 2022-09-25 15:47:36 -04:00
eb3c5d2e6f Remove Unused File 2022-09-23 17:56:44 -04:00
ab1dbd2996 Update Docs 2022-09-23 17:55:38 -04:00
29bc6faf3d Add Disable Creative Mode Mining Delay 2022-09-23 17:08:26 -04:00
5aae95fd37 Add --wipe-cache 2022-09-23 00:31:42 -04:00
5739c5f999 Add Disable Speed Bridging 2022-09-22 23:59:44 -04:00
34ef2d51aa Small Fixes To The Launcher 2022-09-22 18:08:12 -04:00
f328800ce8 Cache Launcher Configuration 2022-09-22 17:43:21 -04:00
02c73176a5 Fix Particles In Front-Facing View 2022-09-21 23:06:58 -04:00
16ce586e9c Add Quit Button 2022-09-21 20:15:00 -04:00
6378a18494 Add 3D Anaglyph To In-Game Options 2022-09-21 18:40:09 -04:00
6994671c6d Add MCPI_API_PORT 2022-09-21 17:54:40 -04:00
58f329bb4f Bug Fixes 2022-09-21 17:34:19 -04:00
d03a1a96ff Tweaks & Fixes 2022-09-20 18:25:27 -04:00
35cafec1ee Tweaks 2022-08-10 17:21:38 -04:00
4ab6b7aed1 New GCC Is *Still* Broken 2022-08-09 18:48:30 -04:00
edd346dd66 Stop Fighting CMake 2022-08-09 18:39:34 -04:00
0d9f498aa7 Fix ZLib In "git status" 2022-08-07 14:14:00 -04:00
d761ad8614 Better CMake 2022-08-05 22:07:19 -04:00
4977898bcd Use New Repos 2022-08-05 20:37:11 -04:00
513628d91f More CMake Tweaks 2022-08-05 20:08:13 -04:00
9a521ebca2 Remove Warnings From SDK 2022-08-03 13:08:20 -04:00
deae36ed94 Better SDK Setup 2022-08-01 19:56:35 -04:00
00d6ee4f9a 2.4.3 2022-08-01 18:41:08 -04:00
8dd562a20f Fix Signs With CP-437 2022-07-30 23:52:50 -04:00
c11c7203ef 2.4.2 2022-07-29 22:13:03 -04:00
379da809cd 2.4.1 2022-07-20 02:58:14 -04:00
96baf9627a Actually Fix Screen Rendering When GUI is Hidden 2022-07-16 00:02:51 -04:00
279b101e46 Hotfix #2 2022-07-15 23:20:31 -04:00
b190851d36 Hotfix 2022-07-15 22:08:12 -04:00
c3c7d22006 Actually Fix CI 2022-07-15 20:09:51 -04:00
3abbb0cb16 Improve Server Dockerfile 2022-07-15 19:54:58 -04:00
dda511f8ff Fix CI (Again) 2022-07-15 19:43:26 -04:00
0ccc1ba6e8 Fix CI 2022-07-15 19:05:59 -04:00
9d3a0964b0 Fix CI Stage Name 2022-07-15 17:54:43 -04:00
ed9bef8492 2.4.0 2022-07-15 17:27:21 -04:00
c4e26c5be2 Fix Classic HUD 2022-07-15 01:37:12 -04:00
0c82db4116 Diable Broken Touchscreen-Specific Block Outline Behavior 2022-07-15 01:28:51 -04:00
ce168c1c16 Add Translucent Toolbar 2022-07-14 19:52:51 -04:00
93eb7807aa Fix Attacking 2022-07-14 18:23:40 -04:00
12074e15d9 Fix Sound 2022-07-14 18:11:44 -04:00
010aaa89e3 Embed Feature Flag Data 2022-07-13 23:35:05 -04:00
0e32fd36c8 Store Temporary Logs In Own Directory 2022-07-13 23:05:59 -04:00
6c89e64f8b Add Classic HUD 2022-07-13 22:11:46 -04:00
9fe6a2fb39 Remove Superfluous Mutexes 2022-07-13 19:32:08 -04:00
c87a6fa3c0 Improve Proxy Client 2022-07-13 17:02:18 -04:00
69d3832815 Move Screenshot Code To ARM 2022-07-13 16:46:33 -04:00
67002006f3 Vendor PatchELF 2022-07-13 11:58:35 -04:00
eb96d80e5a CMake Restructure 2022-07-11 23:51:27 -04:00
968001897d Build Fixes + Don't Force EGL 2022-07-11 20:47:57 -04:00
68519f06fd Add Buckets 2022-07-10 10:37:19 -04:00
b3b935dd1d Logging Changes 2022-07-08 22:40:56 -04:00
006243d02f OpenAL Fixes 2022-07-08 15:00:01 -04:00
3c1bce876c Run Benchmark During CI Test 2022-07-08 13:57:48 -04:00
484d3e7f90 More Miscellaneous Fixes + Fixed GLES v1.1 Support 2022-07-08 00:25:01 -04:00
23df63abb7 CMake Cleanup 2022-07-07 18:55:43 -04:00
126c3d618d No More APT 2022-07-07 18:54:11 -04:00
3937f88084 More Fixes 2022-07-07 00:37:53 -04:00
4bd2fecfa2 Better package.sh 2022-07-04 16:51:56 -04:00
b539491713 Treat AppImages As Self-Mounting Tarballs 2022-07-04 16:44:00 -04:00
ea4c5c77a1 Cmake Refactor 2022-07-02 18:14:23 -04:00
e506dbb1bb GL Fixes 2022-06-30 19:53:32 -04:00
699d83c61b Recipes API 2022-06-27 14:47:55 -04:00
329f92c0a4 Fix Weird Shading 2022-06-26 22:01:31 -04:00
bfa0567ac9 Better Examples 2022-06-26 21:17:52 -04:00
a94708a1ae More Reliable Jenkins 2022-06-25 23:40:24 -04:00
905a569c09 Better Flathub Badge 2022-06-25 23:38:29 -04:00
53f602403a Cache Blacklist/Whitelist 2022-06-25 23:32:31 -04:00
2f64552926 Fix SDK Bugs 2022-06-25 23:03:46 -04:00
2b920f50ba Improve Example Mod README 2022-06-25 17:49:09 -04:00
d859a16b5a Initial SDK Support 2022-06-25 17:30:08 -04:00
78e17d8c18 Block Running As Root 2022-06-24 20:37:52 -04:00
0e7a108a0a Improve Build 2022-06-13 22:53:43 -04:00
ca21877000 Ditch FreeImage 2022-06-13 20:49:09 -04:00
f1ec29ec86 Build Tweak 2022-06-12 16:23:32 -04:00
13ac816baa Fix Invalid AppStream XML 2022-06-10 23:49:15 -04:00
6ba86b9193 Tiny Docker Fix 2022-06-10 22:02:43 -04:00
49f8da2a80 Fix Build 2022-06-10 21:59:57 -04:00
e8faee62fa Improve AppStream 2022-06-09 23:23:37 -04:00
a8ff58f0c4 Update Dependency Installation 2022-06-09 23:10:29 -04:00
daccf65361 Improve Metadata 2022-06-09 21:31:40 -04:00
3d508d7609 2.3.13 2022-06-05 16:14:03 -04:00
0061edb3b2 2.3.12 2022-06-04 14:36:47 -04:00
baeeceeaac Slightly Faster 2022-06-04 14:34:15 -04:00
211bf265ff Optimizations & Fixes 2022-06-03 22:25:22 -04:00
0dd0706f52 2.3.11 2022-05-29 22:54:57 -04:00
1743626113 Sweeping Media Layer Changes (GL ES 2.0 Support) 2022-05-29 18:44:27 -04:00
4ed11b67e7 Add Front-Facing View 2022-05-17 18:31:25 -04:00
365e238c29 Small Fix 2022-05-16 18:56:19 -04:00
36c4ed7e4d Fix Stupid Mistake 2022-05-15 15:16:45 -04:00
cf1faf4835 Better Exit Code Messages 2022-05-15 13:51:28 -04:00
cb4560a602 Don't Require MCPI_DEBUG For Command Errors 2022-05-15 00:53:46 -04:00
b3a96dc3e2 2.3.10 2022-05-14 00:16:25 -04:00
be300a2809 Fix Zenity On Wayland 2022-05-13 23:27:06 -04:00
77d7b82a14 Add Crash Report Dialog 2022-05-13 22:36:12 -04:00
b59c580f6a Fix Build On Ubuntu 22.04 & Bug Fixes 2022-05-11 18:24:03 -04:00
524a390921 Use Debian Sid As AppImage And ARMHF Sysroot Base 2022-05-04 20:47:15 -04:00
ead7e575f3 Allow Specifying Custom Sysroot 2022-05-03 21:08:56 -04:00
f2a9b274d2 Cleanup Sysroot Sources 2022-05-03 17:29:10 -04:00
dd4972172d Fix In-Source Build 2022-05-03 17:27:52 -04:00
8822a22987 Re-Run CMake On Version Change 2022-05-02 22:52:52 -04:00
53cb68beee 2.3.9 2022-05-02 22:46:53 -04:00
47ae13ac51 Bundle An ARM Sysroot 2022-05-02 22:44:10 -04:00
492725ed63 Colored Logs 2022-05-02 20:43:52 -04:00
7c2d0d5625 2.3.8: Switch Up Mod Loading Order 2022-05-01 00:25:29 -04:00
9449cdf747 Fix Bad Comment 2022-04-30 23:29:29 -04:00
d95a9e1871 Update Changelog Formatting 2022-04-30 22:34:52 -04:00
8a83702c3c 2.3.7 2022-04-28 20:54:00 -04:00
be7e44fd3c Update GLFW 2022-04-28 17:00:11 -04:00
651c49980e 2.3.6 2022-04-27 23:43:13 -04:00
46a53ba3cf New Create World Dialog 2022-04-27 23:38:30 -04:00
186728ca5f Small Tweaks 2022-04-24 22:30:35 -04:00
9412c07c45 Fix ARM Check 2022-04-24 18:56:21 -04:00
2717e062b3 Replace LINK_FLAGS With LINK_OPTIONS 2022-04-24 17:56:21 -04:00
0723fb1894 Improve Docs 2022-04-23 23:01:52 -04:00
16f919d147 2.3.5 2022-04-23 21:19:53 -04:00
e18fc9fc63 Simplify 2022-04-23 21:10:44 -04:00
3ebdffd396 Fixes 2022-04-23 18:49:08 -04:00
82b6252927 Classic UI By Default! 2022-04-23 16:46:40 -04:00
4a35935daf Add Improved Title Background 2022-04-22 19:38:15 -04:00
611 changed files with 20888 additions and 9826 deletions

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

@ -0,0 +1,136 @@
name: 'CI'
on:
push:
branches:
- master
tags:
- '*'
- '!flatpak'
# Jobs
jobs:
# Build Project
build:
strategy:
fail-fast: false
matrix:
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.mjs build ${{ matrix.arch }}
# Build
- name: Build
run: ./scripts/build.mjs appimage ${{ matrix.arch }}
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.arch }}
path: ./out/*.AppImage*
if-no-files-found: error
# Test Project
test:
needs: build
strategy:
fail-fast: false
matrix:
mode:
- Client
- Server
arch:
- AMD64
- ARM64
- ARMHF
name: Test
runs-on: ${{ startsWith(matrix.arch, 'ARM') && 'raspberry-pi' || 'ubuntu-latest' }}
container: node:lts-bullseye
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: false
# Dependencies
- name: Install Dependencies
run: ./scripts/install-dependencies.mjs test ${{ matrix.arch }}
# Download Artifact
- name: Download Artifact
uses: actions/download-artifact@v3
with:
name: ${{ matrix.arch }}
path: out
# Test
- name: Test
run: ./scripts/test.sh ${{ matrix.mode }} ${{ matrix.arch }}
# Example Mods
example-mods:
needs: build
name: Build Example Mods
runs-on: ubuntu-latest
container: node:lts-bullseye
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: false
# Dependencies
- name: Install Dependencies
run: ./scripts/install-dependencies.mjs sdk amd64
# SDK
- name: Download SDK
uses: actions/download-artifact@v3
with:
name: AMD64
path: out
- name: Extract SDK
run: |
./scripts/fix-appimage-for-docker.sh ./out/*.AppImage
chmod +x ./out/*.AppImage
./out/*.AppImage --appimage-extract-and-run --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
- test
- example-mods
name: Release
runs-on: ubuntu-latest
container: node:lts-bullseye
steps:
# Dependencies
- name: Install Go
uses: actions/setup-go@v5
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)'

27
.gitignore vendored
View File

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

35
.gitmodules vendored
View File

@ -1,12 +1,29 @@
[submodule "dependencies/libpng/src"]
path = dependencies/libpng/src
url = https://github.com/glennrp/libpng.git
[submodule "dependencies/zlib/src"]
path = dependencies/zlib/src
url = https://github.com/madler/zlib.git
[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/TheBrokenRail/zenity.git
[submodule "dependencies/LIEF/src"]
path = dependencies/LIEF/src
url = https://github.com/lief-project/LIEF.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
shallow = true
[submodule "dependencies/symbol-processor/src"]
path = dependencies/symbol-processor/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/symbol-processor.git
[submodule "dependencies/runtime/src"]
path = dependencies/runtime/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/runtime.git
[submodule "dependencies/imgui/src"]
path = dependencies/imgui/src
url = https://github.com/ocornut/imgui.git
ignore = dirty
[submodule "dependencies/imgui/glad/src"]
path = dependencies/imgui/glad/src
url = https://github.com/Dav1dde/glad.git

View File

@ -1,108 +1,99 @@
cmake_minimum_required(VERSION 3.13.0)
cmake_minimum_required(VERSION 3.25.0)
# Specify Options
option(MCPI_USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" FALSE)
option(MCPI_SERVER_MODE "Server Mode" FALSE)
option(MCPI_HEADLESS_MODE "Headless Mode" ${MCPI_SERVER_MODE})
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")
option(MCPI_OPEN_SOURCE_ONLY "Only Install Open-Source Code (Will Result In Broken Install)" FALSE)
option(MCPI_IS_APPIMAGE_BUILD "AppImage Build" FALSE)
# Avoid Warning About DOWNLOAD_EXTRACT_TIMESTAMP
cmake_policy(SET CMP0135 NEW)
# 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")
endif()
# Core Options
include(cmake/options/core-options.cmake)
# 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 "lib/${MCPI_VARIANT_NAME}")
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin")
include(cmake/util/util.cmake)
# Build Mode
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(IS_MULTI_CONFIG)
force_set(CMAKE_CONFIGURATION_TYPES "Release;Debug" STRING)
set(FORCE_BUILD_TYPE "")
elseif(NOT DEFINED CMAKE_BUILD_TYPE)
set(FORCE_BUILD_TYPE "Release")
endif()
if(DEFINED FORCE_BUILD_TYPE)
force_set(CMAKE_BUILD_TYPE "${FORCE_BUILD_TYPE}" STRING)
endif()
# Start Project
project(minecraft-pi-reborn)
# Require ARM Compilation
if(USE_ARM32_TOOLCHAIN AND (NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "arm") AND (NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l"))
message(FATAL_ERROR "ARM-Targeting Compiler Required")
# Sanity Checks
string(CONCAT ARM_SANITY_CHECK
"include(CheckSymbolExists)\n"
"check_symbol_exists(\"__arm__\" \"\" IS_ARM_TARGETING)\n"
)
if(BUILD_ARM_COMPONENTS)
string(APPEND ARM_SANITY_CHECK
"if(NOT IS_ARM_TARGETING)\n"
" message(FATAL_ERROR \"ARM-Targeting Compiler Required\")\n"
"endif()\n"
)
endif()
cmake_language(EVAL CODE "${ARM_SANITY_CHECK}")
# Specify Default Installation Prefix
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "" FORCE)
endif()
# Extra Options
include(cmake/options/extra-options.cmake)
# Paths
include(cmake/options/paths.cmake)
# Required Compile Flags
set(RELEASE_MODE_GENERATOR "\$<CONFIG:Release>")
string(CONCAT COMPILE_FLAGS_SETUP
# Optimizations
if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_compile_options(-O3)
else()
add_compile_options(-g)
endif()
# Use LLD When Using Clang
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
add_link_options("-fuse-ld=lld")
endif()
"add_compile_options(\"\$<IF:${RELEASE_MODE_GENERATOR},-O3,-g>\")\n"
"add_link_options(\"\$<${RELEASE_MODE_GENERATOR}:-s>\")\n"
# PIC
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
"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 20)\n"
# Skip RPath
"set(CMAKE_SKIP_BUILD_RPATH TRUE)\n"
# Always Build Shared Libraries
"set(BUILD_SHARED_LIBS TRUE CACHE BOOL \"\" FORCE)\n"
)
if(BUILD_ARM_COMPONENTS)
string(APPEND COMPILE_FLAGS_SETUP
# Disable C++11 String ABI
"add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)\n"
)
endif()
cmake_language(EVAL CODE "${COMPILE_FLAGS_SETUP}")
# Build Dependencies
add_subdirectory(dependencies)
# Fast Math
add_compile_options(-ffast-math)
# Buld Dependencies
add_subdirectory(dependencies)
# 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(MCPI_HEADLESS_MODE)
add_definitions(-DMCPI_HEADLESS_MODE)
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 11.0)
add_compile_options(-Wno-array-bounds -Wno-stringop-overread)
endif()
if(MCPI_IS_APPIMAGE_BUILD)
add_definitions(-DMCPI_IS_APPIMAGE_BUILD)
endif()
# Version
file(STRINGS VERSION VERSION)
add_definitions(-DVERSION="${VERSION}")
# Build libreborn
add_subdirectory(libreborn)
@ -123,3 +114,99 @@ endif()
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_NATIVE_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")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake"
# Sanity Check
"${ARM_SANITY_CHECK}"
# Compile Flags
"${COMPILE_FLAGS_SETUP}"
# 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}")
# Calculate Hash Of SDK
string(CONCAT SDK_HASH_SCRIPT
# Prepare
"set(dir \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${MCPI_SDK_DIR}\")\n"
"set(out \"\${dir}/.hash\")\n"
# Calculate Hashes
"set(content \"\")\n"
"file(GLOB_RECURSE files LIST_DIRECTORIES FALSE \"\${dir}/*\")\n"
"foreach(file IN LISTS files)\n"
" file(SHA256 \"\${file}\" hash)\n"
" cmake_path(RELATIVE_PATH file BASE_DIRECTORY \"\${dir}\")\n"
" string(APPEND content \"\${hash} \${file}\\n\")\n"
"endforeach()\n"
# Write File
"file(WRITE \"\${out}\" \"\${content}\")\n"
)
install(CODE "${SDK_HASH_SCRIPT}")
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>")
if(NOT MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
if(DEFINED CMAKE_TOOLCHAIN_FILE)
set(ARM_TOOLCHAIN "${CMAKE_TOOLCHAIN_FILE}")
endif()
else()
set(ARM_TOOLCHAIN "${MCPI_CMAKE_TOOLCHAIN_FILE}")
endif()
if(DEFINED ARM_TOOLCHAIN)
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${ARM_TOOLCHAIN}")
endif()
# Build
ExternalProject_Add(arm-components
# Source Directory
DOWNLOAD_COMMAND ""
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
# Configure
CMAKE_CACHE_ARGS ${ARM_OPTIONS}
CMAKE_GENERATOR "Ninja Multi-Config"
# Build
BUILD_COMMAND
"${CMAKE_COMMAND}" "--build" "<BINARY_DIR>" "--config" "$<CONFIG>"
# Install
INSTALL_COMMAND
"${CMAKE_COMMAND}" "-E"
"rm" "-rf" "<INSTALL_DIR>/${MCPI_INSTALL_DIR}"
COMMAND
"${CMAKE_COMMAND}" "-E" "env" "DESTDIR="
"${CMAKE_COMMAND}" "--install" "<BINARY_DIR>" "--config" "$<CONFIG>"
# Use Terminal
USES_TERMINAL_CONFIGURE TRUE
USES_TERMINAL_BUILD TRUE
USES_TERMINAL_INSTALL TRUE
# Always Build
BUILD_ALWAYS TRUE
)
# Install
ExternalProject_Get_Property(arm-components INSTALL_DIR)
install(DIRECTORY "${INSTALL_DIR}/${MCPI_INSTALL_DIR}/" DESTINATION "${MCPI_INSTALL_DIR}")
endif()

View File

@ -1,31 +0,0 @@
FROM debian:bullseye-slim
# Install
RUN \
apt-get update && \
apt-get install -y tini sed && \
apt-get --fix-broken install -y && \
rm -rf /var/lib/apt/lists/*
# Copy AppImage
RUN mkdir /app
ADD ./out/minecraft-pi-reborn-server-*-amd64.AppImage /app
# Extract AppImage
WORKDIR /app
RUN \
sed -i '0,/AI\x02/{s|AI\x02|\x00\x00\x00|}' ./*.AppImage && \
./*.AppImage --appimage-extract && \
rm -f ./*.AppImage
# Setup AppImage
ENV OWD=/data
ENV APPDIR=/app/squashfs-root
# Setup Working Directory
RUN mkdir /data
WORKDIR /data
# Setup Entrypoint
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/app/squashfs-root/AppRun"]

35
Jenkinsfile vendored
View File

@ -1,35 +0,0 @@
pipeline {
agent none
stages {
stage('Debian Bullseye') {
agent {
dockerfile {
filename 'scripts/ci/Dockerfile'
args '-v /var/run/docker.sock:/var/run/docker.sock'
}
}
stages {
stage('Build') {
steps {
sh './scripts/ci/run.sh'
}
post {
success {
archiveArtifacts artifacts: 'out/*.AppImage*', 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'
}
}
}
}
}
}

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2022 TheBrokenRail
Copyright (c) 2025 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

@ -2,8 +2,16 @@
<img alt="Start Screen" src="images/start.png">
</p>
# Minecraft: Pi Edition: Reborn
<p align="center">
<a href="https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases/latest"><img height="80" alt="Download as an AppImage" src="https://docs.appimage.org/_images/download-appimage-banner.svg" /></a>
<a href="https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn"><img height="80" alt="Download on Flathub" src="https://flathub.org/assets/badges/flathub-badge-en.svg" /></a>
<a href="https://github.com/Botspot/pi-apps"><img height="80" alt="Get it from Pi-Apps" src="https://github.com/Botspot/pi-apps/blob/master/icons/badge.png?raw=true" /></a>
</p>
# Minecraft: Pi Edition: Reborn [![Gitea Actions](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/actions/workflows/build.yml/badge.svg)](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/actions)
Minecraft: Pi Edition Modding Project
Get started [here](docs/GETTING_STARTED.md)!
## Documentation
[View Documentation](docs/README.md)

View File

@ -1 +1 @@
2.3.4
3.0.0

1
archives Submodule

@ -0,0 +1 @@
Subproject commit 5baa6b1948aeebb5e13af31ff62dc97f00a3b71e

View File

@ -1,11 +0,0 @@
# Setup Toolchain
macro(setup_toolchain target)
# Use ARM Cross-Compiler
set(CMAKE_C_COMPILER "${target}-gcc")
set(CMAKE_CXX_COMPILER "${target}-g++")
set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}")
# Extra
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# pkg-config
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/${target}/pkgconfig:/usr/${target}/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig")
endmacro()

View File

@ -0,0 +1,60 @@
# Download 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/type2-runtime/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 Download 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}"
"VERSION=${CPACK_MCPI_VERSION}"
"appimagetool"
"--updateinformation" "zsync|${CPACK_MCPI_REPO}/releases/download/latest/${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}"
"--runtime-file" "${RUNTIME}"
"--comp" "zstd"
"${CPACK_TEMPORARY_DIRECTORY}"
"${CPACK_PACKAGE_FILE_NAME}${CPACK_MCPI_APPIMAGE_EXT}"
WORKING_DIRECTORY "${CPACK_PACKAGE_DIRECTORY}"
COMMAND_ERROR_IS_FATAL ANY
)
# Rename ZSync File
file(RENAME "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}" "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}")
# 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}${CPACK_MCPI_APPIMAGE_EXT}")
check_file("${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}")

View File

@ -0,0 +1,32 @@
# CPack
set(CPACK_PACKAGE_NAME "${MCPI_APP_NAME}")
set(CPACK_PACKAGE_VENDOR "${MCPI_AUTHOR} & Mojang AB")
set(CPACK_VERBATIM_VARIABLES TRUE)
set(CPACK_MONOLITHIC_INSTALL TRUE)
get_package_file_name(CPACK_PACKAGE_FILE_NAME "${MCPI_VERSION}")
get_package_file_name(CPACK_PACKAGE_FILE_NAME_ZSYNC "latest")
# 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")
# Pass Variable To CPack
macro(pass_to_cpack var)
set("CPACK_MCPI_${var}" "${MCPI_${var}}")
endmacro()
pass_to_cpack(VERSION)
pass_to_cpack(ARCH)
pass_to_cpack(REPO)
pass_to_cpack(APPIMAGE_EXT)
pass_to_cpack(APPIMAGE_ZSYNC_EXT)
endif()
# Package
include(CPack)

View File

@ -1,9 +0,0 @@
# Warning
message(WARNING "i686 Builds Are Unsupported, Proceed At Your Own Risk")
# Compile For i686
include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake")
# Use i686 Cross-Compiler
setup_toolchain("i686-linux-gnu")
# Details
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "i686")

View File

View File

@ -0,0 +1,27 @@
# 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()
# Clear External CFLAGS When Building ARM Components
if(BUILD_ARM_COMPONENTS)
unset(ENV{CFLAGS})
unset(ENV{CXXFLAGS})
endif()

View File

@ -0,0 +1,89 @@
# 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()
# 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()
if(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
include("${CMAKE_CURRENT_LIST_DIR}/prebuilt-armhf-toolchain.cmake")
endif()
endif()
# Media Layer
set(DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE FALSE)
if(BUILD_NATIVE_COMPONENTS AND NOT IS_ARM_TARGETING)
set(DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE TRUE)
endif()
mcpi_option(USE_MEDIA_LAYER_TRAMPOLINE "Whether To Enable The Media Layer Trampoline" BOOL "${DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE}")
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
set(BUILD_MEDIA_LAYER_CORE "${BUILD_NATIVE_COMPONENTS}")
else()
set(BUILD_MEDIA_LAYER_CORE "${BUILD_ARM_COMPONENTS}")
endif()
# App Information
mcpi_option(APP_NAME "App Name" STRING "minecraft-pi-reborn")
mcpi_option(APP_ID "App ID" STRING "com.thebrokenrail.MCPIReborn")
mcpi_option(APP_TITLE "App Title" STRING "Minecraft: Pi Edition: Reborn")
# Skin Server
mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data")
# Discord Invite URL
mcpi_option(DISCORD_INVITE "Discord Invite URL" STRING "https://discord.gg/mcpi-revival-740287937727561779")
# Version
set_property(
DIRECTORY
APPEND
PROPERTY CMAKE_CONFIGURE_DEPENDS VERSION
)
file(STRINGS "${CMAKE_CURRENT_LIST_DIR}/../../VERSION" MCPI_VERSION)
file(TIMESTAMP "${CMAKE_CURRENT_LIST_DIR}/../../VERSION" MCPI_VERSION_DATE "%Y-%m-%d" UTC)
# Author
mcpi_option(AUTHOR "Author" STRING "TheBrokenRail")
# Homepage
mcpi_option(REPO_HOST "Repository Host" STRING "https://gitea.thebrokenrail.com")
mcpi_option(REPO_PATH "Repository Path" STRING "minecraft-pi-reborn/minecraft-pi-reborn")
mcpi_option(REPO "Repository URL" STRING "${MCPI_REPO_HOST}/${MCPI_REPO_PATH}")
# Documentation URL
mcpi_option(DOCS "Documentation URL" STRING "${MCPI_REPO}/src/tag/${MCPI_VERSION}/docs/")
# Packaging
set(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(MCPI_ARCH "${name}" PARENT_SCOPE)
endif()
endfunction()
check_arch("__arm__" "armhf")
check_arch("__aarch64__" "arm64")
check_arch("__x86_64__" "amd64")
macro(get_package_file_name out version)
set("${out}" "${MCPI_APP_NAME}-${version}-${MCPI_ARCH}")
endmacro()
# AppImage
if(MCPI_IS_APPIMAGE_BUILD)
mcpi_option(APPIMAGE_EXT "AppImage Extension" STRING ".AppImage")
mcpi_option(APPIMAGE_ZSYNC_EXT "AppImage Update Extension" STRING "${MCPI_APPIMAGE_EXT}.zsync")
mcpi_option(APPIMAGE_JSON_URL "AppImage Update Checker URL" STRING "${MCPI_REPO_HOST}/api/v1/repos/${MCPI_REPO_PATH}/releases/latest")
mcpi_option(APPIMAGE_VERSION_PLACEHOLDER "Version Placeholder In AppImage Download URL" STRING "%VERSION%")
get_package_file_name(appimage_package_file_name "${MCPI_APPIMAGE_VERSION_PLACEHOLDER}")
mcpi_option(APPIMAGE_DOWNLOAD_URL "AppImage Download URL" STRING "${MCPI_REPO}/releases/download/${MCPI_APPIMAGE_VERSION_PLACEHOLDER}/${appimage_package_file_name}${MCPI_APPIMAGE_EXT}")
endif()

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

@ -0,0 +1,33 @@
# Specify Installation Paths
set(MCPI_INSTALL_DIR "lib/${MCPI_APP_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 "Install Prefix" FORCE)
set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT FALSE)
endif()

View File

@ -0,0 +1,88 @@
# Target
set(target "arm-none-linux-gnueabihf")
# Pick Archive
set(toolchain_version "13.3.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-${target}.tar.xz")
elseif(arch STREQUAL "aarch64" OR arch STREQUAL "armv8b" OR arch STREQUAL "armv8l")
set(toolchain_file "arm-gnu-toolchain-${toolchain_version}-aarch64-${target}.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/${target}-gcc\")\n"
"set(CMAKE_CXX_COMPILER \"\${CMAKE_CURRENT_LIST_DIR}/bin/${target}-g++\")\n"
"set(CMAKE_SYSTEM_NAME \"Linux\")\n"
"set(CMAKE_SYSTEM_PROCESSOR \"arm\")\n"
"set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\n"
)
force_set(MCPI_CMAKE_TOOLCHAIN_FILE "${toolchain_dir}/toolchain.cmake" FILEPATH)
# Build Sysroot
set(sysroot_dir "${CMAKE_CURRENT_BINARY_DIR}/bundled-armhf-sysroot")
set(sysroot_dir_debug "${sysroot_dir}/debug")
set(sysroot_dir_release "${sysroot_dir}/release")
if("${toolchain_dir}/bin/${target}-gcc" IS_NEWER_THAN "${sysroot_dir}")
# Create Directory
file(REMOVE_RECURSE "${sysroot_dir}")
file(MAKE_DIRECTORY "${sysroot_dir_debug}")
file(MAKE_DIRECTORY "${sysroot_dir_release}")
# Copy Files From Toolchain
file(
COPY "${toolchain_dir}/${target}/libc/"
DESTINATION "${sysroot_dir_debug}"
USE_SOURCE_PERMISSIONS
FILES_MATCHING
PATTERN "*.so*"
)
# Delete Unneeded Files
file(REMOVE_RECURSE "${sysroot_dir_debug}/usr/lib/audit")
file(REMOVE_RECURSE "${sysroot_dir_debug}/usr/lib/gconv")
# Strip Files
file(COPY "${sysroot_dir_debug}/." DESTINATION "${sysroot_dir_release}")
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE "${sysroot_dir_release}/*")
foreach(file IN LISTS files)
execute_process(
COMMAND "${toolchain_dir}/bin/${target}-strip" "${file}"
RESULT_VARIABLE ret
ERROR_QUIET
)
# Delete Invalid Files
if(NOT ret EQUAL 0)
file(REMOVE "${file}")
endif()
endforeach()
endif()
# Install Sysroot (Skipping Empty Directories)
function(install_arm_sysroot_config config)
set(dir "${sysroot_dir_${config}}")
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE RELATIVE "${dir}" "${dir}/*")
foreach(file IN LISTS files)
cmake_path(GET file PARENT_PATH parent)
install(
PROGRAMS "${dir}/${file}"
DESTINATION "${MCPI_INSTALL_DIR}/sysroot/${parent}"
CONFIGURATIONS "${config}"
)
endforeach()
endfunction()
function(install_arm_sysroot)
install_arm_sysroot_config(debug)
install_arm_sysroot_config(release)
endfunction()

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
cmake_path(GET EMBED_OUT STEM name)
# Write Data
file(WRITE "${EMBED_OUT}"
"#include <stddef.h>\n"
"const unsigned char ${name}[] = {${data}};\n"
"const size_t ${name}_len = sizeof (${name});\n"
)

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

@ -0,0 +1,91 @@
# Symlink Function
function(install_symlink target link)
cmake_path(GET link PARENT_PATH parent)
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
cmake_path(GET file FILENAME name)
string(MAKE_C_IDENTIFIER "${name}" name)
# Add Command
set(in "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
set(out "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
set(script "${util_list_dir}/embed-resource.cmake")
add_custom_command(OUTPUT "${out}"
COMMAND "${CMAKE_COMMAND}"
ARGS "-DEMBED_IN=${in}" "-DEMBED_OUT=${out}" "-P" "${script}"
DEPENDS "${in}" "${script}"
VERBATIM
)
# Add To Target
target_sources("${target}" PRIVATE "${out}")
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()
# Exporting Targets And Headers
macro(_get_sdk_header_dir target)
set(sdk_dir "${MCPI_SDK_INCLUDE_DIR}/${target}")
endmacro()
function(setup_header_dirs target)
_get_sdk_header_dir("${target}")
# Get Header Type
set(header_type "PUBLIC")
get_target_property(type "${target}" TYPE)
if ("${type}" STREQUAL "INTERFACE_LIBRARY")
set(header_type "INTERFACE")
endif()
# Loop
foreach(dir IN LISTS ARGN)
# Add To Target
target_include_directories("${target}" "${header_type}" "$<BUILD_INTERFACE:${dir}>")
# Add To SDK
if(BUILD_ARM_COMPONENTS)
install(
DIRECTORY "${dir}/"
DESTINATION "${sdk_dir}"
FILES_MATCHING
PATTERN "*.h"
)
endif()
endforeach()
# Add SDK Headers To Target
if(BUILD_ARM_COMPONENTS)
target_include_directories("${target}" "${header_type}" "$<INSTALL_INTERFACE:${sdk_dir}>")
endif()
endfunction()
function(setup_library target should_install should_export)
# Install
if(should_install)
install(TARGETS "${target}" DESTINATION "${MCPI_LIB_DIR}")
endif()
# SDK
if(should_export AND BUILD_ARM_COMPONENTS)
install(TARGETS "${target}" EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
endif()
endfunction()
# Force Set Configuration Variable
function(force_set name value type)
set("${name}" "${value}" CACHE "${type}" "" FORCE)
mark_as_advanced(FORCE "${name}")
endfunction()
# Make Directory
function(set_and_mkdir name dir)
set("${name}" "${dir}" PARENT_SCOPE)
file(MAKE_DIRECTORY "${dir}")
endfunction()

View File

@ -1,22 +1,30 @@
project(dependencies)
# ZLib
# stb_image
if(BUILD_ARM_COMPONENTS)
add_subdirectory(zlib)
endif()
# LibPNG
if(BUILD_ARM_COMPONENTS)
add_subdirectory(libpng)
add_subdirectory(stb_image)
endif()
# Minecraft: Pi Edition
if(BUILD_ARM_COMPONENTS AND NOT MCPI_OPEN_SOURCE_ONLY)
add_subdirectory(minecraft-pi)
endif()
# LIEF
if(BUILD_NATIVE_COMPONENTS OR BUILD_MEDIA_LAYER_CORE)
add_subdirectory(LIEF)
endif()
# Extra Runtime
add_subdirectory(runtime)
# GLFW
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
if(BUILD_NATIVE_COMPONENTS OR BUILD_MEDIA_LAYER_CORE)
add_subdirectory(glfw)
endif()
# Zenity (Minimal Build)
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
add_subdirectory(zenity)
# ImGui
if(BUILD_NATIVE_COMPONENTS)
add_subdirectory(imgui)
endif()
# UTF8-CPP
add_subdirectory(utf8cpp)
# Symbol Processor
if(BUILD_ARM_COMPONENTS)
add_subdirectory(symbol-processor)
endif()

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

@ -0,0 +1,43 @@
project(LIEF)
# Silence Warnings
add_compile_options(-w -Wno-psabi)
## LIEF
# Options
force_set(LIEF_C_API FALSE BOOL)
force_set(LIEF_EXAMPLES FALSE BOOL)
force_set(LIEF_PYTHON_API FALSE BOOL)
force_set(LIEF_TESTS FALSE BOOL)
force_set(LIEF_USE_CCACHE FALSE BOOL)
force_set(LIEF_LOGGING FALSE BOOL)
force_set(LIEF_LOGGING_DEBUG FALSE BOOL)
force_set(LIEF_ENABLE_JSON FALSE BOOL)
force_set(LIEF_ELF TRUE BOOL)
force_set(LIEF_PE FALSE BOOL)
force_set(LIEF_MACHO FALSE BOOL)
force_set(LIEF_DEX FALSE BOOL)
force_set(LIEF_ART FALSE BOOL)
force_set(LIEF_OAT FALSE BOOL)
force_set(LIEF_VDEX FALSE BOOL)
# Download
set(MESSAGE_QUIET TRUE)
add_subdirectory(src EXCLUDE_FROM_ALL SYSTEM)
unset(MESSAGE_QUIET)
# Install
setup_library(LIB_LIEF TRUE TRUE)
# License
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/LIEF")
# Fix Flags
function(fix_flags property)
get_target_property(flags LIB_LIEF "${property}")
list(REMOVE_ITEM flags "_GLIBCXX_USE_CXX11_ABI=1")
set_target_properties(LIB_LIEF PROPERTIES "${property}" "${flags}")
endfunction()
fix_flags(COMPILE_DEFINITIONS)
fix_flags(INTERFACE_COMPILE_DEFINITIONS)

1
dependencies/LIEF/src vendored Submodule

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

View File

@ -6,17 +6,21 @@ add_compile_options(-w)
## GLFW
# Download
set(BUILD_SHARED_LIBS FALSE)
set(GLFW_BUILD_EXAMPLES FALSE)
set(GLFW_BUILD_TESTS FALSE)
set(GLFW_BUILD_DOCS FALSE)
set(GLFW_INSTALL FALSE)
set(GLFW_BUILD_WIN32 FALSE)
set(GLFW_BUILD_COCOA FALSE)
set(GLFW_BUILD_X11 TRUE)
set(GLFW_BUILD_WAYLAND TRUE)
set(GLFW_LIBRARY_TYPE "STATIC")
add_subdirectory(src EXCLUDE_FROM_ALL)
force_set(GLFW_BUILD_EXAMPLES FALSE BOOL)
force_set(GLFW_BUILD_TESTS FALSE BOOL)
force_set(GLFW_BUILD_DOCS FALSE BOOL)
force_set(GLFW_INSTALL FALSE BOOL)
force_set(GLFW_BUILD_WIN32 FALSE BOOL)
force_set(GLFW_BUILD_COCOA FALSE BOOL)
force_set(GLFW_BUILD_X11 TRUE BOOL)
force_set(GLFW_BUILD_WAYLAND TRUE BOOL)
force_set(GLFW_LIBRARY_TYPE "SHARED" STRING)
set(MESSAGE_QUIET TRUE)
add_subdirectory(src EXCLUDE_FROM_ALL SYSTEM)
unset(MESSAGE_QUIET)
# Ensure Build
add_custom_target(glfw-build ALL DEPENDS glfw)
# Install
setup_library(glfw TRUE TRUE)
# License
install(FILES src/LICENSE.md DESTINATION "${MCPI_LEGAL_DIR}/GLFW")

@ -1 +1 @@
Subproject commit 4cb36872a5fe448c205d0b46f0e8c8b57530cfe0
Subproject commit 21fea01161e0d6b70c0c5c1f52dc8e7a7df14a50

52
dependencies/imgui/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,52 @@
project(imgui)
# Silence Warnings
add_compile_options(-w)
## ImGui
# Build
add_library(imgui SHARED
src/imgui.cpp
src/imgui_draw.cpp
src/imgui_tables.cpp
src/imgui_widgets.cpp
src/misc/cpp/imgui_stdlib.cpp
src/backends/imgui_impl_glfw.cpp
src/backends/imgui_impl_opengl2.cpp
)
setup_header_dirs(imgui
"${CMAKE_CURRENT_SOURCE_DIR}/src"
"${CMAKE_CURRENT_SOURCE_DIR}/src/backends"
"${CMAKE_CURRENT_SOURCE_DIR}/src/misc/cpp"
)
# OpenGL
add_subdirectory(glad)
target_link_libraries(imgui PUBLIC glfw glad)
# Fonts
embed_resource(imgui src/misc/fonts/Roboto-Medium.ttf)
embed_resource(imgui src/misc/fonts/Cousine-Regular.ttf)
# Configure
target_compile_definitions(imgui PUBLIC
IMGUI_DISABLE_DEMO_WINDOWS
IMGUI_DISABLE_DEBUG_TOOLS
IMGUI_DISABLE_DEFAULT_FONT
IMGUI_DISABLE_OBSOLETE_FUNCTIONS
)
# Patch
execute_process(
COMMAND "patch" "-p1" "--forward" "--reject-file=-"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src"
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/fix-hidpi.patch"
OUTPUT_QUIET
)
# Install
setup_library(imgui TRUE FALSE)
# License
install(FILES src/LICENSE.txt src/docs/FONTS.md DESTINATION "${MCPI_LEGAL_DIR}/ImGui")

55
dependencies/imgui/fix-hidpi.patch vendored Normal file
View File

@ -0,0 +1,55 @@
--- a/backends/imgui_impl_glfw.cpp
+++ b/backends/imgui_impl_glfw.cpp
@@ -422,6 +422,21 @@ void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
io.AddFocusEvent(focused != 0);
}
+static void ImGui_ImplGlfw_ScaleMousePos(GLFWwindow* window, double &x, double &y) {
+ // Get Window Size
+ int window_width, window_height;
+ glfwGetWindowSize(window, &window_width, &window_height);
+ if (window_width <= 0 || window_height <= 0) {
+ return;
+ }
+ // Get Framebuffer Size
+ int framebuffer_width, framebuffer_height;
+ glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
+ // Multiply
+ x *= double(framebuffer_width) / double(window_width);
+ y *= double(framebuffer_height) / double(window_height);
+}
+
void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
{
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
@@ -429,6 +444,7 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
bd->PrevUserCallbackCursorPos(window, x, y);
ImGuiIO& io = ImGui::GetIO();
+ ImGui_ImplGlfw_ScaleMousePos(window, x, y);
io.AddMousePosEvent((float)x, (float)y);
bd->LastValidMousePos = ImVec2((float)x, (float)y);
}
@@ -738,6 +754,7 @@ static void ImGui_ImplGlfw_UpdateMouseData()
{
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
+ ImGui_ImplGlfw_ScaleMousePos(window, mouse_x, mouse_y);
bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
}
@@ -831,13 +848,9 @@ void ImGui_ImplGlfw_NewFrame()
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?");
// Setup display size (every frame to accommodate for window resizing)
- int w, h;
int display_w, display_h;
- glfwGetWindowSize(bd->Window, &w, &h);
glfwGetFramebufferSize(bd->Window, &display_w, &display_h);
- io.DisplaySize = ImVec2((float)w, (float)h);
- if (w > 0 && h > 0)
- io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);
+ io.DisplaySize = ImVec2((float)display_w, (float)display_h);
// Setup time step
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)

49
dependencies/imgui/glad/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,49 @@
project(imgui-glad)
# Directories
set_and_mkdir(GLAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/glad")
set_and_mkdir(GLAD_SRC_DIR "${GLAD_DIR}/src")
set_and_mkdir(GLAD_INCLUDE_DIR "${GLAD_DIR}/include")
# Files
set(GLAD_SOURCES
"${GLAD_INCLUDE_DIR}/KHR/khrplatform.h"
"${GLAD_INCLUDE_DIR}/glad/glad.h"
"${GLAD_SRC_DIR}/glad.c"
)
# Find Python
find_package(Python REQUIRED QUIET)
# Generate
add_custom_command(
OUTPUT ${GLAD_SOURCES}
COMMAND "${Python_EXECUTABLE}"
ARGS "-m" "glad"
"--out" "${GLAD_DIR}"
"--api" "gl=1.1"
"--generator" "c"
"--reproducible"
"--quiet"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src"
VERBATIM
)
# Build
add_library(glad SHARED ${GLAD_SOURCES})
target_compile_definitions(glad
PUBLIC GLAD_GLAPI_EXPORT
PRIVATE GLAD_GLAPI_EXPORT_BUILD
)
# Link
target_link_libraries(glad PRIVATE dl)
# Headers
setup_header_dirs(glad
"${GLAD_INCLUDE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/include"
)
# Install
setup_library(glad TRUE FALSE)

View File

@ -0,0 +1,2 @@
#pragma once
#include <glad/glad.h>

1
dependencies/imgui/glad/src vendored Submodule

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

1
dependencies/imgui/src vendored Submodule

@ -0,0 +1 @@
Subproject commit 6982ce43f5b143c5dce5fab0ce07dd4867b705ae

View File

@ -1,20 +0,0 @@
project(libpng)
# Silence Warnings
add_compile_options(-w)
## LibPNG
# Download
set(ZLIB_LIBRARY zlibstatic)
set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/src" "${CMAKE_CURRENT_BINARY_DIR}/../zlib/src")
set(CMAKE_POLICY_DEFAULT_CMP0054 OLD) # Silence Warning
add_subdirectory(src EXCLUDE_FROM_ALL)
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
# Ensure Build
add_custom_target(png12-build ALL DEPENDS png12)
# 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: *; };

@ -1 +0,0 @@
Subproject commit 5bb5bf345aef1e62adcfe30791f4364730a2aede

View File

@ -5,11 +5,16 @@ include(FetchContent)
## Minecraft: Pi Edition
# Download
FetchContent_Declare(
minecraft-pi
FetchContent_Declare(minecraft-pi
URL "${CMAKE_CURRENT_SOURCE_DIR}/minecraft-pi-0.1.1.tar.gz"
)
FetchContent_Populate(minecraft-pi)
FetchContent_MakeAvailable(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
)
install_symlink("game/minecraft-pi" "${MCPI_INSTALL_DIR}/minecraft-pi")

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

@ -0,0 +1,12 @@
project(runtime)
## Extra Runtime
# Build
add_subdirectory(src)
# RPath
if(TARGET runtime)
set_target_properties(runtime PROPERTIES INSTALL_RPATH "$ORIGIN/../lib/native")
target_link_options(runtime PRIVATE "LINKER:--disable-new-dtags")
endif()

1
dependencies/runtime/src vendored Submodule

@ -0,0 +1 @@
Subproject commit 84e37b572b55afb1eaa2ada1e37bc36de1584cfd

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

@ -0,0 +1,18 @@
project(stb_image)
# Silence Warnings
add_compile_options(-w)
## stb_image
# Build
add_library(stb_image SHARED src/stb_image_impl.c)
target_link_libraries(stb_image PRIVATE m)
target_compile_definitions(stb_image PUBLIC STBI_ONLY_PNG)
setup_header_dirs(stb_image "${CMAKE_CURRENT_SOURCE_DIR}/include")
# Install
setup_library(stb_image TRUE TRUE)
# 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 c803572e248998cc9d197f84661fea56bebf7346

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}/UTF8-CPP")

1
dependencies/utf8cpp/src vendored Submodule

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

View File

@ -1,15 +0,0 @@
project(zenity)
# Silence Warnings
add_compile_options(-w)
## Zenity
# Download
add_subdirectory(src EXCLUDE_FROM_ALL)
# Ensure Build
add_custom_target(zenity-build ALL DEPENDS zenity)
# Install
install(TARGETS zenity DESTINATION "${MCPI_BIN_DIR}")

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

View File

@ -1,12 +0,0 @@
project(zlib)
# Silence Warnings
add_compile_options(-w)
## zlib
# Download
add_subdirectory(src EXCLUDE_FROM_ALL)
# Ensure Build
add_custom_target(zlib-build ALL DEPENDS zlibstatic)

@ -1 +0,0 @@
Subproject commit 21767c654d31d2dccdde4330529775c6c5fd5389

View File

@ -1,109 +0,0 @@
# Architecture
## Launch Sequence
### 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
### Server
1. The launcher is started by the user
2. The launcher replaces itself with MCPI
## Components
### Launcher
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``
This is always compiled for the host system's architecture.
### Media Layer
The Media Layer handles MCPI's graphics calls and user input. It replaces MCPI's native usage of SDL 1.2 with GLFW.
#### Core
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 was created because SDL 1.2 has numerous bugs and is in-general unsupported.
#### Proxy
This sub-component must be used if the host system's architecture isn't ARM. It uses UNIX pipes to cross architectural boundaries and allow MCPI to use the Media Layer Core (which is always compiled for the host system's architecture).
It is made of two parts:
* Media Layer Proxy Server
* Links To MCPI
* Creates The UNIX Pipes
* Same External API As The Media Layer Core
* Compiled For ARM
* Media Layer Proxy Client
* Links To The Media Layer Core
* Connects To The Media Layer Proxy Server
* Uses The System's Native GLES Driver (ie. Mesa)
* Compiled For The Host System's Architecture
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).
#### 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 is always compiled for ARM.
### ``libreborn``
This component contains various utility functions including:
* Code Patching (ARM Only)
* Logging
* 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
* 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)

View File

@ -1,34 +0,0 @@
# Building
## Build Dependencies
* Common
* ARM Compiler
* Host Compiler (Clang)
* CMake
* Host Architecture Dependencies
* Client Mode Only
* GLFW
* FreeImage
* OpenAL
## Runtime Dependencies
* Non-ARM Host Architectures
* QEMU User-Mode
* Host Architecture Dependencies
* CLient Mode Only
* OpenGL ES 1.1
* GLFW
* FreeImage
* OpenAL
* Zenity
## Instructions
```sh
./scripts/build.sh <client|server> <armhf|arm64|i686|amd64>
```
### Custom CMake Arguments
```sh
./scripts/setup.sh <client|server> <armhf|arm64|i686|amd64> <Custom CMake Arguments>
./scripts/build.sh <client|server> <armhf|arm64|i686|amd64>
```

View File

@ -1,22 +1,277 @@
# Changelog
**3.0.0**
* Modding API Revamped
* `*(unsigned char **)` Is Dead!
* Now C++ Only
* Add Peaceful Mode To Options Screen
* Proper Create New World Screen
* Proper Chat Screen
* New Feature Flags
* New Functionality
* `Animated Lava` (Enabled By Default)
* `Animated Fire` (Enabled By Default)
* `Add Cake` (Enabled By Default)
* `Use Java Beta 1.3 Light Ramp` (Enabled By Default)
* `Send Full Level When Hosting Game` (Enabled By Default)
* `Food Overlay` (Disabled By Default)
* `Add Splashes` (Enabled By Default)
* `Display Date In Select World Screen` (Enabled By Default)
* `Optimized Chunk Sorting` (Enabled By Default)
* `Fix Held Item Caching` (Enabled By Default)
* `Add Reborn Info To Options` (Enabled By Default)
* `Log FPS` (Disabled By Default)
* `Add Welcome Screen` (Enabled By Default)
* `F3 Debug Information` (Enabled By Default)
* `Multidraw Rendering` (Enabled By Default)
* `Add Missing Language Strings` (Enabled By Default)
* `Fix Pigmen Burning In The Sun` (Enabled By Default)
* `Fix Carried Grass's Bottom Texture` (Enabled By Default)
* `Hide Crosshair In Third-Person` (Enabled By Default)
* `Fix Camera Legs` (Enabled By Default)
* `Implement Crafting Remainders` (Enabled By Default)
* `Fix Door Duplication` (Enabled By Default)
* `Fix Cobweb Lighting` (Enabled By Default)
* `Fix Sneaking Syncing` (Enabled By Default)
* `Fix Fire Immunity` (Enabled By Default)
* `Fix Fire Syncing` (Enabled By Default)
* `Fix Sunlight Not Properly Setting Mobs On Fire` (Enabled By Default)
* `Stop Creative Players From Burning` (Enabled By Default)
* `Render Fire In Third-Person` (Enabled By Default)
* `Improved Water Rendering` (Enabled By Default)
* `Classic Item Count UI` (Enabled By Default)
* `Allow High-Resolution Title` (Enabled By Default)
* `Improved Classic Title Positioning` (Enabled By Default)
* `Use Updated Title` (Enabled By Default)
* `Hide Block Outline When GUI Is Hidden` (Enabled By Default)
* `Fix Crash When Generating Certain Seeds` (Enabled By Default)
* `Click Buttons On Mouse Down` (Enabled By Default)
* `3D Dropped Items` (Enabled By Default)
* `Render Entity Shadows` (Enabled By Default)
* `Render Vignette` (Enabled By Default)
* `Increase Render Chunk Size` (Enabled By Default)
* `Proper Entity Shading` (Enabled By Default)
* `Fix Sugar Position In Hand` (Enabled By Default)
* `Fix Reloading Textures On Resize` (Enabled By Default)
* `Improved UI Scaling` (Enabled By Default)
* `Text Rendering Fixes` (Enabled By Default)
* `Close Editor When Sign Is Destroyed` (Enabled By Default)
* `Remove Chest Placement Restrictions` (Enabled By Default)
* `Fix Hanging When No Valid Spawn Point Exists` (Enabled By Default)
* `Batch Font Rendering` (Enabled By Default)
* `Fix Furnace Screen Visual Bug` (Enabled By Default)
* `Fix Held Item Poking Through Screen Overlay` (Enabled By Default)
* Existing Functionality (All Enabled By Default)
* `Fix Screen Rendering When Hiding HUD`
* `Sanitize Usernames`
* `Patch RakNet Security Bug`
* `Log RakNet Startup Errors`
* `Prevent Unnecessary Server Pinging`
* `Proper OpenGL Buffer Generation`
* `Fullscreen Support`
* `Always Save Chest Tile Entities`
* `Fix Transferring Durability When Using Items`
* `Fix Switching Perspective While Sneaking`
* `Log Chat Messages`
* `Log Game Status`
* `Screenshot Support`
* `Fix Camera Functionality`
* `Property Scale Animated Textures`
* `Enable Text Input`
* `Update Default Options`
* `Fix options.txt Loading/Saving`
* `Extend Supported Keycodes`
* Split Up `Remove Creative Mode Restrictions` Feature Flag
* `Remove Creative Mode Restrictions` (Disabled By Default)
* `Display Slot Count In Creative Mode` (Disabled By Default)
* `Force Survival Mode Inventory UI` (Disabled By Default)
* `Force Survival Mode Inventory Behavior` (Disabled By Default)
* `Maximize Creative Mode Inventory Stack Size` (Disabled By Default)
* Split Up `Miscellaneous Input Fixes` Feature Flag
* `Fix Escape Key Handling` (Enabled By Default)
* `Stop Locked Mouse From Interacting With HUD` (Enabled By Default)
* Rename Feature Flags
* `Disable Buggy Held Item Caching` To `Fix Held Item Caching`
* `Disable 'gui_blocks' Atlas` To `Regenerate "gui_blocks" Atlas`
* `Fix Sign Placement` To `Enable Sign Screen`
* `Force Touch GUI Inventory` To `Force Touch UI Inventory`
* `Full Touch GUI` To `Full Touch UI`
* `Force Touch GUI Button Behavior` To `Force Touch UI Button Behavior`
* `Remove Forced GUI Lag (Can Break Joining Servers)` To `Remove Forced UI Lag (Can Break Joining Servers)`
* `Hide Block Outline When GUI Is Hidden` To `Hide Block Outline When UI Is Hidden`
* `Fix Camera Functionality` To `Add Camera Functionality`
* `Fix Camera Rendering` To `Enable Camera Rendering`
* `Fix Camera Legs` To `Render Camera Legs`
* Add Milk Buckets
* Included In The `Add Buckets` Feature Flag
* Removed `Property Scale Animated Textures` Feature Flag
* Removed `Remove Invalid Item Background` Feature Flag
* 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
* `overwrite_calls` Now Scans VTables
* Unify Server/Client Builds
* Controller Support Removed
* Brand New Launcher UI!
**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)
* 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)
* 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``
* `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
@ -27,31 +282,31 @@
* 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)
* Add `Disable V-Sync` Feature Flag (Disabled By Default)
**2.3.1**
* Internal Refactor Of ``libreborn``
* Remove Use Of ``/bin/sh``
* 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)
* 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
* 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"
* 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
@ -61,8 +316,8 @@
* Store Files In `/usr/lib`
**2.2.8**
* Add ``Hide Chat Messages`` Optional Feature Flag
* Add ``Remove Creative Mode Restrictions`` Optional Feature Flag
* 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
@ -94,15 +349,15 @@
* Make Missing Sound Event Cause Warning Rather Than Crash
**2.2.1**
* Prevent ``random.burp`` Sound From Crashing Game
* 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
* 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
* Fix Bug Where `RakNetInstance` Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
* Clean-Up Code
* Remove Support For Debian Buster
@ -119,7 +374,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
@ -131,16 +386,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
@ -157,7 +412,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,39 +0,0 @@
# Command Line Usage
## Command Line Arguments
### ``--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:
```
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.
### ``--benchmark`` (Client Mode Only)
If you run MCPI-Reborn with ``--benchmark``, it will 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.
## Environmental Variables
### ``MCPI_DEBUG``
This enables debug logging if you set it to any non-zero-length value.
### Client Mode Only
If a value isn't set for any of the following variables, a GUI will open that allows you to select one.
### ``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.

26
docs/CONTROLS.md Normal file
View File

@ -0,0 +1,26 @@
# 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 |

View File

@ -8,3 +8,4 @@
| [RetDec](https://retdec.com) | Used For Decompiling Minecraft: Pi Edition |
| [minecraft-linux/mcpelauncher-core](https://github.com/minecraft-linux/mcpelauncher-core/blob/6b5e17b5685a612143297ae4595bdd12327284f3/src/patch_utils.cpp#L42) | Original Function Overwrite Code |
| [Hooking C Functions at Runtime - Thomas Finch](http://thomasfinch.me/blog/2015/07/24/Hooking-C-Functions-At-Runtime.html) | Original Patching Code |
| [ReMinecraftPE](https://github.com/ReMinecraftPE/mcpe) | A Lot Of Decompiled Code |

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,17 +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.
### Docker Image
An official Docker image is also provided: [thebrokenrail/minecraft-pi-reborn-server](https://hub.docker.com/r/thebrokenrail/minecraft-pi-reborn-server).
To use, run the normal AppImage with the `--server` argument. 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
* Survival Mode servers are incompatible with un-modded MCPI
[^1]: The exception to this is buckets and other modded items, those will crash MCPE players.

70
docs/GETTING_STARTED.md Normal file
View File

@ -0,0 +1,70 @@
---
gitea: none
include_toc: true
---
# Getting Started
Welcome to the official guide for setting up Minecraft: Pi Edition: Reborn (also known as MCPI-Reborn)! This document will help you through the installation and setup process.
## System Requirements
MCPI-Reborn requires support for OpenGL ES v2.0 (unlike the original game, which used OpenGL ES v1.1). It also only supports Linux-based systems.
In addition, while the original game could only be run on the Raspberry Pi, MCPI-Reborn is much more flexible. It supports running on 32-bit ARM (known as `armhf`), 64-bit ARM (known as `arm64`), and 64-bit x86 (known as `amd64`).
## Installation
There are three supported ways to install MCPI-Reborn.
### AppImage
The first supported way to install MCPI-Reborn is with an [AppImage](https://appimage.org). An AppImage is a portable application format that allows users to run software without installation.
To run MCPI-Reborn, all you need to do is [download the latest AppImage](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases/latest) for your architecture and run it.
More details can be found [here](https://docs.appimage.org/introduction/quickstart.html#how-to-run-an-appimage).
<details>
<summary><b>Additional System Requirements</b></summary>
The AppImage requires Debian Bullseye or higher. This is equivalent to Ubuntu 20.04.
It also requires some additional packages. To install them, run:
```sh
sudo apt install -y libopenal1 libglib2.0-0
```
</details>
### Flatpak
The next method is the official [Flatpak](https://www.flatpak.org/). This method has the additional benefit of built-in sandboxing. Unfortunately, it does not support 32-bit ARM systems.
It can be installed through [Flathub](https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn).
### Pi-Apps
The final supported method is [Pi-Apps](https://github.com/Botspot/pi-apps). It is a ["well-maintained collection of app installation-scripts"](https://github.com/Botspot/pi-apps#:~:text=well-maintained%20collection%20of%20app%20installation-scripts) that includes support for MCPI-Reborn.
The list of systems supported by Pi-Apps can be found [here](https://github.com/Botspot/pi-apps?tab=readme-ov-file#supported-systems).
## Managing Game Data
Just as regular Minecraft stores game data at `~/.minecraft`, MCPI-Reborn uses `~/.minecraft-pi`[^1]. This is the profile directory and is where your worlds, screenshots, and game settings are stored.
The profile directory can easily be accessed by opening MCPI-Reborn and going to `Options -> Reborn -> Profile Directory`.
## Sound
One of MCPI-Reborn's most important modifications is the addition of a sound engine. However, due to copyright limitations, Minecraft's sounds cannot be distributed with MCPI-Reborn and must be installed manually.
Fortunately, installing the sound data is simple:
1. Obtain a valid Minecraft: Pocket Edition v0.6.1[^2] APK file.
2. Extract `lib/*/libminecraftpe.so` from the APK.
3. Create the directory `<Profile Directory>/overrides` if it does not already exist.
4. Copy `libminecraftpe.so` into `<Profile Directory>/overrides`.
5. Sound should now be fully functional!
## Custom Textures
MCPI-Reborn allows users to easily use custom textures through the use of an "overrides directory." Any files placed in this directory will automatically replace their equivalent file in MCPI-Reborn.
For instance, to override `data/images/terrain.png`, you would copy the replacement file to `<Overrides Folder>/images/terrain.png`.
The overrides directory is located at `<Profile Directory>/overrides`.
## Discord
If you have any questions or just want to talk about Minecraft: Pi Edition, there is an [official Discord server](https://discord.com/invite/aDqejQGMMy)!
[^1]: When using the Flatpak, the profile directory is located at `~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi`.
[^2]: This is not a strict requirement; a Minecraft: Pocket Edition v0.8.1 APK would likely work, but it is not guaranteed.

View File

@ -1,36 +0,0 @@
# Manual Installation
[Download Packages Here](https://jenkins.thebrokenrail.com/job/minecraft-pi-reborn/job/master/lastSuccessfulBuild/artifact/out/)
## Picking A Package
### Name Format
```
minecraft-pi-reborn-<Variant>_X.Y.Z_<Architecture>
```
### 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
### 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
### Download and Install the app
Download with your favourite browser. You can run it directly from your Downloads folder, but for long-term use, and for use by multiple users, it's preferable to move the file to /opt. Open the Terminal (often Accessories-> Terminal, or CTRL+T) and enter:
```
sudo mv Downloads/minecraft-pi-reborn-client-2.3.4-arm64.AppImage /opt/
```
(replacing Downloads/minecraft-pi-reborn-client-2.3.4-arm64.AppImage with the file you downloaded).
To run, the file must be executable:
```
sudo chmod a+x /opt/minecraft-pi-reborn-client-2.3.4-arm64.AppImage
```
### Run the app
Enter the name of the AppImage to run, e.g.:
```
/opt/minecraft-pi-reborn-client-2.3.4-arm64.AppImage
```

View File

@ -1,16 +0,0 @@
# Multiplayer
MCPI-Reborn supports two ways to play multiplayer.
## Local Network (LAN)
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.
### Example ``~/.minecraft-pi/servers.txt``
```
# Default Port Is 19132
example.com
# Custom Port
example.com:19133
```

View File

@ -1,6 +0,0 @@
# 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``.
## Examples
- ``data/images/terrain.png`` -> ``~/.minecraft-pi/overrides/images/terrain.png``
- ``data/lang/en_US.lang`` -> ``~/.minecraft-pi/overrides/lang/en_US.lang``

View File

@ -1,12 +1,8 @@
# Documentation
* [View Manual Installation](INSTALL.md)
* [View Overriding Assets](OVERRIDING_ASSETS.md)
* [View Getting Started](GETTING_STARTED.md)
* [View Dedicated Server](DEDICATED_SERVER.md)
* [View Credits](CREDITS.md)
* [View Terminology](TERMINOLOGY.md)
* [View Building](BUILDING.md)
* [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)

View File

@ -1,7 +0,0 @@
# Sound
One of MCPI-Reborn's main modifications is a sound-engine since MCPI doesn't include one by default[^1]. However, it can't be used out-of-box because MCPI doesn't 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` and you should have sound!
[^1]: The mute button is just leftover code from MCPE, it doesn't actually do anything in un-modded MCPI, however it is connected to MCPI-Reborn's sound-engine.
[^2]: This isn't a hard limit, an MCPE v0.8.1 APK would probably work, but don't rely on it.

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

@ -0,0 +1,11 @@
# Example Mods
These are example mods 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 a chat message starting with `/` 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` whenever MCPI-Reborn is started.

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/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,45 @@
#include <libreborn/patch.h>
#include <libreborn/util/util.h>
#include <libreborn/util/string.h>
#include <symbols/minecraft.h>
#include <mods/chat/chat.h>
#include <mods/misc/misc.h>
#include <mods/server/server.h>
// The Actual Mod
HOOK(chat_handle_packet_send, void, (const Minecraft *minecraft, ChatPacket *packet)) {
// Get Message
const char *message = packet->message.c_str();
if (message[0] == '/') {
// API Command
Minecraft *mc = (Minecraft *) minecraft;
Gui *gui = &mc->gui;
std::string out = chat_send_api_command(mc, (char *) &message[1]);
if (out.length() > 0 && out[out.length() - 1] == '\n') {
out[out.length() - 1] = '\0';
}
std::string cp437_out = to_cp437(out);
gui->addMessage(cp437_out);
} else {
// Call Original Method
real_chat_handle_packet_send()(minecraft, packet);
}
}
// Add Server Command
HOOK(server_get_commands, std::vector<ServerCommand> *, (Minecraft *minecraft, ServerSideNetworkHandler *server_side_network_handler)) {
// Call Original Method
std::vector<ServerCommand> *commands = real_server_get_commands()(minecraft, server_side_network_handler);
// Add Command
commands->push_back({
.name = "greet",
.comment = "Example Custom Command",
.callback = [](__attribute__((unused)) const std::string &cmd) {
INFO("Hello World!");
}
});
// Return
return commands;
}

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

View File

@ -0,0 +1,65 @@
#include <libreborn/patch.h>
#include <symbols/minecraft.h>
#include <mods/misc/misc.h>
// Custom Crafting Recipes
#define SAND 12
static void Recipes_injection(Recipes *recipes) {
// Add
Recipes_Type type1 = {
.item = 0,
.tile = 0,
.instance = {
.count = 1,
.id = SAND,
.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(result, types);
}
// Custom Furnace Recipes
static void FurnaceRecipes_injection(FurnaceRecipes *recipes) {
// Add
ItemInstance result = {
.count = 1,
.id = 246,
.auxiliary = 0
};
recipes->addFurnaceRecipe(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);
// Recipe Remainder
overwrite_calls(Minecraft_init, [](Minecraft_init_t original, Minecraft *self) {
original(self);
Item::items[SAND]->craftingRemainingItem = Item::snowball;
});
}

38
images/CMakeLists.txt Normal file
View File

@ -0,0 +1,38 @@
project(images)
# Logo
install(
FILES "modern_logo.png"
DESTINATION "${MCPI_INSTALL_DIR}/data/images/gui"
)
# Title Background
install(
FILES "background.png"
DESTINATION "${MCPI_INSTALL_DIR}/data/images/gui"
RENAME "titleBG.png"
)
# Mojang Textures
install(
FILES "mojang/chest.png"
DESTINATION "${MCPI_INSTALL_DIR}/data/images/item"
)
install(
FILES "mojang/shadow.png" "mojang/vignette.png" "mojang/grasscolor.png"
DESTINATION "${MCPI_INSTALL_DIR}/data/images/misc"
)
# Icon
set(ICON_DIR "${MCPI_SHARE_DIR}/icons/hicolor/512x512/apps")
install(
FILES "icon.png"
DESTINATION "${ICON_DIR}"
RENAME "${MCPI_APP_ID}.png"
)
# AppImage
if(MCPI_IS_APPIMAGE_BUILD)
install_symlink("${ICON_DIR}/${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: 139 KiB

BIN
images/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
images/modern_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
images/mojang/chest.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
images/mojang/shadow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 B

BIN
images/mojang/vignette.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 133 KiB

View File

@ -1,32 +1,123 @@
project(launcher)
# Launcher
if(BUILD_NATIVE_COMPONENTS)
add_executable(launcher src/bootstrap.c src/patchelf.c)
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-util)
add_executable(launcher
src/bootstrap/bootstrap.cpp
src/bootstrap/mods.cpp
src/bootstrap/assets.cpp
src/bootstrap/patchelf.cpp
src/bootstrap/debug.cpp
src/util/util.cpp
src/util/sdk.cpp
src/util/env.cpp
src/logger/logger.cpp
src/logger/crash-report.cpp
src/options/parser.cpp
src/main.cpp
src/ui/frame.cpp
src/ui/color.cpp
src/client/configuration.cpp
src/client/cache.cpp
src/client/ui.cpp
src/updater/updater.cpp
)
target_link_libraries(launcher
reborn-util
LIB_LIEF
imgui
trampoline-headers
pthread
)
# RPath
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
target_link_options(launcher PRIVATE "LINKER:--disable-new-dtags")
# Files
target_compile_definitions(launcher PRIVATE _FILE_OFFSET_BITS=64)
# Install
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")
install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_VARIANT_NAME}")
set(ICON_PATH "data/com.thebrokenrail.MCPIReborn.png")
set(ICON_TARGET_PATH "share/icons/hicolor/scalable/apps")
if(NOT MCPI_SERVER_MODE)
install(DIRECTORY "data/client/" DESTINATION ".")
install(
FILES "${ICON_PATH}"
DESTINATION "${ICON_TARGET_PATH}"
RENAME "com.thebrokenrail.MCPIRebornClient.png"
install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_APP_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_APP_NAME}\n"
"Type=Application\n"
"Categories=Game;\n"
"Terminal=false\n"
"StartupNotify=false\n"
"StartupWMClass=${MCPI_APP_ID}\n"
)
else()
install(DIRECTORY "data/server/" DESTINATION ".")
install(
FILES "${ICON_PATH}"
DESTINATION "${ICON_TARGET_PATH}"
RENAME "com.thebrokenrail.MCPIRebornServer.png"
FILES "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
DESTINATION "${MCPI_SHARE_DIR}/applications"
RENAME "${MCPI_APP_ID}.desktop"
)
endif()
# 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\">${MCPI_REPO}</url>\n"
" <launchable type=\"desktop-id\">${MCPI_APP_ID}.desktop</launchable>\n"
" <provides>\n"
" <id>${MCPI_APP_ID}.desktop</id>\n"
" </provides>\n"
" <project_license>LicenseRef-proprietary</project_license>\n"
" <developer_name>${MCPI_AUTHOR} &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"
" <screenshots>\n"
" <screenshot type=\"default\">\n"
" <image>${MCPI_REPO}/raw/branch/master/images/start.png</image>\n"
" </screenshot>\n"
" </screenshots>\n"
"</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_APP_NAME}" "AppRun")
install_symlink("${MCPI_SHARE_DIR}/applications/${MCPI_APP_ID}.desktop" "${MCPI_APP_ID}.desktop")
# Updater
target_sources(launcher PRIVATE src/updater/appimage.cpp)
endif()

View File

@ -1,35 +0,0 @@
TRUE 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 Inventory
FALSE Remove Creative Mode Restrictions
TRUE Animated Water
TRUE Remove Invalid Item Background
TRUE Disable "gui_blocks" Atlas
FALSE 3D Anaglyph
TRUE Fix Camera Rendering
TRUE Implement Chat
FALSE Hide Chat Messages
TRUE Implement Death Messages
TRUE Implement Game-Mode Switching
TRUE Allow Joining Survival 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
FALSE Disable V-Sync
TRUE Fix Options Screen
FALSE Force Touch Inventory
TRUE Fix Pause Menu

View File

@ -1,10 +0,0 @@
[Desktop Entry]
Name=Minecraft: Pi Edition: Reborn (Client)
Comment=Fun with Blocks
Icon=com.thebrokenrail.MCPIRebornClient
StartupNotify=false
StartupWMClass=Minecraft: Pi Edition: Reborn
Exec=minecraft-pi-reborn-client
Terminal=false
Type=Application
Categories=Game;

View File

@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>com.thebrokenrail.MCPIRebornClient</id>
<name>Minecraft: Pi Edition: Reborn (Client)</name>
<metadata_license>CC0-1.0</metadata_license>
<summary>Fun with Blocks</summary>
<description><p>Minecraft: Pi Edition Modding Project.</p><p>NOTE: This is not verified by, affiliated with, or supported by Mojang or Microsoft.</p></description>
<url type="homepage">https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn</url>
<screenshots>
<screenshot type="default">
<image>https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn/raw/branch/master/images/start.png</image>
</screenshot>
</screenshots>
<launchable type="desktop-id">com.thebrokenrail.MCPIRebornClient.desktop</launchable>
<provides>
<id>com.thebrokenrail.MCPIRebornClient.desktop</id>
</provides>
<project_license>LicenseRef-proprietary</project_license>
<developer_name>TheBrokenRail &amp; Mojang AB</developer_name>
<content_rating type="oars-1.0">
<content_attribute id="violence-cartoon">moderate</content_attribute>
<content_attribute id="violence-fantasy">none</content_attribute>
<content_attribute id="violence-realistic">none</content_attribute>
<content_attribute id="violence-bloodshed">none</content_attribute>
<content_attribute id="violence-sexual">none</content_attribute>
<content_attribute id="drugs-alcohol">none</content_attribute>
<content_attribute id="drugs-narcotics">none</content_attribute>
<content_attribute id="drugs-tobacco">none</content_attribute>
<content_attribute id="sex-nudity">none</content_attribute>
<content_attribute id="sex-themes">none</content_attribute>
<content_attribute id="language-profanity">none</content_attribute>
<content_attribute id="language-humor">none</content_attribute>
<content_attribute id="language-discrimination">none</content_attribute>
<content_attribute id="social-chat">intense</content_attribute>
<content_attribute id="social-info">none</content_attribute>
<content_attribute id="social-audio">none</content_attribute>
<content_attribute id="social-location">none</content_attribute>
<content_attribute id="social-contacts">none</content_attribute>
<content_attribute id="money-purchasing">none</content_attribute>
<content_attribute id="money-gambling">none</content_attribute>
</content_rating>
</component>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

View File

@ -1,9 +0,0 @@
[Desktop Entry]
Name=Minecraft: Pi Edition: Reborn (Server)
Comment=Fun with Blocks
Icon=com.thebrokenrail.MCPIRebornServer
Exec=minecraft-pi-reborn-server
Terminal=true
Type=Application
Categories=Game;
NoDisplay=true

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>com.thebrokenrail.MCPIRebornServer</id>
<name>Minecraft: Pi Edition: Reborn (Server)</name>
<metadata_license>CC0-1.0</metadata_license>
<summary>Fun with Blocks</summary>
<description><p>Minecraft: Pi Edition Modding Project.</p><p>NOTE: This is not verified by, affiliated with, or supported by Mojang or Microsoft.</p></description>
<url type="homepage">https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn</url>
<launchable type="desktop-id">com.thebrokenrail.MCPIRebornServer.desktop</launchable>
<provides>
<id>com.thebrokenrail.MCPIRebornServer.desktop</id>
</provides>
<project_license>LicenseRef-proprietary</project_license>
<developer_name>TheBrokenRail &amp; Mojang AB</developer_name>
<content_rating type="oars-1.0">
<content_attribute id="violence-cartoon">moderate</content_attribute>
<content_attribute id="violence-fantasy">none</content_attribute>
<content_attribute id="violence-realistic">none</content_attribute>
<content_attribute id="violence-bloodshed">none</content_attribute>
<content_attribute id="violence-sexual">none</content_attribute>
<content_attribute id="drugs-alcohol">none</content_attribute>
<content_attribute id="drugs-narcotics">none</content_attribute>
<content_attribute id="drugs-tobacco">none</content_attribute>
<content_attribute id="sex-nudity">none</content_attribute>
<content_attribute id="sex-themes">none</content_attribute>
<content_attribute id="language-profanity">none</content_attribute>
<content_attribute id="language-humor">none</content_attribute>
<content_attribute id="language-discrimination">none</content_attribute>
<content_attribute id="social-chat">intense</content_attribute>
<content_attribute id="social-info">none</content_attribute>
<content_attribute id="social-audio">none</content_attribute>
<content_attribute id="social-location">none</content_attribute>
<content_attribute id="social-contacts">none</content_attribute>
<content_attribute id="money-purchasing">none</content_attribute>
<content_attribute id="money-gambling">none</content_attribute>
</content_rating>
</component>

View File

@ -1,355 +0,0 @@
#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 "bootstrap.h"
#include "patchelf.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); \
} \
}
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];
}
}
void set_and_print_env(const char *name, char *value) {
// Set Variable With No Trailing Colon
static const char *unmodified_name_prefix = "MCPI_";
if (!starts_with(name, unmodified_name_prefix)) {
trim(&value);
}
// Print New Value
DEBUG("Set %s = %s", name, value);
// Set The Value
setenv(name, value, 1);
}
#ifndef __ARM_ARCH
#define PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU(name) \
{ \
char *old_value = getenv("QEMU_SET_ENV"); \
char *new_value = NULL; \
/* Pass Variable */ \
safe_asprintf(&new_value, "%s%s%s=%s", old_value == NULL ? "" : old_value, old_value == NULL ? "" : ",", name, getenv(name)); \
setenv("QEMU_SET_ENV", new_value, 1); \
free(new_value); \
/* Reset Variable */ \
RESET_ENVIRONMENTAL_VARIABLE(name); \
}
#endif
// 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 : "";
}
// 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];
// 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));
}
}
}
#define MCPI_BINARY "minecraft-pi"
#define QEMU_BINARY "qemu-arm"
// Pre-Bootstrap
void pre_bootstrap() {
// GTK Dark Mode
#ifndef MCPI_HEADLESS_MODE
set_and_print_env("GTK_THEME", "Adwaita:dark");
#endif
// 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
// Get Binary Directory
char *binary_directory = get_binary_directory();
// Configure PATH
{
// Add Library Directory
char *new_path;
safe_asprintf(&new_path, "%s/bin", binary_directory);
// Add Existing PATH
{
char *value = get_env_safe("PATH");
if (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);
}
// Bootstrap
void bootstrap(int argc, char *argv[]) {
INFO("Configuring Game...");
// Get Binary Directory
char *binary_directory = get_binary_directory();
// Handle AppImage
char *usr_prefix = NULL;
#ifdef MCPI_IS_APPIMAGE_BUILD
usr_prefix = getenv("APPDIR");
#endif
if (usr_prefix == NULL) {
usr_prefix = "";
}
// Resolve Binary Path & Set MCPI_DIRECTORY
{
// Log
DEBUG("Resolving File Paths...");
// Resolve Full Binary Path
char *full_path = NULL;
safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory);
char *resolved_path = realpath(full_path, NULL);
ALLOC_CHECK(resolved_path);
free(full_path);
// Set MCPI_EXECUTABLE_PATH
set_and_print_env("MCPI_EXECUTABLE_PATH", resolved_path);
// Set MCPI_DIRECTORY
chop_last_component(&resolved_path);
set_and_print_env("MCPI_DIRECTORY", resolved_path);
free(resolved_path);
}
// Fix MCPI Dependencies
{
// Log
DEBUG("Patching ELF Dependencies...");
// Find Linker
char *linker = NULL;
// Preserve Existing Linker On ARM
#ifndef __arm__
safe_asprintf(&linker, "%s/usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3", usr_prefix);
#endif
// Patch
patch_mcpi_elf_dependencies(linker);
// Free Linker Path
if (linker != NULL) {
free(linker);
}
// Verify
if (!starts_with(getenv("MCPI_EXECUTABLE_PATH"), "/tmp")) {
IMPOSSIBLE();
}
}
// AppImage
#ifdef MCPI_IS_APPIMAGE_BUILD
// Mark Patched MCPI As Part Of AppImage
set_and_print_env("APPDIR_MODULE_DIR", getenv("MCPI_EXECUTABLE_PATH"));
#endif
// Configure LD_LIBRARY_PATH
{
// Log
DEBUG("Setting Linker Search Paths...");
// Preserve
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH");
char *new_ld_path = NULL;
// Add Library Directory
safe_asprintf(&new_ld_path, "%s/lib", binary_directory);
// Load ARM Libraries (Ensure Priority)
string_append(&new_ld_path, ":%s/usr/lib/arm-linux-gnueabihf:%s/usr/arm-linux-gnueabihf/lib", usr_prefix, usr_prefix);
// Add LD_LIBRARY_PATH
{
char *value = get_env_safe("LD_LIBRARY_PATH");
if (strlen(value) > 0) {
string_append(&new_ld_path, ":%s", value);
}
}
// Set And Free
set_and_print_env("LD_LIBRARY_PATH", new_ld_path);
free(new_ld_path);
}
// Configure LD_PRELOAD
{
// Log
DEBUG("Locating Mods...");
// Preserve
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_PRELOAD");
char *new_ld_preload = NULL;
// Built-In Mods
{
// 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);
}
// ~/.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(&new_ld_preload, mods_folder);
// Free Mods Folder
free(mods_folder);
}
// Add LD_PRELOAD
{
char *value = get_env_safe("LD_PRELOAD");
if (strlen(value) > 0) {
string_append(&new_ld_preload, ":%s", value);
}
}
// Set LD_PRELOAD
set_and_print_env("LD_PRELOAD", new_ld_preload);
free(new_ld_preload);
}
// Free Binary Directory
free(binary_directory);
// Start Game
INFO("Starting Game...");
// 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 */]; //
// Copy Existing Arguments
for (int i = 1; i < argc; i++) {
new_args[i + argv_start] = argv[i];
}
// NULL-Terminator
new_args[argv_start + argc] = NULL;
// Set Executable Argument
new_args[argv_start] = getenv("MCPI_EXECUTABLE_PATH");
// Non-ARM Systems Need QEMU
#ifndef __ARM_ARCH
argv_start--;
new_args[argv_start] = QEMU_BINARY;
// Prevent QEMU From Being Modded
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_LIBRARY_PATH");
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_PRELOAD");
#endif
// Run
const char **new_argv = &new_args[argv_start];
safe_execvpe(new_argv, (const char *const *) environ);
}

View File

@ -1,14 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void set_and_print_env(const char *name, char *value);
void pre_bootstrap();
void bootstrap(int argc, char *argv[]);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,15 @@
#include <libreborn/env/env.h>
#include "bootstrap.h"
#include "../util/util.h"
// Setup Asset Paths
static void setup_path(const char *env_name, std::string assets_path) {
chop_last_component(assets_path);
assets_path += "/data";
set_and_print_env(env_name, assets_path.c_str());
}
void bootstrap_assets(const std::string &original_game_binary) {
setup_path(_MCPI_REBORN_ASSETS_PATH_ENV, safe_realpath("/proc/self/exe"));
setup_path(_MCPI_VANILLA_ASSETS_PATH_ENV, original_game_binary);
}

View File

@ -0,0 +1,78 @@
#include <string>
#include <vector>
#include <libreborn/log.h>
#include <libreborn/env/env.h>
#include <libreborn/config.h>
#include <libreborn/util/exec.h>
#include "../util/util.h"
#include "bootstrap.h"
#define MCPI_BINARY "minecraft-pi"
#define REQUIRED_PAGE_SIZE 4096
// Bootstrap
void bootstrap(const options_t &options) {
// Debug Information
print_debug_information();
// Check Page Size
const long page_size = sysconf(_SC_PAGESIZE);
if (page_size != REQUIRED_PAGE_SIZE) {
CONDITIONAL_ERR(!options.skip_pagesize_check, "Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
}
// Get Binary Directory
const std::string binary_directory = get_binary_directory();
DEBUG("Binary Directory: %s", binary_directory.c_str());
// Copy SDK
if (!reborn_is_server()) {
copy_sdk(binary_directory, false);
}
// Resolve Binary Path
DEBUG("Resolving File Paths...");
std::string original_game_binary = binary_directory + ("/" MCPI_BINARY);
original_game_binary = safe_realpath(original_game_binary);
const char *custom_binary = getenv(MCPI_BINARY_ENV);
const std::string game_binary = custom_binary ? safe_realpath(custom_binary) : original_game_binary;
// Configure Preloaded Objects
DEBUG("Locating Mods...");
const std::vector<std::string> mcpi_ld_preload = bootstrap_mods(binary_directory);
// Configure Library Search Path
DEBUG("Setting Linker Search Paths...");
const std::vector<std::string> mcpi_ld_path = get_ld_path(binary_directory);
// Assets
DEBUG("Finding Assets...");
bootstrap_assets(original_game_binary);
// Patch Binary
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
DEBUG("Patching ELF...");
patch_mcpi_elf_dependencies(game_binary, new_mcpi_exe_path, get_new_linker(binary_directory), mcpi_ld_path, mcpi_ld_preload);
// Start Game
INFO("Starting Game...");
// Arguments
const std::vector<std::string> args {
#ifdef MCPI_BUILD_RUNTIME
"runtime",
#endif
new_mcpi_exe_path
};
// Run
const char *new_argv[args.size() + 1];
for (std::vector<std::string>::size_type i = 0; i < args.size(); i++) {
new_argv[i] = args[i].c_str();
}
new_argv[args.size()] = nullptr;
safe_execvpe(new_argv, environ);
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <string>
#include <vector>
#include "../options/parser.h"
#define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched"
void bootstrap(const options_t &options);
// Debugging
void print_debug_information();
// Mods
std::vector<std::string> bootstrap_mods(const std::string &binary_directory);
// Assets
void bootstrap_assets(const std::string &original_game_binary);
// ELF
std::string get_new_linker(const std::string &binary_directory);
std::vector<std::string> get_ld_path(const std::string &binary_directory);
void patch_mcpi_elf_dependencies(const std::string &original_path, char *new_path, const std::string &interpreter, const std::vector<std::string> &rpath, const std::vector<std::string> &mods);

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