Compare commits

...

118 Commits

Author SHA1 Message Date
TheBrokenRail 56d93f0150 Tweak Text Wrapping
CI / Build (AMD64, Server) (push) Successful in 13m17s Details
CI / Build (AMD64, Client) (push) Successful in 13m39s Details
CI / Build (ARM64, Server) (push) Successful in 13m37s Details
CI / Build (ARM64, Client) (push) Successful in 16m16s Details
CI / Build (ARMHF, Server) (push) Successful in 9m25s Details
CI / Build (ARMHF, Client) (push) Successful in 12m21s Details
CI / Test (Server) (push) Successful in 15m8s Details
CI / Test (Client) (push) Successful in 16m28s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 8m3s Details
2024-05-19 00:19:01 -04:00
TheBrokenRail 3132f9442d Better Error Message 2024-05-18 21:25:11 -04:00
TheBrokenRail b129f0a503 Attack Of The Templates!
CI / Build (AMD64, Server) (push) Successful in 13m3s Details
CI / Build (AMD64, Client) (push) Successful in 13m21s Details
CI / Build (ARM64, Server) (push) Successful in 13m52s Details
CI / Build (ARM64, Client) (push) Successful in 16m29s Details
CI / Build (ARMHF, Server) (push) Successful in 9m26s Details
CI / Build (ARMHF, Client) (push) Successful in 12m33s Details
CI / Test (Server) (push) Successful in 14m51s Details
CI / Test (Client) (push) Successful in 16m35s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 8m26s Details
2024-05-18 18:58:39 -04:00
TheBrokenRail 97bc124d72 Better Static Properties
CI / Build (AMD64, Server) (push) Successful in 14m16s Details
CI / Build (AMD64, Client) (push) Successful in 14m37s Details
CI / Build (ARM64, Server) (push) Successful in 13m0s Details
CI / Build (ARM64, Client) (push) Successful in 15m26s Details
CI / Build (ARMHF, Server) (push) Successful in 8m58s Details
CI / Build (ARMHF, Client) (push) Successful in 11m38s Details
CI / Test (Server) (push) Successful in 14m12s Details
CI / Test (Client) (push) Successful in 16m37s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m50s Details
2024-05-17 02:52:55 -04:00
TheBrokenRail b23f7f1618 Remove alloc_*() Functions 2024-05-17 00:36:28 -04:00
TheBrokenRail bbaa69edeb Tweak Reborn Info Screen
CI / Build (AMD64, Server) (push) Successful in 13m2s Details
CI / Build (AMD64, Client) (push) Successful in 13m22s Details
CI / Build (ARM64, Server) (push) Successful in 13m18s Details
CI / Build (ARM64, Client) (push) Successful in 15m57s Details
CI / Build (ARMHF, Server) (push) Successful in 9m11s Details
CI / Build (ARMHF, Client) (push) Successful in 12m14s Details
CI / Test (Server) (push) Successful in 14m14s Details
CI / Test (Client) (push) Successful in 16m5s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m55s Details
2024-05-16 21:59:51 -04:00
TheBrokenRail 6cfc1a7e20 Small Tweaks
CI / Build (AMD64, Server) (push) Successful in 12m46s Details
CI / Build (AMD64, Client) (push) Successful in 13m3s Details
CI / Build (ARM64, Server) (push) Successful in 13m8s Details
CI / Build (ARM64, Client) (push) Successful in 15m26s Details
CI / Build (ARMHF, Server) (push) Successful in 9m10s Details
CI / Build (ARMHF, Client) (push) Successful in 11m55s Details
CI / Test (Server) (push) Successful in 14m0s Details
CI / Test (Client) (push) Successful in 16m6s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m55s Details
2024-05-16 04:07:02 -04:00
TheBrokenRail f25a2adcef Update More Methods!
CI / Build (AMD64, Server) (push) Successful in 12m47s Details
CI / Build (AMD64, Client) (push) Successful in 13m7s Details
CI / Build (ARM64, Server) (push) Successful in 13m7s Details
CI / Build (ARM64, Client) (push) Successful in 15m38s Details
CI / Build (ARMHF, Server) (push) Successful in 9m9s Details
CI / Build (ARMHF, Client) (push) Successful in 11m46s Details
CI / Test (Server) (push) Successful in 14m4s Details
CI / Test (Client) (push) Successful in 16m33s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m55s Details
2024-05-15 05:08:39 -04:00
TheBrokenRail 6ae475785e Fix Newlines 2024-05-15 05:06:36 -04:00
TheBrokenRail 51bbad15f4 Use New Method Call Style
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Client) (push) Has been cancelled Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
2024-05-15 05:02:19 -04:00
TheBrokenRail 73454adc22 Refactor Logging
CI / Build (AMD64, Server) (push) Successful in 12m31s Details
CI / Build (AMD64, Client) (push) Successful in 12m51s Details
CI / Build (ARM64, Server) (push) Successful in 13m2s Details
CI / Build (ARM64, Client) (push) Successful in 15m33s Details
CI / Build (ARMHF, Server) (push) Successful in 9m14s Details
CI / Build (ARMHF, Client) (push) Successful in 12m4s Details
CI / Test (Server) (push) Successful in 14m15s Details
CI / Test (Client) (push) Successful in 16m20s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 8m6s Details
2024-05-14 01:23:16 -04:00
TheBrokenRail 4d54a9d28c Refactor Launcher
CI / Build (AMD64, Server) (push) Successful in 13m26s Details
CI / Build (AMD64, Client) (push) Successful in 13m45s Details
CI / Build (ARM64, Server) (push) Successful in 14m6s Details
CI / Build (ARM64, Client) (push) Successful in 16m50s Details
CI / Build (ARMHF, Server) (push) Successful in 9m35s Details
CI / Build (ARMHF, Client) (push) Successful in 12m27s Details
CI / Test (Server) (push) Successful in 15m7s Details
CI / Test (Client) (push) Successful in 16m38s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Failing after 8m12s Details
2024-05-12 03:19:01 -04:00
TheBrokenRail d7616419bc Fix Server Build
CI / Build (AMD64, Client) (push) Successful in 13m1s Details
CI / Build (AMD64, Server) (push) Successful in 13m30s Details
CI / Build (ARM64, Server) (push) Successful in 14m22s Details
CI / Build (ARM64, Client) (push) Successful in 15m26s Details
CI / Build (ARMHF, Server) (push) Successful in 9m40s Details
CI / Build (ARMHF, Client) (push) Successful in 12m59s Details
CI / Test (Client) (push) Successful in 16m15s Details
CI / Test (Server) (push) Successful in 13m38s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 8m16s Details
2024-05-11 22:06:37 -04:00
TheBrokenRail 823495a811 Fix QEMU Build
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Server) (push) Failing after 8m0s Details
CI / Build (AMD64, Client) (push) Successful in 12m20s Details
CI / Build (ARM64, Server) (push) Failing after 8m36s Details
CI / Build (ARM64, Client) (push) Successful in 13m48s Details
CI / Build (ARMHF, Client) (push) Has been cancelled Details
CI / Build (ARMHF, Server) (push) Has been cancelled Details
2024-05-11 21:43:28 -04:00
TheBrokenRail 03c7c50d48 Trampoline
CI / Build (AMD64, Server) (push) Failing after 7m39s Details
CI / Build (AMD64, Client) (push) Failing after 11m40s Details
CI / Build (ARM64, Server) (push) Failing after 8m50s Details
CI / Build (ARM64, Client) (push) Failing after 13m21s Details
CI / Build (ARMHF, Client) (push) Has been cancelled Details
CI / Build (ARMHF, Server) (push) Has been cancelled Details
CI / Test (Client) (push) Has been cancelled Details
CI / Test (Server) (push) Has been cancelled Details
CI / Build Example Mods (push) Has been cancelled Details
CI / Release (push) Has been cancelled Details
2024-05-11 21:14:14 -04:00
TheBrokenRail f15625ff79 UI Tweaks 2024-05-10 19:50:28 -04:00
TheBrokenRail e2d32cad21 Add QEMU Patch 2024-05-10 18:58:39 -04:00
TheBrokenRail eeef63d9ef Improve Creative Restrictions Mod
CI / Build (AMD64, Server) (push) Successful in 13m26s Details
CI / Build (AMD64, Client) (push) Successful in 13m47s Details
CI / Build (ARM64, Server) (push) Successful in 13m36s Details
CI / Build (ARM64, Client) (push) Successful in 14m0s Details
CI / Build (ARMHF, Server) (push) Successful in 9m34s Details
CI / Build (ARMHF, Client) (push) Successful in 12m46s Details
CI / Test (Client) (push) Successful in 15m57s Details
CI / Test (Server) (push) Successful in 13m22s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 8m19s Details
2024-05-09 19:03:48 -04:00
TheBrokenRail e1f0787e48 Fix Layering Iverwrites 2024-05-09 17:50:02 -04:00
TheBrokenRail 37e1abbdd3 Fix Splash Animation
CI / Build (AMD64, Server) (push) Successful in 13m6s Details
CI / Build (AMD64, Client) (push) Successful in 13m29s Details
CI / Build (ARM64, Server) (push) Successful in 13m22s Details
CI / Build (ARM64, Client) (push) Successful in 14m9s Details
CI / Build (ARMHF, Server) (push) Successful in 9m25s Details
CI / Build (ARMHF, Client) (push) Successful in 12m41s Details
CI / Test (Client) (push) Successful in 16m6s Details
CI / Test (Server) (push) Successful in 13m40s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m59s Details
2024-05-09 04:19:08 -04:00
TheBrokenRail c88db307d7 Reduce Code Duplication
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Client) (push) Has been cancelled Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
2024-05-09 02:55:30 -04:00
TheBrokenRail 75fc48da24 One Last Fix
CI / Build (AMD64, Server) (push) Successful in 13m34s Details
CI / Build (AMD64, Client) (push) Successful in 14m8s Details
CI / Build (ARM64, Client) (push) Successful in 13m53s Details
CI / Build (ARM64, Server) (push) Successful in 13m32s Details
CI / Build (ARMHF, Server) (push) Successful in 9m24s Details
CI / Build (ARMHF, Client) (push) Successful in 12m37s Details
CI / Test (Client) (push) Successful in 16m0s Details
CI / Test (Server) (push) Successful in 13m24s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 8m1s Details
2024-05-09 02:20:09 -04:00
TheBrokenRail cd39733177 Update Changelog & Fix Flatpak Detection In Info Screen
CI / Build (AMD64, Client) (push) Has been cancelled Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
CI / Build (ARM64, Client) (push) Has been cancelled Details
CI / Build (ARM64, Server) (push) Has been cancelled Details
CI / Build (ARMHF, Client) (push) Has been cancelled Details
CI / Build (ARMHF, Server) (push) Has been cancelled Details
CI / Test (Client) (push) Has been cancelled Details
CI / Test (Server) (push) Has been cancelled Details
CI / Build Example Mods (push) Has been cancelled Details
CI / Release (push) Has been cancelled Details
2024-05-09 02:06:24 -04:00
TheBrokenRail 592d6c4e63 Simplify CMake
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Server) (push) Successful in 13m53s Details
CI / Build (AMD64, Client) (push) Successful in 14m25s Details
CI / Build (ARM64, Client) (push) Has been cancelled Details
CI / Build (ARM64, Server) (push) Has been cancelled Details
2024-05-09 01:38:57 -04:00
TheBrokenRail d519142a8a Fancy Info Screen 2024-05-09 01:25:53 -04:00
TheBrokenRail 09bae1cf3e Split Up Options Mod 2024-05-08 20:18:50 -04:00
TheBrokenRail 4523935d62 Fix Example Mod (Again)
CI / Build (AMD64, Server) (push) Successful in 12m25s Details
CI / Build (AMD64, Client) (push) Successful in 12m48s Details
CI / Build (ARM64, Server) (push) Successful in 12m48s Details
CI / Build (ARM64, Client) (push) Successful in 13m18s Details
CI / Build (ARMHF, Server) (push) Successful in 9m15s Details
CI / Build (ARMHF, Client) (push) Successful in 12m53s Details
CI / Test (Client) (push) Successful in 15m7s Details
CI / Test (Server) (push) Successful in 12m23s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m44s Details
2024-05-05 02:17:46 -04:00
Bigjango13 f3f8e342d8 More chunk symbols
CI / Build (AMD64, Server) (push) Successful in 12m46s Details
CI / Build (AMD64, Client) (push) Successful in 13m8s Details
CI / Build (ARM64, Client) (push) Successful in 13m13s Details
CI / Build (ARM64, Server) (push) Successful in 12m54s Details
CI / Build (ARMHF, Server) (push) Successful in 9m13s Details
CI / Build (ARMHF, Client) (push) Successful in 12m15s Details
CI / Test (Client) (push) Successful in 15m39s Details
CI / Test (Server) (push) Successful in 13m1s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m42s Details
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
TheBrokenRail 49a54a7396 Update Symbol Processor
CI / Build (AMD64, Client) (push) Waiting to run Details
CI / Build (AMD64, Server) (push) Waiting to run Details
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
2024-05-05 00:44:37 -04:00
TheBrokenRail a305cf9e38 More Changes!
CI / Build (AMD64, Server) (push) Successful in 12m33s Details
CI / Build (AMD64, Client) (push) Successful in 12m58s Details
CI / Build (ARM64, Server) (push) Successful in 12m56s Details
CI / Build (ARM64, Client) (push) Successful in 13m35s Details
CI / Build (ARMHF, Server) (push) Successful in 8m51s Details
CI / Build (ARMHF, Client) (push) Successful in 12m9s Details
CI / Test (Client) (push) Successful in 15m39s Details
CI / Test (Server) (push) Successful in 13m16s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m43s Details
2024-05-04 20:46:15 -04:00
TheBrokenRail cf6989bed2 I need to sleep, here be dragons
CI / Build (AMD64, Server) (push) Failing after 6m39s Details
CI / Build (AMD64, Client) (push) Successful in 10m47s Details
CI / Build (ARM64, Client) (push) Successful in 10m26s Details
CI / Build (ARM64, Server) (push) Failing after 6m43s Details
CI / Build (ARMHF, Server) (push) Failing after 6m13s Details
CI / Build (ARMHF, Client) (push) Successful in 11m13s Details
CI / Release (push) Has been skipped Details
CI / Test (Client) (push) Failing after 5m45s Details
CI / Test (Server) (push) Failing after 5m1s Details
CI / Build Example Mods (push) Failing after 8m54s Details
2024-04-03 03:19:12 -04:00
TheBrokenRail b2a7fe3eaf C++-Ification! 2024-04-02 19:22:01 -04:00
TheBrokenRail 7739fb6b9b Update Dependency
CI / Build (AMD64, Server) (push) Successful in 12m36s Details
CI / Build (AMD64, Client) (push) Successful in 12m54s Details
CI / Build (ARM64, Server) (push) Successful in 12m14s Details
CI / Build (ARM64, Client) (push) Successful in 13m19s Details
CI / Build (ARMHF, Server) (push) Successful in 8m54s Details
CI / Build (ARMHF, Client) (push) Successful in 11m59s Details
CI / Test (Server) (push) Successful in 12m52s Details
CI / Test (Client) (push) Successful in 15m10s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m32s Details
2024-04-02 15:21:35 -04:00
TheBrokenRail f3755387e8 Improve Mouse Sensitivity On Wayland
CI / Build (AMD64, Server) (push) Successful in 12m9s Details
CI / Build (AMD64, Client) (push) Successful in 12m20s Details
CI / Build (ARM64, Server) (push) Successful in 12m35s Details
CI / Build (ARM64, Client) (push) Successful in 13m4s Details
CI / Build (ARMHF, Server) (push) Successful in 8m47s Details
CI / Build (ARMHF, Client) (push) Successful in 12m6s Details
CI / Test (Client) (push) Successful in 14m25s Details
CI / Test (Server) (push) Successful in 12m22s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m31s Details
2024-03-19 00:25:50 -04:00
TheBrokenRail b1b28defd5 Small Change 2024-03-19 00:12:26 -04:00
TheBrokenRail 18c5d34974 Ignore CLion Files 2024-03-19 00:12:26 -04:00
Bigjango13 76a66a0ba5 Sneak in Level_setTileEntity
CI / Build (AMD64, Server) (push) Successful in 12m25s Details
CI / Build (AMD64, Client) (push) Successful in 12m41s Details
CI / Build (ARM64, Server) (push) Successful in 12m25s Details
CI / Build (ARM64, Client) (push) Successful in 12m56s Details
CI / Build (ARMHF, Server) (push) Successful in 8m51s Details
CI / Build (ARMHF, Client) (push) Successful in 11m57s Details
CI / Test (Client) (push) Successful in 14m36s Details
CI / Test (Server) (push) Successful in 12m32s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Failing after 7m21s Details
2024-03-18 21:02:01 -04:00
Bigjango13 a6ad1994de Remove left over check 2024-03-18 19:58:38 -04:00
Bigjango13 8de638eb1a Make chat history edits saved temporarily 2024-03-18 19:44:17 -04:00
Bigjango13 5e5088e3ef Move chat history into chat
- `get_death_message` is no longer static
- Fix ItemInHandRenderer_instance symbol
2024-03-10 22:46:34 -04:00
Bigjango13 a6e0cd8f13 Fix history editing bug
- Use the `get_<var>` pattern for chat's `history`.
- Make the Biome_map comment clearer
2024-03-09 13:01:52 -05:00
Bigjango13 3ff24c2a92 Add chat history
- More symbols too
- Made CUSTOM_VTABLE not static, for modders
2024-03-08 18:03:19 -05:00
TheBrokenRail d74d1501ce Update Sound Warning
CI / Build (AMD64, Server) (push) Successful in 12m33s Details
CI / Build (AMD64, Client) (push) Successful in 12m47s Details
CI / Build (ARM64, Server) (push) Successful in 12m35s Details
CI / Build (ARM64, Client) (push) Successful in 13m5s Details
CI / Build (ARMHF, Server) (push) Successful in 8m52s Details
CI / Build (ARMHF, Client) (push) Successful in 12m2s Details
CI / Test (Client) (push) Successful in 15m14s Details
CI / Test (Server) (push) Successful in 12m27s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m27s Details
2024-03-02 17:16:16 -05:00
TheBrokenRail fb84bcc06b GLFW 3.4!
CI / Build (AMD64, Server) (push) Successful in 12m58s Details
CI / Build (AMD64, Client) (push) Successful in 13m20s Details
CI / Build (ARM64, Server) (push) Successful in 15m3s Details
CI / Build (ARM64, Client) (push) Successful in 15m32s Details
CI / Build (ARMHF, Server) (push) Successful in 8m59s Details
CI / Build (ARMHF, Client) (push) Successful in 12m16s Details
CI / Test (Client) (push) Successful in 15m10s Details
CI / Test (Server) (push) Successful in 13m15s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m49s Details
2024-02-23 20:54:07 -05:00
TheBrokenRail 117c5d2702 Better HiDPI Support
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
CI / Build (AMD64, Client) (push) Has been cancelled Details
2024-02-23 20:50:56 -05:00
TheBrokenRail 9556d13791 Minor Tweaks
CI / Build (AMD64, Server) (push) Successful in 12m42s Details
CI / Build (AMD64, Client) (push) Successful in 12m59s Details
CI / Build (ARM64, Server) (push) Successful in 12m49s Details
CI / Build (ARM64, Client) (push) Successful in 13m21s Details
CI / Build (ARMHF, Server) (push) Successful in 9m2s Details
CI / Build (ARMHF, Client) (push) Successful in 12m23s Details
CI / Test (Client) (push) Successful in 15m37s Details
CI / Test (Server) (push) Successful in 13m6s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m43s Details
2024-02-15 23:02:44 -05:00
Bigjango13 f8bd6d380b Fix invalid ItemInHandRenderer texture cache 2024-02-15 01:59:35 -05:00
Bigjango13 5d57253d56 More symbols and better patch error message 2024-02-15 01:59:34 -05:00
Bigjango13 6ac808919f More symbols! Mostly tile entity stuff 2024-02-15 01:58:38 -05:00
Bigjango13 5353bc188d Rename Entity::aabb to Entity::hitbox 2024-02-15 01:58:38 -05:00
Bigjango13 f57c0a6190 More symbols and clean up "Disable Hostile AI In Creative Mode" 2024-02-15 01:58:38 -05:00
TheBrokenRail b033912633 Also Scan .data.rel.ro
CI / Build (AMD64, Server) (push) Successful in 12m2s Details
CI / Build (AMD64, Client) (push) Successful in 12m22s Details
CI / Build (ARM64, Server) (push) Successful in 13m4s Details
CI / Build (ARM64, Client) (push) Successful in 13m36s Details
CI / Build (ARMHF, Server) (push) Successful in 8m37s Details
CI / Build (ARMHF, Client) (push) Successful in 11m27s Details
CI / Test (Server) (push) Successful in 12m26s Details
CI / Test (Client) (push) Successful in 15m7s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 7m22s Details
2024-02-12 00:55:50 -05:00
TheBrokenRail a2b3bb128b Bug Fixes & Low-Level Improvements
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
CI / Build (AMD64, Client) (push) Has been cancelled Details
2024-02-12 00:44:38 -05:00
TheBrokenRail 180ba9dcaf Small Changes 2024-02-11 20:35:41 -05:00
TheBrokenRail 71cc24104c Add More Splashes
CI / Build (AMD64, Server) (push) Successful in 11m14s Details
CI / Build (AMD64, Client) (push) Successful in 11m30s Details
CI / Build (ARM64, Server) (push) Successful in 11m31s Details
CI / Build (ARM64, Client) (push) Successful in 11m51s Details
CI / Build (ARMHF, Server) (push) Successful in 7m54s Details
CI / Build (ARMHF, Client) (push) Successful in 11m11s Details
CI / Test (Client) (push) Successful in 14m25s Details
CI / Test (Server) (push) Successful in 11m49s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m54s Details
2024-02-08 00:59:57 -05:00
TheBrokenRail 6951ebe620 Improve Performance
CI / Build (AMD64, Server) (push) Successful in 11m15s Details
CI / Build (AMD64, Client) (push) Successful in 11m33s Details
CI / Build (ARM64, Client) (push) Successful in 11m49s Details
CI / Build (ARM64, Server) (push) Successful in 11m35s Details
CI / Build (ARMHF, Server) (push) Successful in 7m50s Details
CI / Build (ARMHF, Client) (push) Successful in 11m3s Details
CI / Test (Client) (push) Successful in 14m43s Details
CI / Test (Server) (push) Successful in 11m40s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m48s Details
2024-02-08 00:34:43 -05:00
TheBrokenRail 28dbb2eacd Some CMake Cleanup
CI / Build (AMD64, Server) (push) Successful in 12m44s Details
CI / Build (AMD64, Client) (push) Successful in 12m56s Details
CI / Build (ARM64, Server) (push) Successful in 11m40s Details
CI / Build (ARM64, Client) (push) Successful in 12m1s Details
CI / Build (ARMHF, Server) (push) Successful in 8m1s Details
CI / Build (ARMHF, Client) (push) Successful in 10m59s Details
CI / Test (Client) (push) Successful in 14m15s Details
CI / Test (Server) (push) Successful in 11m53s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m49s Details
2024-02-07 22:12:02 -05:00
TheBrokenRail d86018717e Split Splash Loading Into Own Function 2024-02-07 21:40:26 -05:00
TheBrokenRail db22caa50f Add Splash Text From MCPIL
CI / Build (AMD64, Server) (push) Successful in 11m15s Details
CI / Build (AMD64, Client) (push) Successful in 11m28s Details
CI / Build (ARM64, Client) (push) Successful in 11m48s Details
CI / Build (ARM64, Server) (push) Successful in 11m47s Details
CI / Build (ARMHF, Server) (push) Successful in 7m55s Details
CI / Build (ARMHF, Client) (push) Successful in 11m14s Details
CI / Test (Client) (push) Successful in 14m39s Details
CI / Test (Server) (push) Successful in 11m42s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m49s Details
2024-02-07 21:15:48 -05:00
TheBrokenRail ecbcfb2922 Split Up Animated Textures Into Three Flags
CI / Build (AMD64, Server) (push) Successful in 11m25s Details
CI / Build (AMD64, Client) (push) Successful in 11m46s Details
CI / Build (ARM64, Client) (push) Successful in 11m50s Details
CI / Build (ARM64, Server) (push) Successful in 11m40s Details
CI / Build (ARMHF, Server) (push) Successful in 7m56s Details
CI / Build (ARMHF, Client) (push) Successful in 11m14s Details
CI / Test (Client) (push) Successful in 14m25s Details
CI / Test (Server) (push) Successful in 11m29s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m51s Details
2024-02-07 19:00:55 -05:00
TheBrokenRail 781377005e Update Dependencies
CI / Build (AMD64, Server) (push) Successful in 11m17s Details
CI / Build (AMD64, Client) (push) Successful in 11m30s Details
CI / Build (ARM64, Server) (push) Successful in 11m36s Details
CI / Build (ARM64, Client) (push) Successful in 12m0s Details
CI / Build (ARMHF, Server) (push) Successful in 7m57s Details
CI / Build (ARMHF, Client) (push) Successful in 11m18s Details
CI / Test (Client) (push) Successful in 14m21s Details
CI / Test (Server) (push) Successful in 11m49s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Has been cancelled Details
2024-02-07 18:04:53 -05:00
TheBrokenRail 6e306e500d I Have Made This Typo Countless Times
CI / Build (AMD64, Server) (push) Successful in 10m4s Details
CI / Build (AMD64, Client) (push) Successful in 10m14s Details
CI / Build (ARM64, Server) (push) Successful in 10m12s Details
CI / Build (ARM64, Client) (push) Successful in 10m22s Details
CI / Build (ARMHF, Server) (push) Successful in 7m0s Details
CI / Build (ARMHF, Client) (push) Successful in 9m26s Details
CI / Test (Client) (push) Successful in 13m20s Details
CI / Test (Server) (push) Successful in 10m55s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m6s Details
2024-02-07 02:01:43 -05:00
TheBrokenRail 7e300a6e1b Update Changelog
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Client) (push) Has been cancelled Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
2024-02-07 01:58:21 -05:00
bigjango13 f5a680af7b Add Cake (#81)
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Server) (push) Successful in 10m3s Details
CI / Build (AMD64, Client) (push) Successful in 10m16s Details
CI / Build (ARM64, Client) (push) Has been cancelled Details
CI / Build (ARM64, Server) (push) Has been cancelled Details
Adds cake, crafting remainders, milk buckets, death messages, `misc_run_on_language_setup`, and a lot more symbols.

Co-authored-by: Bigjango13 <bigjango13@gmail.com>
Reviewed-on: #81
Co-authored-by: bigjango13 <bigjango13@noreply.thebrokenrail.org>
Co-committed-by: bigjango13 <bigjango13@noreply.thebrokenrail.org>
2024-02-07 06:47:46 +00:00
Bigjango13 c62d5264a8 More consistent lookup for sounds
CI / Build (AMD64, Client) (push) Has started running Details
CI / Build (ARM64, Client) (push) Has been cancelled Details
CI / Build (ARM64, Server) (push) Has been cancelled Details
CI / Build (ARMHF, Client) (push) Has been cancelled Details
CI / Build (ARMHF, Server) (push) Has been cancelled Details
CI / Test (Client) (push) Has been cancelled Details
CI / Test (Server) (push) Has been cancelled Details
CI / Build Example Mods (push) Has been cancelled Details
CI / Release (push) Has been cancelled Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
2024-02-07 02:16:34 +00:00
Bigjango13 93498ce9c0 Fix load_symbol ignoring source when a previous source has already been loaded 2024-02-07 02:16:34 +00:00
TheBrokenRail 90a2b0ac85 Call Ninja Directly
CI / Build (ARM64, Client) (push) Waiting to run Details
CI / Build (ARM64, Server) (push) Waiting to run Details
CI / Build (ARMHF, Client) (push) Waiting to run Details
CI / Build (ARMHF, Server) (push) Waiting to run Details
CI / Test (Client) (push) Waiting to run Details
CI / Test (Server) (push) Waiting to run Details
CI / Build Example Mods (push) Waiting to run Details
CI / Release (push) Blocked by required conditions Details
CI / Build (AMD64, Server) (push) Has been cancelled Details
CI / Build (AMD64, Client) (push) Has been cancelled Details
2024-02-06 19:35:44 -05:00
Bigjango13 2d9d4a638a Move food overlay to after classic HUD
CI / Build (AMD64, Server) (push) Successful in 10m14s Details
CI / Build (AMD64, Client) (push) Successful in 10m26s Details
CI / Build (ARM64, Server) (push) Successful in 10m28s Details
CI / Build (ARM64, Client) (push) Successful in 10m38s Details
CI / Build (ARMHF, Server) (push) Successful in 7m6s Details
CI / Build (ARMHF, Client) (push) Successful in 9m47s Details
CI / Test (Client) (push) Successful in 13m41s Details
CI / Test (Server) (push) Successful in 11m12s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m15s Details
2024-02-06 18:16:21 -05:00
Bigjango13 8c265a69d9 Add Food Overlay 2024-02-06 17:53:21 -05:00
TheBrokenRail b5e9486460 Fix Script Bug
CI / Build (AMD64, Client) (push) Successful in 5m45s Details
CI / Build (AMD64, Server) (push) Successful in 5m22s Details
CI / Build (ARM64, Client) (push) Successful in 5m39s Details
CI / Build (ARM64, Server) (push) Successful in 5m24s Details
CI / Build (ARMHF, Client) (push) Successful in 5m48s Details
CI / Build (ARMHF, Server) (push) Successful in 4m0s Details
CI / Test (Client) (push) Successful in 9m6s Details
CI / Test (Server) (push) Successful in 5m53s Details
CI / Build Example Mods (push) Successful in 5m58s Details
CI / Release (push) Has been skipped Details
2024-02-04 03:40:59 -05:00
TheBrokenRail 7fc5638143 Fix CI (Again)
CI / Build (AMD64, Server) (push) Successful in 9m45s Details
CI / Build (AMD64, Client) (push) Successful in 9m55s Details
CI / Build (ARM64, Server) (push) Successful in 9m57s Details
CI / Build (ARM64, Client) (push) Successful in 10m10s Details
CI / Build (ARMHF, Server) (push) Successful in 7m14s Details
CI / Build (ARMHF, Client) (push) Successful in 9m33s Details
CI / Test (Server) (push) Successful in 10m23s Details
CI / Test (Client) (push) Successful in 13m14s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Successful in 6m0s Details
2024-02-04 02:33:35 -05:00
TheBrokenRail 7ba9daa84e Fix CI
CI / Build (AMD64, Server) (push) Successful in 9m47s Details
CI / Build (AMD64, Client) (push) Successful in 9m58s Details
CI / Build (ARM64, Server) (push) Successful in 9m50s Details
CI / Build (ARM64, Client) (push) Successful in 10m11s Details
CI / Build (ARMHF, Server) (push) Successful in 7m1s Details
CI / Build (ARMHF, Client) (push) Successful in 9m6s Details
CI / Test (Server) (push) Successful in 10m45s Details
CI / Test (Client) (push) Successful in 13m11s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Failing after 5m56s Details
2024-02-04 01:31:41 -05:00
TheBrokenRail 930d0120f3 More CI Improvements
CI / Build (AMD64, Server) (push) Successful in 9m46s Details
CI / Build (AMD64, Client) (push) Successful in 9m57s Details
CI / Build (ARM64, Client) (push) Successful in 10m0s Details
CI / Build (ARM64, Server) (push) Successful in 10m3s Details
CI / Build (ARMHF, Server) (push) Successful in 6m53s Details
CI / Build (ARMHF, Client) (push) Successful in 9m8s Details
CI / Test (Server) (push) Successful in 10m50s Details
CI / Test (Client) (push) Successful in 13m14s Details
CI / Release (push) Has been skipped Details
CI / Build Example Mods (push) Failing after 5m55s Details
2024-02-04 00:43:25 -05:00
TheBrokenRail 31fcff13e9 CI Improvements 2024-02-04 00:36:58 -05:00
TheBrokenRail 41fcc942fa JS-Based Build Script
Build / Build (AMD64, Server) (push) Successful in 10m4s Details
Build / Build (AMD64, Client) (push) Successful in 10m19s Details
Build / Build (ARM64, Client) (push) Successful in 10m11s Details
Build / Build (ARM64, Server) (push) Successful in 10m0s Details
Build / Build (ARMHF, Server) (push) Successful in 6m57s Details
Build / Build (ARMHF, Client) (push) Successful in 9m20s Details
Build / Test (Server) (push) Successful in 10m42s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 13m41s Details
2024-02-03 21:07:53 -05:00
TheBrokenRail ddd9226e9e Fix Button Hover 2024-02-02 22:28:57 -05:00
TheBrokenRail a336cd1c7b Improve Key Handling 2024-02-02 22:25:22 -05:00
TheBrokenRail eaf6dd2fe2 Add Peaceful Mode To Options Screen 2024-02-02 14:49:47 -05:00
TheBrokenRail 99b43ddb5a Create World Screen + Scrolling Text Boxes!
Build / Build (AMD64, Server) (push) Successful in 9m42s Details
Build / Build (AMD64, Client) (push) Successful in 9m52s Details
Build / Build (ARM64, Server) (push) Successful in 9m55s Details
Build / Build (ARM64, Client) (push) Successful in 10m20s Details
Build / Build (ARMHF, Server) (push) Successful in 6m59s Details
Build / Build (ARMHF, Client) (push) Successful in 9m9s Details
Build / Test (Client) (push) Failing after 10m13s Details
Build / Release (push) Has been skipped Details
Build / Test (Server) (push) Successful in 10m4s Details
2024-02-02 04:20:34 -05:00
TheBrokenRail 4f32cfab45 Send Button In Chat
Build / Build (AMD64, Server) (push) Successful in 9m38s Details
Build / Build (AMD64, Client) (push) Successful in 10m0s Details
Build / Build (ARM64, Server) (push) Successful in 7m58s Details
Build / Build (ARM64, Client) (push) Successful in 10m35s Details
Build / Build (ARMHF, Client) (push) Successful in 8m50s Details
Build / Build (ARMHF, Server) (push) Successful in 6m45s Details
Build / Test (Server) (push) Successful in 10m54s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m7s Details
2024-02-01 14:56:16 -05:00
TheBrokenRail 69211eb31d Improve Markdown Formatting 2024-02-01 03:18:47 -05:00
TheBrokenRail 58713976d4 In-Game Chat
Build / Build (AMD64, Server) (push) Successful in 9m49s Details
Build / Build (AMD64, Client) (push) Successful in 10m10s Details
Build / Build (ARM64, Client) (push) Successful in 9m53s Details
Build / Build (ARM64, Server) (push) Successful in 10m0s Details
Build / Build (ARMHF, Server) (push) Successful in 7m7s Details
Build / Build (ARMHF, Client) (push) Successful in 9m14s Details
Build / Test (Server) (push) Successful in 11m12s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m21s Details
2024-02-01 03:12:24 -05:00
TheBrokenRail d175f692e0 Put Sending Full Level Behind Flag 2024-01-31 23:52:29 -05:00
TheBrokenRail 6d4ff44092 Java Light Ramp (Also From ReMCPE)
Build / Build (AMD64, Server) (push) Successful in 9m51s Details
Build / Build (AMD64, Client) (push) Successful in 10m2s Details
Build / Build (ARM64, Server) (push) Successful in 10m4s Details
Build / Build (ARM64, Client) (push) Successful in 10m21s Details
Build / Build (ARMHF, Server) (push) Successful in 7m11s Details
Build / Build (ARMHF, Client) (push) Successful in 9m23s Details
Build / Test (Server) (push) Successful in 10m53s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m33s Details
2024-01-31 23:44:04 -05:00
TheBrokenRail 1771919cc1 Port Fire/Lava Textures From ReMCPE
Build / Build (AMD64, Server) (push) Successful in 9m44s Details
Build / Build (AMD64, Client) (push) Successful in 9m59s Details
Build / Build (ARM64, Server) (push) Successful in 9m58s Details
Build / Build (ARM64, Client) (push) Successful in 10m28s Details
Build / Build (ARMHF, Server) (push) Successful in 6m56s Details
Build / Build (ARMHF, Client) (push) Successful in 9m28s Details
Build / Test (Server) (push) Successful in 11m28s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m51s Details
2024-01-31 22:13:20 -05:00
TheBrokenRail 522cee2d3b Fix overwrite_calls_within Macro
Build / Build (AMD64, Server) (push) Successful in 9m54s Details
Build / Build (AMD64, Client) (push) Successful in 10m9s Details
Build / Build (ARM64, Server) (push) Successful in 10m14s Details
Build / Build (ARM64, Client) (push) Successful in 10m32s Details
Build / Build (ARMHF, Server) (push) Successful in 7m1s Details
Build / Build (ARMHF, Client) (push) Successful in 9m27s Details
Build / Test (Server) (push) Successful in 11m58s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 17m23s Details
2024-01-30 01:30:11 -05:00
TheBrokenRail ccc7e5b190 Fix MCPI Ignoring ♪
Build / Build (AMD64, Server) (push) Successful in 9m37s Details
Build / Build (AMD64, Client) (push) Successful in 10m3s Details
Build / Build (ARM64, Client) (push) Successful in 9m51s Details
Build / Build (ARM64, Server) (push) Successful in 9m45s Details
Build / Build (ARMHF, Server) (push) Successful in 6m56s Details
Build / Build (ARMHF, Client) (push) Successful in 9m11s Details
Build / Test (Server) (push) Successful in 11m45s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m54s Details
2024-01-28 21:48:51 -05:00
TheBrokenRail 7c9d16d662 Fix Mistake
Build / Build (AMD64, Server) (push) Successful in 9m49s Details
Build / Build (AMD64, Client) (push) Successful in 10m1s Details
Build / Build (ARM64, Server) (push) Successful in 10m0s Details
Build / Build (ARM64, Client) (push) Successful in 10m13s Details
Build / Build (ARMHF, Server) (push) Successful in 6m59s Details
Build / Build (ARMHF, Client) (push) Successful in 9m21s Details
Build / Test (Server) (push) Successful in 11m47s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m57s Details
2024-01-27 17:47:43 -05:00
TheBrokenRail 49f56bd90d Fix Benchmark
Build / Build (AMD64, Server) (push) Successful in 10m10s Details
Build / Build (AMD64, Client) (push) Successful in 10m24s Details
Build / Build (ARM64, Server) (push) Successful in 10m15s Details
Build / Build (ARM64, Client) (push) Successful in 10m35s Details
Build / Build (ARMHF, Server) (push) Successful in 7m7s Details
Build / Build (ARMHF, Client) (push) Successful in 9m43s Details
Build / Test (Server) (push) Successful in 11m22s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 17m22s Details
2024-01-23 23:00:22 -05:00
TheBrokenRail 0b252faa5f Simplify Some Code
Build / Build (AMD64, Server) (push) Successful in 10m14s Details
Build / Build (AMD64, Client) (push) Successful in 10m27s Details
Build / Build (ARM64, Server) (push) Successful in 10m18s Details
Build / Build (ARM64, Client) (push) Successful in 10m37s Details
Build / Build (ARMHF, Server) (push) Successful in 7m12s Details
Build / Build (ARMHF, Client) (push) Successful in 9m44s Details
Build / Test (Server) (push) Successful in 11m50s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Has been cancelled Details
2024-01-23 21:58:18 -05:00
Bigjango13 233e8d691b Fix Tesselator instance symbols
Build / Build (AMD64, Server) (push) Successful in 10m36s Details
Build / Build (AMD64, Client) (push) Successful in 10m48s Details
Build / Build (ARM64, Server) (push) Successful in 10m27s Details
Build / Build (ARM64, Client) (push) Successful in 10m42s Details
Build / Build (ARMHF, Server) (push) Successful in 7m15s Details
Build / Build (ARMHF, Client) (push) Successful in 9m47s Details
Build / Test (Client) (push) Failing after 2m55s Details
Build / Release (push) Has been skipped Details
Build / Test (Server) (push) Failing after 1m55s Details
2024-01-24 01:51:57 +00:00
Bigjango13 83a282551d Add packet related symbols 2024-01-24 01:51:57 +00:00
Bigjango13 29b49ac70a More symbols 2024-01-24 01:51:57 +00:00
Bigjango13 118fc6f396 Even more symbols from other projects 2024-01-24 01:51:57 +00:00
Bigjango13 e95236023c A few more symbols 2024-01-24 01:51:57 +00:00
TheBrokenRail 46241c9aa0 Expose Some Properties
Build / Build (ARM64, Client) (push) Waiting to run Details
Build / Build (ARM64, Server) (push) Waiting to run Details
Build / Build (ARMHF, Client) (push) Waiting to run Details
Build / Build (ARMHF, Server) (push) Waiting to run Details
Build / Test (Client) (push) Waiting to run Details
Build / Test (Server) (push) Waiting to run Details
Build / Release (push) Blocked by required conditions Details
Build / Build (AMD64, Server) (push) Has been cancelled Details
Build / Build (AMD64, Client) (push) Has been cancelled Details
2024-01-23 20:51:36 -05:00
TheBrokenRail f7be586a4c Build On Bullseye 2024-01-23 18:20:14 -05:00
Bigjango13 5c5538df2f Move worldgen desync patch to misc, for LAN games
Build / Build (AMD64, Server) (push) Successful in 9m30s Details
Build / Build (AMD64, Client) (push) Successful in 9m43s Details
Build / Build (ARM64, Server) (push) Successful in 8m29s Details
Build / Build (ARM64, Client) (push) Successful in 9m17s Details
Build / Build (ARMHF, Server) (push) Successful in 6m41s Details
Build / Build (ARMHF, Client) (push) Successful in 8m46s Details
Build / Test (Server) (push) Successful in 10m27s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m49s Details
2024-01-21 19:00:01 -05:00
Bigjango13 2995d1c9ad Fix short alignment 2024-01-21 18:43:31 -05:00
Bigjango13 b9b44a62bc Fix worldgen desync (and add some symbols) 2024-01-21 18:24:06 -05:00
Bigjango13 7e546a4a09 Fix ItemInHandRenderer in symbols
Build / Build (AMD64, Server) (push) Successful in 9m32s Details
Build / Build (AMD64, Client) (push) Successful in 9m46s Details
Build / Build (ARM64, Server) (push) Successful in 9m2s Details
Build / Build (ARM64, Client) (push) Successful in 9m28s Details
Build / Build (ARMHF, Server) (push) Successful in 6m39s Details
Build / Build (ARMHF, Client) (push) Successful in 8m58s Details
Build / Test (Server) (push) Successful in 11m53s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m43s Details
2024-01-20 08:24:35 +00:00
Bigjango13 be5bcf24c4 More symbols, mostly item rendering related 2024-01-20 08:24:35 +00:00
TheBrokenRail 91ff082c97 Create AppImages Using CPack
Build / Build (AMD64, Server) (push) Successful in 9m39s Details
Build / Build (AMD64, Client) (push) Successful in 9m57s Details
Build / Build (ARM64, Server) (push) Successful in 8m59s Details
Build / Build (ARM64, Client) (push) Successful in 9m17s Details
Build / Build (ARMHF, Server) (push) Successful in 6m35s Details
Build / Build (ARMHF, Client) (push) Successful in 8m47s Details
Build / Test (Server) (push) Successful in 11m17s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m22s Details
2024-01-20 02:10:18 -05:00
TheBrokenRail 40cd1b0a14 Improve CMake Superbuild
Build / Build (AMD64, Server) (push) Successful in 10m14s Details
Build / Build (AMD64, Client) (push) Successful in 10m31s Details
Build / Build (ARM64, Server) (push) Successful in 9m2s Details
Build / Build (ARM64, Client) (push) Successful in 9m27s Details
Build / Build (ARMHF, Server) (push) Successful in 6m43s Details
Build / Build (ARMHF, Client) (push) Successful in 8m50s Details
Build / Test (Server) (push) Successful in 12m13s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m57s Details
2024-01-16 03:08:34 -05:00
TheBrokenRail 5c607d96b8 Simplify CMake
Build / Build (AMD64, Server) (push) Successful in 10m2s Details
Build / Build (AMD64, Client) (push) Successful in 10m13s Details
Build / Build (ARM64, Server) (push) Successful in 9m2s Details
Build / Build (ARM64, Client) (push) Successful in 9m22s Details
Build / Build (ARMHF, Server) (push) Successful in 6m37s Details
Build / Build (ARMHF, Client) (push) Successful in 8m50s Details
Build / Test (Server) (push) Successful in 11m39s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 17m2s Details
2024-01-16 01:45:52 -05:00
TheBrokenRail 6e9b364f81 Organize Symbols
Build / Build (AMD64, Server) (push) Successful in 9m53s Details
Build / Build (AMD64, Client) (push) Successful in 10m7s Details
Build / Build (ARM64, Server) (push) Successful in 9m16s Details
Build / Build (ARM64, Client) (push) Successful in 9m49s Details
Build / Build (ARMHF, Server) (push) Successful in 6m39s Details
Build / Build (ARMHF, Client) (push) Successful in 8m49s Details
Build / Test (Server) (push) Successful in 11m35s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m27s Details
2024-01-11 22:10:30 -05:00
TheBrokenRail 67a0d3017b Fix Furnace Visual Bug
Build / Build (AMD64, Server) (push) Successful in 9m53s Details
Build / Build (AMD64, Client) (push) Successful in 10m11s Details
Build / Build (ARM64, Server) (push) Successful in 9m17s Details
Build / Build (ARM64, Client) (push) Successful in 9m34s Details
Build / Build (ARMHF, Server) (push) Successful in 6m24s Details
Build / Build (ARMHF, Client) (push) Successful in 8m42s Details
Build / Test (Server) (push) Successful in 11m19s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m15s Details
2024-01-07 04:57:16 -05:00
TheBrokenRail e4d9ee4f20 Code Style Changes 2024-01-07 03:23:43 -05:00
TheBrokenRail d32fa2d265 Add Some Symbols From MCPI-Addons
Build / Build (AMD64, Server) (push) Successful in 9m50s Details
Build / Build (AMD64, Client) (push) Successful in 10m5s Details
Build / Build (ARM64, Server) (push) Successful in 9m12s Details
Build / Build (ARM64, Client) (push) Successful in 9m46s Details
Build / Build (ARMHF, Server) (push) Successful in 6m35s Details
Build / Build (ARMHF, Client) (push) Successful in 8m49s Details
Build / Test (Server) (push) Successful in 11m0s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Successful in 16m16s Details
2024-01-07 02:59:04 -05:00
TheBrokenRail 34c24378f3 Update Example Mods 2024-01-06 20:36:59 -05:00
TheBrokenRail b7b60876d8 Fix Item Dropping When Killing Players From The Server Console
Build / Build (AMD64, Server) (push) Successful in 9m59s Details
Build / Build (AMD64, Client) (push) Successful in 10m15s Details
Build / Build (ARM64, Server) (push) Successful in 9m17s Details
Build / Build (ARM64, Client) (push) Successful in 9m40s Details
Build / Build (ARMHF, Server) (push) Successful in 6m31s Details
Build / Build (ARMHF, Client) (push) Successful in 9m3s Details
Build / Test (Server) (push) Successful in 12m4s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Failing after 17m0s Details
2024-01-06 18:15:52 -05:00
TheBrokenRail 4dff667749 Fix Server Build
Build / Build (ARMHF, Client) (push) Waiting to run Details
Build / Build (ARMHF, Server) (push) Waiting to run Details
Build / Test (Client) (push) Waiting to run Details
Build / Test (Server) (push) Waiting to run Details
Build / Release (push) Blocked by required conditions Details
Build / Build (AMD64, Server) (push) Successful in 10m3s Details
Build / Build (AMD64, Client) (push) Successful in 10m15s Details
Build / Build (ARM64, Client) (push) Has been cancelled Details
Build / Build (ARM64, Server) (push) Has been cancelled Details
2024-01-06 18:03:48 -05:00
TheBrokenRail aa92da6fdd WIP New Modding API
Build / Build (AMD64, Server) (push) Failing after 3m17s Details
Build / Build (AMD64, Client) (push) Successful in 8m28s Details
Build / Build (ARM64, Client) (push) Successful in 8m27s Details
Build / Build (ARM64, Server) (push) Failing after 4m1s Details
Build / Build (ARMHF, Server) (push) Failing after 3m31s Details
Build / Build (ARMHF, Client) (push) Successful in 7m38s Details
Build / Release (push) Has been skipped Details
Build / Test (Client) (push) Failing after 5m48s Details
Build / Test (Server) (push) Failing after 3m9s Details
2024-01-06 06:30:23 -05:00
413 changed files with 9421 additions and 7821 deletions

View File

@ -1,4 +1,4 @@
name: 'Build' name: 'CI'
on: on:
push: push:
@ -23,28 +23,24 @@ jobs:
- ARMHF - ARMHF
name: Build name: Build
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: node:16-buster container: node:lts-bullseye
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
submodules: true submodules: true
# Dependencies # Dependencies
- name: Install CMake
run: |
echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/backports.list
apt-get update
apt-get install --no-install-recommends -y -t buster-backports cmake
- name: Install Dependencies - name: Install Dependencies
run: ./scripts/install-dependencies.sh ${{ matrix.arch }} run: ./scripts/install-dependencies.sh ${{ matrix.arch }}
# Build # Build
- name: Build - name: Build
run: ./scripts/package.sh ${{ matrix.mode }} ${{ matrix.arch }} run: ./scripts/build.mjs appimage ${{ matrix.mode }} ${{ matrix.arch }}
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: ${{ matrix.mode }}-${{ matrix.arch }} name: ${{ matrix.mode }} (${{ matrix.arch }})
path: ./out/*.AppImage* path: ./out/*.AppImage*
if-no-files-found: error
# Test Project # Test Project
test: test:
strategy: strategy:
@ -55,33 +51,56 @@ jobs:
- Server - Server
name: Test name: Test
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: node:16-buster container: node:lts-bullseye
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
submodules: true submodules: true
# Dependencies # Dependencies
- name: Install CMake
run: |
echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/backports.list
apt-get update
apt-get install --no-install-recommends -y -t buster-backports cmake
- name: Install Dependencies - name: Install Dependencies
run: ./scripts/install-dependencies.sh run: ./scripts/install-dependencies.sh
- name: Install ARM Toolchain
if: ${{ matrix.mode == 'Client' }}
run: apt-get install --no-install-recommends -y g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf
# Test # Test
- name: Test - name: Test
run: ./scripts/test.sh ${{ matrix.mode }} run: ./scripts/test.sh ${{ matrix.mode }}
# Example Mods
example-mods:
name: Build Example Mods
runs-on: ubuntu-latest
container: node:lts-bullseye
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: true
# Dependencies
- name: Install Dependencies
run: ./scripts/install-dependencies.sh
- name: Install ARM Toolchain
run: apt-get install --no-install-recommends -y g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf
# Build SDK
- name: Build SDK
run: |
./scripts/build.mjs none client host
export _MCPI_SKIP_ROOT_CHECK=1
export DISPLAY=
./out/client/host/usr/bin/minecraft-pi-reborn-client --copy-sdk
# Build Example Mods
- name: Build Example Mods
run: ./example-mods/build.sh
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: Example Mods
path: ./example-mods/out/*
if-no-files-found: error
# Create Release # Create Release
release: release:
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
needs: build needs: build
name: Release name: Release
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: node:16-buster container: node:lts-bullseye
steps: steps:
# Dependencies # Dependencies
- name: Install Go - name: Install Go
@ -97,7 +116,7 @@ jobs:
- name: Create Release - name: Create Release
uses: https://gitea.com/actions/release-action@main uses: https://gitea.com/actions/release-action@main
with: with:
files: ./out files: ./out/*/*.AppImage*
api_key: ${{ secrets.RELEASE_TOKEN }} api_key: ${{ secrets.RELEASE_TOKEN }}
title: v${{ github.ref_name }} title: v${{ github.ref_name }}
body: "[View Changelog](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/src/branch/master/docs/CHANGELOG.md)" body: "[View Changelog](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/src/branch/master/docs/CHANGELOG.md)"

4
.gitignore vendored
View File

@ -12,3 +12,7 @@
/*.AppImage /*.AppImage
/core* /core*
/qemu_* /qemu_*
/example-mods/out
/.testing-tmp
/cmake-build-*
/.idea

3
.gitmodules vendored
View File

@ -19,3 +19,6 @@
[submodule "archives"] [submodule "archives"]
path = archives path = archives
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/archives.git url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/archives.git
[submodule "dependencies/symbol-processor/src"]
path = dependencies/symbol-processor/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/symbol-processor.git

View File

@ -1,124 +1,28 @@
cmake_minimum_required(VERSION 3.16.0) cmake_minimum_required(VERSION 3.17.0)
# Avoid Warning About DOWNLOAD_EXTRACT_TIMESTAMP # Avoid Warning About DOWNLOAD_EXTRACT_TIMESTAMP
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24.0) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24.0)
cmake_policy(SET CMP0135 NEW) cmake_policy(SET CMP0135 NEW)
endif() endif()
# Build Mode # Core Options
set(MCPI_BUILD_MODE "native" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code") include(cmake/options/core-options.cmake)
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
option(MCPI_IS_MIXED_BUILD "Whether The Architecture-Independent And ARM Code Are Different Architecture" FALSE)
option(MCPI_OPEN_SOURCE_ONLY "Only Install Open-Source Code (Will Result In Broken Install)" FALSE)
option(MCPI_IS_APPIMAGE_BUILD "AppImage Build" FALSE)
option(MCPI_IS_FLATPAK_BUILD "Flatpak Build" FALSE)
# Server/Headless Builds
option(MCPI_SERVER_MODE "Server Mode" FALSE)
option(MCPI_HEADLESS_MODE "Headless Mode" ${MCPI_SERVER_MODE})
# Media Layer
if(MCPI_HEADLESS_MODE)
set(DEFAULT_USE_MEDIA_LAYER_PROXY FALSE)
else()
set(DEFAULT_USE_MEDIA_LAYER_PROXY ${MCPI_IS_MIXED_BUILD})
endif()
option(MCPI_USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" ${DEFAULT_USE_MEDIA_LAYER_PROXY})
if(NOT MCPI_HEADLESS_MODE)
option(MCPI_USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" TRUE)
endif()
if(MCPI_USE_MEDIA_LAYER_PROXY)
set(BUILD_MEDIA_LAYER_CORE "${BUILD_NATIVE_COMPONENTS}")
else()
set(BUILD_MEDIA_LAYER_CORE "${BUILD_ARM_COMPONENTS}")
endif()
# App ID
set(DEFAULT_APP_ID "com.thebrokenrail.MCPIReborn")
if(MCPI_SERVER_MODE)
string(APPEND DEFAULT_APP_ID "Server")
else()
string(APPEND DEFAULT_APP_ID "Client")
endif()
set(MCPI_APP_ID "${DEFAULT_APP_ID}" CACHE STRING "App ID")
# App Title
set(MCPI_APP_BASE_TITLE "Minecraft: Pi Edition: Reborn" CACHE STRING "Base App Title")
set(DEFAULT_APP_TITLE "${MCPI_APP_BASE_TITLE}")
if(MCPI_SERVER_MODE)
string(APPEND DEFAULT_APP_TITLE " (Server)")
else()
string(APPEND DEFAULT_APP_TITLE " (Client)")
endif()
set(MCPI_APP_TITLE "${DEFAULT_APP_TITLE}" CACHE STRING "App Title")
# Specify Variant Name
set(MCPI_VARIANT_NAME "minecraft-pi-reborn")
if(MCPI_SERVER_MODE)
string(APPEND MCPI_VARIANT_NAME "-server")
else()
string(APPEND MCPI_VARIANT_NAME "-client")
endif()
# Skin Server
set(MCPI_SKIN_SERVER "https://raw.githubusercontent.com/MCPI-Revival/Skins/data" CACHE STRING "Skin Server")
# Specify Installation Paths
set(MCPI_INSTALL_DIR "lib/${MCPI_VARIANT_NAME}")
set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin")
set(MCPI_LEGAL_DIR "${MCPI_INSTALL_DIR}/legal") # For Software Licenses
set(MCPI_SDK_DIR "${MCPI_INSTALL_DIR}/sdk")
set(MCPI_SDK_LIB_DIR "${MCPI_SDK_DIR}/lib")
set(MCPI_SDK_INCLUDE_DIR "${MCPI_SDK_DIR}/include")
# Library Directory
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
if(BUILD_ARM_COMPONENTS)
string(APPEND MCPI_LIB_DIR "/arm")
elseif(BUILD_NATIVE_COMPONENTS)
string(APPEND MCPI_LIB_DIR "/native")
endif()
# Share Directory
set(MCPI_SHARE_DIR "share")
if(MCPI_IS_APPIMAGE_BUILD)
string(PREPEND MCPI_SHARE_DIR "usr/")
endif()
# Build Mode # Build Mode
if(NOT CMAKE_BUILD_TYPE) if(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release") set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
endif()
# Prebuilt ARMHF Toolchain
option(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN "Whether To Use A Prebuilt ARMHF Toolchain For Building ARM Components" ${MCPI_IS_MIXED_BUILD})
if(BUILD_ARM_COMPONENTS AND MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
include(cmake/prebuilt-armhf-toolchain.cmake)
endif() endif()
# Start Project # Start Project
project(minecraft-pi-reborn) project(minecraft-pi-reborn)
# Utility Functions # Utility Functions
include(cmake/util.cmake) include(cmake/util/util.cmake)
# Sanity Checks # Sanity Checks
string(CONCAT ARM_SANITY_CHECK string(CONCAT ARM_SANITY_CHECK
"set(IS_ARM_TARGETING FALSE)\n" "include(CheckSymbolExists)\n"
"if(CMAKE_SYSTEM_PROCESSOR STREQUAL \"arm\" OR CMAKE_SYSTEM_PROCESSOR STREQUAL \"armv7l\")\n" "check_symbol_exists(\"__arm__\" \"\" IS_ARM_TARGETING)"
" set(IS_ARM_TARGETING TRUE)\n"
"endif()"
) )
if(BUILD_ARM_COMPONENTS) if(BUILD_ARM_COMPONENTS)
string(CONCAT ARM_SANITY_CHECK string(CONCAT ARM_SANITY_CHECK
@ -129,27 +33,19 @@ if(BUILD_ARM_COMPONENTS)
) )
endif() endif()
cmake_language(EVAL CODE "${ARM_SANITY_CHECK}") cmake_language(EVAL CODE "${ARM_SANITY_CHECK}")
if(BUILD_NATIVE_COMPONENTS AND NOT IS_ARM_TARGETING AND NOT MCPI_IS_MIXED_BUILD)
message(FATAL_ERROR "Project is configured as a mixed-buld, but MCPI_IS_MIXED_BUILD is disabled.")
endif()
# Specify Default Installation Prefix # Extra Options
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) include(cmake/options/extra-options.cmake)
set(DEFAULT_PREFIX "/usr")
if(MCPI_IS_APPIMAGE_BUILD) # Paths
set(DEFAULT_PREFIX "/") include(cmake/options/paths.cmake)
elseif(MCPI_IS_FLATPAK_BUILD)
set(DEFAULT_PREFIX "/app")
endif()
set(CMAKE_INSTALL_PREFIX "${DEFAULT_PREFIX}" CACHE PATH "" FORCE)
set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT FALSE)
endif()
# Required Compile Flags # Required Compile Flags
string(CONCAT COMPILE_FLAGS_SETUP string(CONCAT COMPILE_FLAGS_SETUP
# Optimizations # Optimizations
"if(CMAKE_BUILD_TYPE STREQUAL \"Release\")\n" "if(CMAKE_BUILD_TYPE STREQUAL \"Release\")\n"
" add_compile_options(-O3 -s)\n" " add_compile_options(-O3)\n"
" add_link_options(-s)\n"
"else()\n" "else()\n"
" add_compile_options(-g)\n" " add_compile_options(-g)\n"
"endif()\n" "endif()\n"
@ -175,7 +71,7 @@ add_compile_options(-ffast-math)
# Warnings # Warnings
add_compile_options(-Wall -Wextra -Werror -Wpointer-arith -Wshadow -Wnull-dereference) add_compile_options(-Wall -Wextra -Werror -Wpointer-arith -Wshadow -Wnull-dereference)
if(CMAKE_C_COMPILER_ID STREQUAL \"GNU\") if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
# Prevents False Positives # Prevents False Positives
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 10.0) if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 10.0)
add_compile_options(-Wno-stringop-overflow) add_compile_options(-Wno-stringop-overflow)
@ -223,6 +119,11 @@ if(BUILD_NATIVE_COMPONENTS)
add_subdirectory(images) add_subdirectory(images)
endif() endif()
# Install Prebuilt ARMHF Toolchain Sysroot
if(BUILD_NATIVE_COMPONENTS AND MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
install_arm_sysroot()
endif()
# Install SDK # Install SDK
if(BUILD_ARM_COMPONENTS) if(BUILD_ARM_COMPONENTS)
install(EXPORT sdk DESTINATION "${MCPI_SDK_DIR}" FILE "sdk-targets.cmake" EXPORT_LINK_INTERFACE_LIBRARIES) install(EXPORT sdk DESTINATION "${MCPI_SDK_DIR}" FILE "sdk-targets.cmake" EXPORT_LINK_INTERFACE_LIBRARIES)
@ -238,3 +139,46 @@ if(BUILD_ARM_COMPONENTS)
) )
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake" DESTINATION "${MCPI_SDK_DIR}") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake" DESTINATION "${MCPI_SDK_DIR}")
endif() 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)
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_TOOLCHAIN_FILE}")
endif()
else()
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${MCPI_CMAKE_TOOLCHAIN_FILE}")
endif()
list(APPEND ARM_OPTIONS "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}")
# Build
ExternalProject_Add(arm-components
DOWNLOAD_COMMAND ""
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
CMAKE_CACHE_ARGS ${ARM_OPTIONS}
INSTALL_COMMAND
"${CMAKE_COMMAND}" "-E"
"rm" "-rf" "<INSTALL_DIR>/${MCPI_INSTALL_DIR}"
COMMAND
"${CMAKE_COMMAND}" "-E" "env"
"DESTDIR="
"${CMAKE_COMMAND}" "--install" "<BINARY_DIR>"
USES_TERMINAL_CONFIGURE TRUE
USES_TERMINAL_BUILD TRUE
USES_TERMINAL_INSTALL TRUE
BUILD_ALWAYS TRUE
)
# Install
ExternalProject_Get_Property(arm-components INSTALL_DIR)
install(DIRECTORY "${INSTALL_DIR}/${MCPI_INSTALL_DIR}/" DESTINATION "${MCPI_INSTALL_DIR}")
endif()

View File

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

View File

@ -1 +1 @@
2.5.3 3.0.0

@ -1 +1 @@
Subproject commit f878bb1299f3c9506737f311cb01749e41e3f9dd Subproject commit 37d4baec5874b39e10cafda2f9fcf6b63129c85a

View File

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

View File

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

View File

@ -0,0 +1,21 @@
# 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()

View File

@ -0,0 +1,82 @@
# Specify Options
mcpi_option(OPEN_SOURCE_ONLY "Only Install Open-Source Code (Will Result In Broken Install)" BOOL FALSE)
mcpi_option(IS_APPIMAGE_BUILD "AppImage Build" BOOL FALSE)
mcpi_option(IS_FLATPAK_BUILD "Flatpak Build" BOOL FALSE)
if(MCPI_IS_APPIMAGE_BUILD AND MCPI_IS_FLATPAK_BUILD)
message(FATAL_ERROR "Invalid Build Configuration")
endif()
# Server/Headless Builds
mcpi_option(SERVER_MODE "Server Mode" BOOL FALSE)
mcpi_option(HEADLESS_MODE "Headless Mode" BOOL "${MCPI_SERVER_MODE}")
# Prebuilt ARMHF Toolchain
if(BUILD_NATIVE_COMPONENTS)
set(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN FALSE)
if(NOT IS_ARM_TARGETING)
set(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN TRUE)
endif()
if(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
include("${CMAKE_CURRENT_LIST_DIR}/prebuilt-armhf-toolchain.cmake")
endif()
endif()
# Media Layer
if(NOT MCPI_HEADLESS_MODE)
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 (Requires QEMU)" BOOL "${DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE}")
mcpi_option(USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" BOOL TRUE)
else()
set(MCPI_USE_MEDIA_LAYER_TRAMPOLINE FALSE)
endif()
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
set(BUILD_MEDIA_LAYER_CORE "${BUILD_NATIVE_COMPONENTS}")
else()
set(BUILD_MEDIA_LAYER_CORE "${BUILD_ARM_COMPONENTS}")
endif()
# QEMU
if(BUILD_NATIVE_COMPONENTS)
include(CheckSymbolExists)
check_symbol_exists("__ARM_ARCH" "" MCPI_IS_ARM32_OR_ARM64_TARGETING)
set(MCPI_USE_QEMU TRUE)
if(MCPI_IS_ARM32_OR_ARM64_TARGETING AND NOT MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
set(MCPI_USE_QEMU FALSE)
endif()
endif()
# Specify Variant Name
set(MCPI_VARIANT_NAME "minecraft-pi-reborn")
if(MCPI_SERVER_MODE)
string(APPEND MCPI_VARIANT_NAME "-server")
else()
string(APPEND MCPI_VARIANT_NAME "-client")
endif()
# App ID
set(DEFAULT_APP_ID "com.thebrokenrail.MCPIReborn")
if(MCPI_SERVER_MODE)
string(APPEND DEFAULT_APP_ID "Server")
else()
string(APPEND DEFAULT_APP_ID "Client")
endif()
mcpi_option(APP_ID "App ID" STRING "${DEFAULT_APP_ID}")
# App Title
mcpi_option(APP_BASE_TITLE "Base App Title" STRING "Minecraft: Pi Edition: Reborn")
set(DEFAULT_APP_TITLE "${MCPI_APP_BASE_TITLE}")
if(MCPI_SERVER_MODE)
string(APPEND DEFAULT_APP_TITLE " (Server)")
else()
string(APPEND DEFAULT_APP_TITLE " (Client)")
endif()
mcpi_option(APP_TITLE "App Title" STRING "${DEFAULT_APP_TITLE}")
# Skin Server
mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data")
# Discord Invite
mcpi_option(DISCORD_INVITE "Discord Invite URL" STRING "https://discord.gg/mcpi-revival-740287937727561779")

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

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

View File

@ -13,7 +13,7 @@ endif()
include(FetchContent) include(FetchContent)
FetchContent_Declare( FetchContent_Declare(
prebuilt-armhf-toolchain prebuilt-armhf-toolchain
URL "file://${CMAKE_CURRENT_LIST_DIR}/../archives/${toolchain_file}" URL "${CMAKE_CURRENT_LIST_DIR}/../../archives/${toolchain_file}"
) )
FetchContent_MakeAvailable(prebuilt-armhf-toolchain) FetchContent_MakeAvailable(prebuilt-armhf-toolchain)
set(toolchain_dir "${prebuilt-armhf-toolchain_SOURCE_DIR}") set(toolchain_dir "${prebuilt-armhf-toolchain_SOURCE_DIR}")
@ -26,7 +26,7 @@ file(WRITE "${toolchain_dir}/toolchain.cmake"
"set(CMAKE_SYSTEM_PROCESSOR \"arm\")\n" "set(CMAKE_SYSTEM_PROCESSOR \"arm\")\n"
"set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\n" "set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\n"
) )
set(CMAKE_TOOLCHAIN_FILE "${toolchain_dir}/toolchain.cmake" CACHE STRING "" FORCE) set(MCPI_CMAKE_TOOLCHAIN_FILE "${toolchain_dir}/toolchain.cmake" CACHE FILEPATH "" FORCE)
# Build Sysroot # Build Sysroot
set(sysroot_dir "${CMAKE_CURRENT_BINARY_DIR}/bundled-armhf-sysroot") set(sysroot_dir "${CMAKE_CURRENT_BINARY_DIR}/bundled-armhf-sysroot")
@ -61,8 +61,10 @@ if("${toolchain_dir}/bin/arm-none-linux-gnueabihf-gcc" IS_NEWER_THAN "${sysroot_
endif() endif()
# Install Sysroot (Skipping Empty Directories) # Install Sysroot (Skipping Empty Directories)
function(install_arm_sysroot)
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE RELATIVE "${sysroot_dir}" "${sysroot_dir}/*") file(GLOB_RECURSE files LIST_DIRECTORIES FALSE RELATIVE "${sysroot_dir}" "${sysroot_dir}/*")
foreach(file IN LISTS files) foreach(file IN LISTS files)
get_filename_component(parent "${file}" DIRECTORY) get_filename_component(parent "${file}" DIRECTORY)
install(PROGRAMS "${sysroot_dir}/${file}" DESTINATION "${MCPI_INSTALL_DIR}/sysroot/${parent}") install(PROGRAMS "${sysroot_dir}/${file}" DESTINATION "${MCPI_INSTALL_DIR}/sysroot/${parent}")
endforeach() endforeach()
endfunction()

View File

@ -9,6 +9,7 @@ macro(setup_toolchain target)
add_target_variant(unknown) add_target_variant(unknown)
add_target_variant(none) add_target_variant(none)
add_target_variant(pc) add_target_variant(pc)
# Find Compiler # Find Compiler
macro(find_compiler output name) macro(find_compiler output name)
set(possible_names "") set(possible_names "")
@ -26,13 +27,11 @@ macro(setup_toolchain target)
endmacro() endmacro()
find_compiler(CMAKE_C_COMPILER "gcc") find_compiler(CMAKE_C_COMPILER "gcc")
find_compiler(CMAKE_CXX_COMPILER "g++") find_compiler(CMAKE_CXX_COMPILER "g++")
# Extra # Extra
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Custom Search Paths # Custom Search Paths
if(NOT DEFINED ENV{MCPI_TOOLCHAIN_USE_DEFAULT_SEARCH_PATHS})
# Find Root
set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}" "/usr") set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}" "/usr")
# pkg-config # pkg-config
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/${target}/pkgconfig:/usr/${target}/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig") set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/${target}/pkgconfig:/usr/${target}/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig")
endif()
endmacro() endmacro()

View File

@ -24,3 +24,10 @@ function(embed_resource target file)
# Add To Target # Add To Target
target_sources("${target}" PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${name}.c") target_sources("${target}" PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
endfunction() 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()

View File

@ -13,11 +13,11 @@ if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_SERVER_MODE)
add_subdirectory(zenity) add_subdirectory(zenity)
endif() endif()
# LIEF # LIEF
if(BUILD_NATIVE_COMPONENTS OR (BUILD_ARM_COMPONENTS AND NOT MCPI_SERVER_MODE AND NOT MCPI_USE_MEDIA_LAYER_PROXY)) if(BUILD_NATIVE_COMPONENTS OR (BUILD_MEDIA_LAYER_CORE AND NOT MCPI_HEADLESS_MODE))
add_subdirectory(LIEF) add_subdirectory(LIEF)
endif() endif()
# QEMU # QEMU
if(BUILD_NATIVE_COMPONENTS AND NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")) if(BUILD_NATIVE_COMPONENTS AND MCPI_USE_QEMU)
add_subdirectory(qemu) add_subdirectory(qemu)
endif() endif()
# GLFW # GLFW
@ -30,3 +30,7 @@ if(BUILD_MEDIA_LAYER_CORE AND NOT MCPI_HEADLESS_MODE AND MCPI_USE_GLES1_COMPATIB
endif() endif()
# UTF8-CPP # UTF8-CPP
add_subdirectory(utf8cpp) add_subdirectory(utf8cpp)
# Symbol Prcoessor
if(BUILD_ARM_COMPONENTS)
add_subdirectory(symbol-processor)
endif()

View File

@ -24,10 +24,9 @@ set(LIEF_OAT FALSE CACHE BOOL "" FORCE)
set(LIEF_VDEX FALSE CACHE BOOL "" FORCE) set(LIEF_VDEX FALSE CACHE BOOL "" FORCE)
# Download # Download
set(MESSAGE_QUIET TRUE)
add_subdirectory(src EXCLUDE_FROM_ALL) add_subdirectory(src EXCLUDE_FROM_ALL)
unset(MESSAGE_QUIET)
# Ensure Build
add_custom_target(LIEF-build ALL DEPENDS LIB_LIEF)
# Install # Install
install(TARGETS LIB_LIEF DESTINATION "${MCPI_LIB_DIR}") install(TARGETS LIB_LIEF DESTINATION "${MCPI_LIB_DIR}")

@ -1 +1 @@
Subproject commit 2d9855fc7f9d4ce6325245f8b75c98eb7663db60 Subproject commit 16962f2f36a51b2acefad9cec3622f6de5730aa3

View File

@ -16,10 +16,9 @@ set(GLFW_BUILD_COCOA FALSE CACHE BOOL "" FORCE)
set(GLFW_BUILD_X11 TRUE CACHE BOOL "" FORCE) set(GLFW_BUILD_X11 TRUE CACHE BOOL "" FORCE)
set(GLFW_BUILD_WAYLAND TRUE CACHE BOOL "" FORCE) set(GLFW_BUILD_WAYLAND TRUE CACHE BOOL "" FORCE)
set(GLFW_LIBRARY_TYPE "SHARED" CACHE BOOL "" FORCE) set(GLFW_LIBRARY_TYPE "SHARED" CACHE BOOL "" FORCE)
set(MESSAGE_QUIET TRUE)
add_subdirectory(src EXCLUDE_FROM_ALL) add_subdirectory(src EXCLUDE_FROM_ALL)
unset(MESSAGE_QUIET)
# Ensure Build
add_custom_target(glfw-build ALL DEPENDS glfw)
# Install # Install
install(TARGETS glfw DESTINATION "${MCPI_LIB_DIR}") install(TARGETS glfw DESTINATION "${MCPI_LIB_DIR}")

@ -1 +1 @@
Subproject commit b4c3ef9d0fdf46845f3e81e5d989dab06e71e6c1 Subproject commit 7b6aead9fb88b3623e3b3725ebb42670cbe4c579

View File

@ -3,23 +3,26 @@ project(qemu)
## QEMU ## QEMU
# Version # Version
set(QEMU_VERSION "8.1.3") set(QEMU_VERSION "8.2.1")
# Flatpak Support # Flatpak Support
set(QEMU_PATCH "") set(QEMU_FLATPAK_PATCH "")
if(MCPI_IS_FLATPAK_BUILD) if(MCPI_IS_FLATPAK_BUILD)
set(QEMU_PATCH "sed" "-i" "s/libdrm/libdrm-dis/g" "<SOURCE_DIR>/meson.build") set(QEMU_FLATPAK_PATCH "sed" "-i" "s/libdrm/libdrm-dis/g" "<SOURCE_DIR>/meson.build")
endif() endif()
# Build # Build
include(ProcessorCount)
ProcessorCount(NPROC)
include(ExternalProject) include(ExternalProject)
set(PKGCONFIG_ENV "")
if(DEFINED ENV{PKG_CONFIG_LIBDIR})
set(PKGCONFIG_ENV "PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}")
endif()
ExternalProject_Add(qemu ExternalProject_Add(qemu
URL "file://${CMAKE_CURRENT_SOURCE_DIR}/../../archives/qemu-${QEMU_VERSION}.tar.xz" URL "${CMAKE_CURRENT_SOURCE_DIR}/../../archives/qemu-${QEMU_VERSION}.tar.xz"
# Configure Build
CONFIGURE_COMMAND CONFIGURE_COMMAND
"${CMAKE_COMMAND}" "-E" "env" "${CMAKE_COMMAND}" "-E" "env"
"PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}" ${PKGCONFIG_ENV}
"CFLAGS=-s" "CFLAGS=-s"
"CXXFLAGS=-s" "CXXFLAGS=-s"
"<SOURCE_DIR>/configure" "<SOURCE_DIR>/configure"
@ -27,16 +30,21 @@ ExternalProject_Add(qemu
"--cross-prefix=" "--cross-prefix="
"--cc=${CMAKE_C_COMPILER}" "--cc=${CMAKE_C_COMPILER}"
"--cxx=${CMAKE_CXX_COMPILER}" "--cxx=${CMAKE_CXX_COMPILER}"
"--extra-ldflags=-ldl -Wl,-rpath=$ORIGIN/../lib/native -Wl,--disable-new-dtags"
"--disable-debug-info" "--disable-debug-info"
"--target-list=arm-linux-user" "--target-list=arm-linux-user"
"--without-default-features" "--without-default-features"
USES_TERMINAL_CONFIGURE TRUE USES_TERMINAL_CONFIGURE TRUE
BUILD_COMMAND "make" "-j${NPROC}" "qemu-arm" # Build Command
BUILD_COMMAND "ninja" "qemu-arm"
BUILD_BYPRODUCTS "<BINARY_DIR>/qemu-arm"
USES_TERMINAL_BUILD TRUE USES_TERMINAL_BUILD TRUE
# Disable Install/Test Commands
INSTALL_COMMAND "" INSTALL_COMMAND ""
TEST_COMMAND "" TEST_COMMAND ""
PATCH_COMMAND ${QEMU_PATCH} # Patch Command
BUILD_BYPRODUCTS "<BINARY_DIR>/qemu-arm" PATCH_COMMAND "patch" "-p1" "<" "${CMAKE_CURRENT_SOURCE_DIR}/trampoline.patch"
COMMAND ${QEMU_FLATPAK_PATCH}
) )
# Install # Install

56
dependencies/qemu/trampoline.patch vendored Normal file
View File

@ -0,0 +1,56 @@
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -17,6 +17,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#define _ATFILE_SOURCE
+#include <dlfcn.h>
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qemu/path.h"
@@ -9070,6 +9071,17 @@ _syscall5(int, sys_move_mount, int, __from_dfd, const char *, __from_pathname,
int, __to_dfd, const char *, __to_pathname, unsigned int, flag)
#endif
+// g2h For Trampoline
+static CPUState *_trampoline_g2h_cpu = NULL;
+static void *_trampoline_g2h(uint32_t guest_addr) {
+ if (guest_addr == 0) {
+ return NULL;
+ }
+ return g2h(_trampoline_g2h_cpu, guest_addr);
+}
+// Trampoline Function
+typedef void (*_trampoline_t)(typeof(_trampoline_g2h) *g2h, uint32_t id, uint32_t *args);
+
/* This is an internal helper for do_syscall so that it is easier
* to have a single return point, so that actions, such as logging
* of syscall results, can be performed.
@@ -9095,6 +9107,27 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
void *p;
switch(num) {
+ case 0x1337: {
+ // Load Trampoline
+ static _trampoline_t _trampoline = NULL;
+ if (_trampoline == NULL) {
+ // Open Library
+ void *_trampoline_handle = dlopen("libmedia-layer-trampoline.so", RTLD_NOW);
+ // Load Function
+ if (_trampoline_handle != NULL) {
+ _trampoline = dlsym(_trampoline_handle, "trampoline");
+ }
+ }
+ if (_trampoline == NULL) {
+ // Failed To Load
+ qemu_log_mask(LOG_UNIMP, "Unable To Load Media Layer Trampoline: %s\n", dlerror());
+ return -TARGET_ENOSYS;
+ }
+ // Call Trampoline
+ _trampoline_g2h_cpu = cpu;
+ _trampoline(_trampoline_g2h, arg1, g2h(cpu, arg2));
+ return 0;
+ }
case TARGET_NR_exit:
/* In old applications this may be used to implement _exit(2).
However in threaded applications it is used for thread termination,

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 eb49f25fa45842ebff448cbadd347c883e66efb6

View File

@ -6,7 +6,9 @@ add_compile_options(-w)
## Zenity ## Zenity
# Download # Download
set(MESSAGE_QUIET TRUE)
add_subdirectory(src EXCLUDE_FROM_ALL) add_subdirectory(src EXCLUDE_FROM_ALL)
unset(MESSAGE_QUIET)
# Ensure Build # Ensure Build
add_custom_target(zenity-build ALL DEPENDS zenity) add_custom_target(zenity-build ALL DEPENDS zenity)

View File

@ -14,7 +14,7 @@
2. If a setting is cached, then the dialog's default value will be the cached value instead of the normal default. 2. If a setting is cached, then the dialog's default value will be the cached value instead of the normal default.
3. When configuration has been completed, the settings specified will be cached. 3. When configuration has been completed, the settings specified will be cached.
2. The launcher replaces itself with MCPI. 2. The launcher replaces itself with MCPI.
1. MCPI-Reborn components are loaded using ``LD_PRELOAD`` and ``LD_LIBRARY_PATH``. 1. MCPI-Reborn components are loaded using `LD_PRELOAD` and `LD_LIBRARY_PATH`.
2. If the Media Layer Proxy is enabled, then the Media Layer Proxy Client is started as a sub-process. 2. If the Media Layer Proxy is enabled, then the Media Layer Proxy Client is started as a sub-process.
### Server ### Server
@ -27,11 +27,11 @@
This component configures the various environmental variables required for MCPI-Reborn to work. When running in client-mode, this component will also launch several Zenity dialogs for interactive configuration. 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: The environmental variables configured by this component includes:
* ``LD_PRELOAD`` * `LD_PRELOAD`
* ``LD_LIBRARY_PATH`` * `LD_LIBRARY_PATH`
* ``MCPI_FEATURE_FLAGS`` * `MCPI_FEATURE_FLAGS`
* ``MCPI_RENDER_DISTANCE`` * `MCPI_RENDER_DISTANCE`
* ``MCPI_USERNAME`` * `MCPI_USERNAME`
This is always compiled for the host system's architecture. This is always compiled for the host system's architecture.
@ -78,11 +78,11 @@ This is always compiled for ARM.
This sub-component includes headers for SDL, GLES, and EGL allowing easy (cross-)compilation. This sub-component includes headers for SDL, GLES, and EGL allowing easy (cross-)compilation.
### Mods ### Mods
This component patches MCPI to modify its behavior. It's loaded using ``LD_PRELOAD``. This component patches MCPI to modify its behavior. It's loaded using `LD_PRELOAD`.
This is always compiled for ARM. This is always compiled for ARM.
### ``libreborn`` ### `libreborn`
This component contains various utility functions including: This component contains various utility functions including:
* Code Patching (ARM Only) * Code Patching (ARM Only)
@ -91,7 +91,7 @@ This component contains various utility functions including:
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). 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`` ### `symbols`
This component contains all MCPI symbols. This component contains all MCPI symbols.
## Dependencies ## Dependencies

View File

@ -9,14 +9,5 @@
## Instructions ## Instructions
```sh ```sh
./scripts/build.sh <client|server> <armhf|arm64|i686|amd64> ./scripts/build.mjs <none|appimage|flatpak> <client|server> <armhf|arm64|amd64|host> [--clean] [--install] [-Dvar=value...]
``` ```
### 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>
```
### Environment Variables
* ``MCPI_TOOLCHAIN_USE_DEFAULT_SEARCH_PATHS``: Use Default CMake Search Paths Rather Than Guessing

View File

@ -1,41 +1,74 @@
# Changelog # 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
* Add `Animated Lava` Feature Flag (Enabled By Default)
* Add `Animated Fire` Feature Flag (Enabled By Default)
* Add `Use Java Beta 1.3 Light Ramp` Feature Flag (Enabled By Default)
* Add `Send Full Level When Hosting Game` Feature Flag (Enabled By Default)
* Add `Food Overlay` Feature Flag (Disabled By Default)
* Add `Display Date In Select World Screen` Feature Flag (Enabled By Default)
* Add `Optimized Chunk Sorting` Feature Flag (Enabled By Default)
* Add `Add Cake` Feature Flag (Enabled By Default)
* Add `Add Reborn Info To Options` Feature Flag (Enabled By Default)
* Add `Track FPS` Feature Flag (Disabled By Default)
* 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)
* Rename `Disable Buggy Held Item Caching` Feature Flag To `Fix Held Item Caching`
* Add Milk Buckets
* Implement Crafting Remainders
* Improve Death Messages
* Massive Build System Improvements
* Fix Item Dropping When Killing Players From The Server Console
* Fix Furnace Visual Bug When Using Lava Bucket As Fuel
* Add Splash Text To Start Screen
* `overwrite_calls` Now Scans VTables
**2.5.3** **2.5.3**
* Add ``Replace Block Highlight With Outline`` Feature Flag (Enabled By Default) * Add `Replace Block Highlight With Outline` Feature Flag (Enabled By Default)
* By Default, The Outline Width Is Set Using The GUI Scale * By Default, The Outline Width Is Set Using The GUI Scale
* This Can Be Overridden Using The ``MCPI_BLOCK_OUTLINE_WIDTH`` Environmental Variable * This Can Be Overridden Using The `MCPI_BLOCK_OUTLINE_WIDTH` Environmental Variable
* Added ``overwrite_calls_within`` Function * Added `overwrite_calls_within` Function
**2.5.2** **2.5.2**
* Add ``3D Chest Model`` Feature Flag (Enabled By Default) * Add `3D Chest Model` Feature Flag (Enabled By Default)
* Stop Using Jenkins * Stop Using Jenkins
* Replace ``iconv`` * Replace `iconv`
* Replace LibPNG * Replace LibPNG
**2.5.1** **2.5.1**
* Allow Overriding Custom Skin Server Using ``MCPI_SKIN_SERVER`` Environmental Variable * Allow Overriding Custom Skin Server Using `MCPI_SKIN_SERVER` Environmental Variable
* Fix Bug With SDK Generation * Fix Bug With SDK Generation
**2.5.0** **2.5.0**
* [Custom skin support](CUSTOM_SKINS.md)! * [Custom skin support](CUSTOM_SKINS.md)!
* Add ``Load Custom Skins`` Feature Flag (Enabled By Default) * Add `Load Custom Skins` Feature Flag (Enabled By Default)
**2.4.9** **2.4.9**
* Allow Overriding GUI Scale With ``MCPI_GUI_SCALE`` Environmental Variable * Allow Overriding GUI Scale With `MCPI_GUI_SCALE` Environmental Variable
* Add ``Disable Block Tinting`` Feature Flag (Disabled By Default) * Add `Disable Block Tinting` Feature Flag (Disabled By Default)
* Add ``Disable Hostile AI In Creative Mode`` Feature Flag (Enabled 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) * Allow Accessing Configuration At Runtime (Useful For Mods That Need To Support Multiple Versions)
**2.4.8** **2.4.8**
* Fix Bug In ``extract_from_bl_instruction`` * Fix Bug In `extract_from_bl_instruction`
* Update LIEF And GLFW * Update LIEF And GLFW
* Allow Mods To Access The Original GLFW Keycode For Key Events (But Better) * Allow Mods To Access The Original GLFW Keycode For Key Events (But Better)
* More Accurate Sound * More Accurate Sound
**2.4.7** **2.4.7**
* Improve Server Performance * Improve Server Performance
* Add ``Add Biome Colors To Grass`` Feature Flag (Disabled By Default) * Add `Add Biome Colors To Grass` Feature Flag (Disabled By Default)
* Add ``Generate Caves`` Feature Flag (Enabled By Default) * Add `Generate Caves` Feature Flag (Enabled By Default)
* Allow Mods To Access The Original GLFW Keycode For Key Events * Allow Mods To Access The Original GLFW Keycode For Key Events
**2.4.6** **2.4.6**
@ -49,16 +82,16 @@
**2.4.4** **2.4.4**
* Cache Previous Launcher Configuration * Cache Previous Launcher Configuration
* Add ``MCPI_API_PORT`` Environmental Variable * Add `MCPI_API_PORT` Environmental Variable
* Fix Particles In Front-Facing View * Fix Particles In Front-Facing View
* Fixed Launch Crash On Ubuntu ARM64 * Fixed Launch Crash On Ubuntu ARM64
* PatchELF Replaced With LIEF * PatchELF Replaced With LIEF
* Moved ``3D Anaglyph`` Feature Flag To Options Screen * Moved `3D Anaglyph` Feature Flag To Options Screen
* Add ``Improved Classic Title Screen`` Feature Flag (Enabled By Default) * Add `Improved Classic Title Screen` Feature Flag (Enabled By Default)
* Add Quit button * Add Quit button
* Add Options Button (Moved From ``Fix Options Screen`` Feature Flag) * Add Options Button (Moved From `Fix Options Screen` Feature Flag)
* Add ``Disable Speed Bridging`` Feature Flag (Disabled By Default) * Add `Disable Speed Bridging` Feature Flag (Disabled By Default)
* Add ``Disable Creative Mode Mining Delay`` Feature Flag (Disabled By Default) * Add `Disable Creative Mode Mining Delay` Feature Flag (Disabled By Default)
* Improved Feature Flag Names * Improved Feature Flag Names
* Miscellaneous Bug Fixes * Miscellaneous Bug Fixes
* Improved Build System * Improved Build System
@ -80,11 +113,11 @@
* More Reliable AppImages * More Reliable AppImages
* CMake Refactors * CMake Refactors
* Disable Broken Touchscreen-Specific Block Outline Behavior * Disable Broken Touchscreen-Specific Block Outline Behavior
* Add ``Remove Forced GUI Lag (Can Break Joining Servers)`` Feature Flag (Disabled By Default) * Add `Remove Forced GUI Lag (Can Break Joining Servers)` Feature Flag (Disabled By Default)
* Add ``Add Buckets`` Feature Flag (Enabled By Default) * Add `Add Buckets` Feature Flag (Enabled By Default)
* Add ``Classic HUD`` Feature Flag (Enabled By Default) * Add `Classic HUD` Feature Flag (Enabled By Default)
* Add ``Translucent Toolbar`` Feature Flag (Enabled By Default) * Add `Translucent Toolbar` Feature Flag (Enabled By Default)
* Add ``Force EGL`` Feature Flag (Disabled By Default) * Add `Force EGL` Feature Flag (Disabled By Default)
* Fix Sound Pitch/Volume/Attenuation * Fix Sound Pitch/Volume/Attenuation
* Fix Holding Left-Click When Attacking * Fix Holding Left-Click When Attacking
* Don't Force EGL (Should Fix Some NVIDIA Systems) * Don't Force EGL (Should Fix Some NVIDIA Systems)
@ -98,7 +131,7 @@
* Bug Fixes * Bug Fixes
**2.3.11** **2.3.11**
* ``--version`` Command Line Option * `--version` Command Line Option
* TPS Measured In Benchmark & Server * TPS Measured In Benchmark & Server
* Front-Facing Third-Person * Front-Facing Third-Person
* GLESv1 Comparability Layer * GLESv1 Comparability Layer
@ -124,39 +157,39 @@
* Don't Append Hyphens To New World Name, Only Folder Names * Don't Append Hyphens To New World Name, Only Folder Names
**2.3.6** **2.3.6**
* Fix ``Invert Y-axis`` Option Name * Fix `Invert Y-axis` Option Name
* Improve Touch GUI Inventory In Non-Touch GUI * Improve Touch GUI Inventory In Non-Touch GUI
* New Create World Dialog * New Create World Dialog
* Controlled By ``Implement Create World Dialog`` Feature Flag (Enabled By Default) * Controlled By `Implement Create World Dialog` Feature Flag (Enabled By Default)
* Custom World Names * Custom World Names
* Game-Mode Selection * Game-Mode Selection
* Custom Seeds * Custom Seeds
**2.3.5** **2.3.5**
* Renamed Some Feature Flags * Renamed Some Feature Flags
* Add ``Improved Title Background`` Feature Flag (Enabled By Default) * Add `Improved Title Background` Feature Flag (Enabled By Default)
* Non-Touch GUI Rework * Non-Touch GUI Rework
* Make ``Full Touch GUI`` Feature Flag Disabled By Default * Make `Full Touch GUI` Feature Flag Disabled By Default
* Add ``Force Touch GUI Button Behavior`` Feature Flag (Enabled By Default) * Add `Force Touch GUI Button Behavior` Feature Flag (Enabled By Default)
* Add ``Improved Button Hover Behavior`` Feature Flag (Enabled By Default) * Add `Improved Button Hover Behavior` Feature Flag (Enabled By Default)
**2.3.4** **2.3.4**
* AppImage Fixes * AppImage Fixes
* Make Death Messages Customizable Server-Side * Make Death Messages Customizable Server-Side
* Fix Q-Key Behavior Behavior When Editing Signs * Fix Q-Key Behavior Behavior When Editing Signs
* Add ``Force Touch Inventory`` Feature Flag (Disabled By Default) * Add `Force Touch Inventory` Feature Flag (Disabled By Default)
* Add ``Fix Pause Menu`` Feature Flag (Enabled By Default) * Add `Fix Pause Menu` Feature Flag (Enabled By Default)
* Enables Server Visibility Toggle Button * Enables Server Visibility Toggle Button
* Options Changes (Not Supported On Legacy) * 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 * Adds Options Button To Classic UI Start Screen
* Removes Useless Options Toggles * Removes Useless Options Toggles
* Fixes Options Toggles' Default Position * Fixes Options Toggles' Default Position
* Store Multiple Settings In `options.txt` * Store Multiple Settings In `options.txt`
* ``Peaceful Mode`` Feature Flag Moved To ``game_difficulty`` * `Peaceful Mode` Feature Flag Moved To `game_difficulty`
* ``Smooth Lighting`` Feature Flag Moved To ``gfx_ao`` * `Smooth Lighting` Feature Flag Moved To `gfx_ao`
* ``Fancy Graphics`` Feature Flag Moved To ``gfx_fancygraphics`` * `Fancy Graphics` Feature Flag Moved To `gfx_fancygraphics`
* ``Disable Hosting LAN Worlds`` Feature Flag Moved To ``mp_server_visible_default`` * `Disable Hosting LAN Worlds` Feature Flag Moved To `mp_server_visible_default`
**2.3.3** **2.3.3**
* Add More Blocks To Expanded Creative Inventory * Add More Blocks To Expanded Creative Inventory
@ -167,30 +200,30 @@
* Add More Blocks To Expanded Creative Inventory * Add More Blocks To Expanded Creative Inventory
* Fix Nether Reactor With Creative Restrictions Disabled * Fix Nether Reactor With Creative Restrictions Disabled
* Alphabetize Feature Flags * Alphabetize Feature Flags
* Add ``Disable V-Sync`` Feature Flag (Disabled By Default) * Add `Disable V-Sync` Feature Flag (Disabled By Default)
**2.3.1** **2.3.1**
* Internal Refactor Of ``libreborn`` * Internal Refactor Of `libreborn`
* Remove Use Of ``/bin/sh`` * Remove Use Of `/bin/sh`
* Load Custom Mods First * Load Custom Mods First
* Use Zenity Dark Mode * 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** **2.3.0**
* Switch To AppImage For Packaging * Switch To AppImage For Packaging
* Prevent OpenAL From Crashing When Out Of Memory * Prevent OpenAL From Crashing When Out Of Memory
* Vendor GLFW & Zenity * Vendor GLFW & Zenity
* Seamless Wayland Support * Seamless Wayland Support
* Add ``MCPI_DEBUG`` Environmental Variable * Add `MCPI_DEBUG` Environmental Variable
* Add ``Disable Hosting LAN Worlds`` Feature Flag (Disabled By Default) * Add `Disable Hosting LAN Worlds` Feature Flag (Disabled By Default)
* Add ``Fix Furnace Not Checking Item Auxiliary`` Feature Flag (Enabled 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 `Disable Raw Mouse Motion (Not Recommended)` Feature Flag (Disabled By Default) For Broken X11 Setups
* Added Back `~/.minecraft-pi/mods` * Added Back `~/.minecraft-pi/mods`
* Improve Build System * Improve Build System
* Improve Documentation * Improve Documentation
**2.2.11** **2.2.11**
* Add ``Close Current Screen On Death`` Feature Flag (Enabled By Default) To Prevent Bugs * 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" * Fix More Furnace UI Bugs When Using "Disable 'gui_blocks' Atlas"
**2.2.10** **2.2.10**
@ -201,8 +234,8 @@
* Store Files In `/usr/lib` * Store Files In `/usr/lib`
**2.2.8** **2.2.8**
* Add ``Hide Chat Messages`` Optional Feature Flag * Add `Hide Chat Messages` Optional Feature Flag
* Add ``Remove Creative Mode Restrictions`` Optional Feature Flag * Add `Remove Creative Mode Restrictions` Optional Feature Flag
* Improve GLFW->SDL Mouse Motion Event Conversion * Improve GLFW->SDL Mouse Motion Event Conversion
* Performance Optimizations * Performance Optimizations
* Make Majority Of Server-Specific Logging Code Also Apply To The Client * Make Majority Of Server-Specific Logging Code Also Apply To The Client
@ -234,15 +267,15 @@
* Make Missing Sound Event Cause Warning Rather Than Crash * Make Missing Sound Event Cause Warning Rather Than Crash
**2.2.1** **2.2.1**
* Prevent ``random.burp`` Sound From Crashing Game * Prevent `random.burp` Sound From Crashing Game
* Always Cleanup Media Layer, Even On Crash * Always Cleanup Media Layer, Even On Crash
* Resolve All Sounds On Startup * Resolve All Sounds On Startup
**2.2.0** **2.2.0**
* Sound Support * 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 * 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 * Clean-Up Code
* Remove Support For Debian Buster * Remove Support For Debian Buster
@ -259,7 +292,7 @@
* Print Error Message If RakNet Fails To Start * Print Error Message If RakNet Fails To Start
**2.1.4** **2.1.4**
* Fix ``RakNet::RakString`` Security Bug * Fix `RakNet::RakString` Security Bug
**2.1.3** **2.1.3**
* Workaround Broken Library Search Path On Some ARM 32-Bit Systems * Workaround Broken Library Search Path On Some ARM 32-Bit Systems
@ -271,16 +304,16 @@
* Fix Symlink Code * Fix Symlink Code
**2.1.0** **2.1.0**
* Allow Binding ``Q`` Key To Item Dropping * Allow Binding `Q` Key To Item Dropping
* Expose More Feature Flags * Expose More Feature Flags
* Replace ``Mob Spawning`` Feature Flag With ``Force Mob Spawning`` * Replace `Mob Spawning` Feature Flag With `Force Mob Spawning`
* Fix ``ESC`` Key In Options Menu When ``Miscellaneous Input Fixes`` Is Enabled * Fix `ESC` Key In Options Menu When `Miscellaneous Input Fixes` Is Enabled
**2.0.9** **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** **2.0.8**
* Use Default Port In ``servers.txt`` If Not Specified * Use Default Port In `servers.txt` If Not Specified
**2.0.7** **2.0.7**
* Fix Sign Text Not Updating In Multiplayer When Exiting Editing UI Using Escape Button * Fix Sign Text Not Updating In Multiplayer When Exiting Editing UI Using Escape Button
@ -297,7 +330,7 @@
* Optimize Media Layer Proxy * Optimize Media Layer Proxy
**2.0.3** **2.0.3**
* Make ``kill`` Admin Command Print Death Message * Make `kill` Admin Command Print Death Message
**2.0.2** **2.0.2**
* Fix Mouse Cursor Bugs * Fix Mouse Cursor Bugs

View File

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

View File

@ -3,4 +3,4 @@ MCPI-Reborn supports downloading custom skins from [a central skin server](https
This *does not* cache skins and *will not* work without internet access. This *does not* cache skins and *will not* work without internet access.
Custom skins can be disabled using the ``Load Custom Skins`` feature flag. Custom skins can be disabled using the `Load Custom Skins` feature flag.

View File

@ -1,10 +1,10 @@
# Dedicated Server # 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[^1]. This server is also compatible with MCPE Alpha v0.6.1[^1].
## Setup ## Setup
To use, install and run the ``minecraft-pi-reborn-server`` AppImage. It will generate the world and ``server.properties`` in the current directory. To use, install and run the `minecraft-pi-reborn-server` AppImage. It will generate the world and `server.properties` in the current directory.
## Server Limitations ## Server Limitations
* Player data is not saved because of limitations with MCPE LAN worlds * Player data is not saved because of limitations with MCPE LAN worlds

View File

@ -4,18 +4,18 @@
Download packages [here](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases). Download packages [here](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases).
### System Requirements ### System Requirements
* Debian Buster/Ubuntu 18.04 Or Higher * Debian Bullseye/Ubuntu 20.04 Or Higher
* FUSE 2 * FUSE 2
* Debian/Ubuntu: ``sudo apt install libfuse2`` * Debian/Ubuntu: `sudo apt install libfuse2`
* Arch: ``sudo pacman -S fuse2`` * Arch: `sudo pacman -S fuse2`
* Client-Only Dependencies * Client-Only Dependencies
* Graphics Drivers * Graphics Drivers
* GTK+ 3 * GTK+ 3
* Debian/Ubuntu: ``sudo apt install libgtk-3-0`` * Debian/Ubuntu: `sudo apt install libgtk-3-0`
* Arch: ``sudo pacman -S gtk3`` * Arch: `sudo pacman -S gtk3`
* OpenAL * OpenAL
* Debian/Ubuntu: ``sudo apt install libopenal1`` * Debian/Ubuntu: `sudo apt install libopenal1`
* Arch: ``sudo pacman -S openal`` * Arch: `sudo pacman -S openal`
### Running ### Running
Follow [these](https://docs.appimage.org/introduction/quickstart.html#how-to-run-an-appimage) instructions. Follow [these](https://docs.appimage.org/introduction/quickstart.html#how-to-run-an-appimage) instructions.
@ -24,7 +24,7 @@ Follow [these](https://docs.appimage.org/introduction/quickstart.html#how-to-run
<a href="https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn"><img width="240" alt="Download On Flathub" src="https://flathub.org/assets/badges/flathub-badge-en.svg" /></a> <a href="https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn"><img width="240" alt="Download On Flathub" src="https://flathub.org/assets/badges/flathub-badge-en.svg" /></a>
### Note ### Note
Game data is stored in ``~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi`` instead of ``~/.minecraft-pi``. Game data is stored in `~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi` instead of `~/.minecraft-pi`.
## Arch User Repository (Arch Linux Only) ## Arch User Repository (Arch Linux Only)
The [``minecraft-pi-reborn-git``](https://aur.archlinux.org/packages/minecraft-pi-reborn-git) is available in the AUR. The [`minecraft-pi-reborn-git`](https://aur.archlinux.org/packages/minecraft-pi-reborn-git) is available in the AUR.

View File

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

View File

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

View File

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

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

View File

@ -14,4 +14,4 @@ include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cma
# Build # Build
add_library(chat-commands SHARED chat-commands.cpp) add_library(chat-commands SHARED chat-commands.cpp)
target_link_libraries(chat-commands mods-headers reborn-patch symbols chat misc) target_link_libraries(chat-commands mods reborn-patch symbols)

View File

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

View File

@ -14,4 +14,4 @@ include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cma
# Build # Build
add_library(expanded-creative SHARED expanded-creative.cpp) add_library(expanded-creative SHARED expanded-creative.cpp)
target_link_libraries(expanded-creative mods-headers reborn-patch symbols misc) target_link_libraries(expanded-creative mods reborn-patch symbols)

View File

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

View File

@ -14,4 +14,4 @@ include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cma
# Build # Build
add_library(recipes SHARED recipes.cpp) add_library(recipes SHARED recipes.cpp)
target_link_libraries(recipes mods-headers reborn-util symbols misc) target_link_libraries(recipes mods reborn-util symbols)

View File

@ -1,11 +1,10 @@
// Headers // Headers
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#include <symbols/minecraft.h> #include <symbols/minecraft.h>
#include <mods/misc/misc.h> #include <mods/misc/misc.h>
// Custom Crafting Recipes // Custom Crafting Recipes
static void Recipes_injection(unsigned char *recipes) { static void Recipes_injection(Recipes *recipes) {
// Add // Add
Recipes_Type type1 = { Recipes_Type type1 = {
.item = 0, .item = 0,
@ -32,13 +31,19 @@ static void Recipes_injection(unsigned char *recipes) {
.id = 344, .id = 344,
.auxiliary = 0 .auxiliary = 0
}; };
(*Recipes_addShapelessRecipe)(recipes, result, {type1, type2}); std::vector<Recipes_Type> types = {type1, type2};
Recipes_addShapelessRecipe(recipes, &result, &types);
} }
// Custom Furnace Recipes // Custom Furnace Recipes
static void FurnaceRecipes_injection(unsigned char *recipes) { static void FurnaceRecipes_injection(FurnaceRecipes *recipes) {
// Add // Add
(*FurnaceRecipes_addFurnaceRecipe)(recipes, 49, {.count = 1, .id = 246, .auxiliary = 0}); ItemInstance result = {
.count = 1,
.id = 246,
.auxiliary = 0
};
FurnaceRecipes_addFurnaceRecipe(recipes, 49, &result);
} }
// Init // Init

View File

@ -1,16 +1,28 @@
project(launcher) project(launcher)
# Launcher # Launcher
add_executable(launcher src/bootstrap.c src/patchelf.cpp src/util.c src/crash-report.c) add_executable(launcher
if(MCPI_SERVER_MODE) src/bootstrap.cpp
target_sources(launcher PRIVATE src/server/launcher.c) src/patchelf.cpp
else() src/util.c
src/crash-report.c
src/sdk.cpp
src/mods.cpp
src/options/parser.cpp
src/main.cpp
)
if(NOT MCPI_SERVER_MODE)
embed_resource(launcher src/client/available-feature-flags) embed_resource(launcher src/client/available-feature-flags)
target_sources(launcher PRIVATE src/client/launcher.cpp src/client/cache.cpp) target_sources(launcher PRIVATE
src/client/configuration.cpp
src/client/cache.cpp
src/client/available-feature-flags # Show In IDE
)
endif() endif()
target_link_libraries(launcher reborn-util LIB_LIEF) target_link_libraries(launcher reborn-util LIB_LIEF)
# RPath # RPath
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native") set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
target_link_options(launcher PRIVATE "LINKER:--disable-new-dtags")
# Install # Install
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}") install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")

View File

@ -1,520 +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 "util.h"
#include "bootstrap.h"
#include "patchelf.h"
#include "crash-report.h"
// 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 Accessible
int result = access(name, R_OK);
if (result == 0) {
// Add To LD_PRELOAD
string_append(ld_preload, "%s%s", *ld_preload == NULL ? "" : ":", name);
} else if (result == -1 && errno != 0) {
// Fail
WARN("Unable To Access: %s: %s", name, strerror(errno));
errno = 0;
}
}
} else if (errno != 0) {
// Error Reading Contents Of Folder
ERR("Error Reading Directory: %s: %s", folder, strerror(errno));
} else {
// Done!
break;
}
}
// Close Folder
closedir(dp);
// 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"
#ifndef __ARM_ARCH
#define USE_QEMU
#endif
#define REQUIRED_PAGE_SIZE 4096
#define _STR(x) #x
#define STR(x) _STR(x)
// Exit Handler
static void exit_handler(__attribute__((unused)) int signal_id) {
// Pass Signal To Child
murder_children();
while (wait(NULL) > 0) {}
_exit(EXIT_SUCCESS);
}
// Debug Information
static void run_debug_command(const char *const command[], const char *prefix) {
int status = 0;
char *output = run_command(command, &status, NULL);
if (output != NULL) {
// Remove Newline
size_t length = strlen(output);
if (length > 0 && output[length - 1] == '\n') {
output[length - 1] = '\0';
}
// Print
DEBUG("%s: %s", prefix, output);
free(output);
}
if (!is_exit_status_success(status)) {
ERR("Unable To Gather Debug Information");
}
}
static void print_debug_information() {
// System Information
const char *const command[] = {"uname", "-a", NULL};
run_debug_command(command, "System Information");
// Version
DEBUG("Reborn Version: v%s", MCPI_VERSION);
// Architecture
const char *arch = "Unknown";
#ifdef __x86_64__
arch = "AMD64";
#elif defined(__aarch64__)
arch = "ARM64";
#elif defined(__arm__)
arch = "ARM32";
#endif
DEBUG("Reborn Target Architecture: %s", arch);
}
// Pre-Bootstrap
void pre_bootstrap(int argc, char *argv[]) {
// Set Debug Tag
reborn_debug_tag = "(Launcher) ";
// Disable stdout Buffering
setvbuf(stdout, NULL, _IONBF, 0);
// Print Version
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0) {
// Print
printf("Reborn v%s\n", MCPI_VERSION);
fflush(stdout);
exit(EXIT_SUCCESS);
}
}
// Setup Logging
setup_log_file();
// --debug
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--debug") == 0) {
set_and_print_env("MCPI_DEBUG", "1");
break;
}
}
// Set Default Native Component Environment
#define set_variable_default(name) set_and_print_env("MCPI_NATIVE_" name, getenv(name));
for_each_special_environmental_variable(set_variable_default);
// GTK Dark Mode
#ifndef MCPI_SERVER_MODE
set_and_print_env("GTK_THEME", "Adwaita:dark");
#endif
// Get Binary Directory
char *binary_directory = get_binary_directory();
// Configure PATH
{
// Add Library Directory
char *new_path = NULL;
safe_asprintf(&new_path, "%s/bin", binary_directory);
// Add Existing PATH
{
char *value = getenv("PATH");
if (value != NULL && strlen(value) > 0) {
string_append(&new_path, ":%s", value);
}
}
// Set And Free
set_and_print_env("PATH", new_path);
free(new_path);
}
// Free Binary Directory
free(binary_directory);
// Setup Crash Reports
setup_crash_report();
// AppImage
#ifdef MCPI_IS_APPIMAGE_BUILD
{
char *owd = getenv("OWD");
if (owd != NULL && chdir(owd) != 0) {
ERR("AppImage: Unable To Fix Current Directory: %s", strerror(errno));
}
}
#endif
// Install Signal Handlers
struct sigaction act_sigint;
memset((void *) &act_sigint, 0, sizeof (struct sigaction));
act_sigint.sa_flags = SA_RESTART;
act_sigint.sa_handler = &exit_handler;
sigaction(SIGINT, &act_sigint, NULL);
struct sigaction act_sigterm;
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
act_sigterm.sa_flags = SA_RESTART;
act_sigterm.sa_handler = &exit_handler;
sigaction(SIGTERM, &act_sigterm, NULL);
// Check Page Size (Not Needed When Using QEMU)
#ifndef USE_QEMU
long page_size = sysconf(_SC_PAGESIZE);
if (page_size != REQUIRED_PAGE_SIZE) {
ERR("Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
}
#endif
// Debug Information
print_debug_information();
}
// Copy SDK Into ~/.minecraft-pi
#define HOME_SUBDIRECTORY_FOR_SDK HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk"
static void copy_sdk(char *binary_directory) {
// Ensure SDK Directory
{
char *sdk_path = NULL;
safe_asprintf(&sdk_path, "%s" HOME_SUBDIRECTORY_FOR_SDK, getenv("HOME"));
const char *const command[] = {"mkdir", "-p", sdk_path, NULL};
run_simple_command(command, "Unable To Create SDK Directory");
}
// Lock File
char *lock_file_path = NULL;
safe_asprintf(&lock_file_path, "%s" HOME_SUBDIRECTORY_FOR_SDK "/.lock", getenv("HOME"));
int lock_file_fd = lock_file(lock_file_path);
// Output Directory
char *output = NULL;
safe_asprintf(&output, "%s" HOME_SUBDIRECTORY_FOR_SDK "/" MCPI_SDK_DIR, getenv("HOME"));
// Source Directory
char *source = NULL;
safe_asprintf(&source, "%s/sdk/.", binary_directory);
// Clean
{
const char *const command[] = {"rm", "-rf", output, NULL};
run_simple_command(command, "Unable To Clean SDK Output Directory");
}
// Make Directory
{
const char *const command[] = {"mkdir", "-p", output, NULL};
run_simple_command(command, "Unable To Create SDK Output Directory");
}
// Copy
{
const char *const command[] = {"cp", "-ar", source, output, NULL};
run_simple_command(command, "Unable To Copy SDK");
}
// Free
free(output);
free(source);
// Unlock File
unlock_file(lock_file_path, lock_file_fd);
free(lock_file_path);
}
// Bootstrap
void bootstrap(int argc, char *argv[]) {
INFO("Configuring Game...");
// Get Binary Directory
char *binary_directory = get_binary_directory();
DEBUG("Binary Directory: %s", binary_directory);
// Copy SDK
copy_sdk(binary_directory);
// Set MCPI_REBORN_ASSETS_PATH
{
char *assets_path = realpath("/proc/self/exe", NULL);
ALLOC_CHECK(assets_path);
chop_last_component(&assets_path);
string_append(&assets_path, "/data");
set_and_print_env("MCPI_REBORN_ASSETS_PATH", assets_path);
free(assets_path);
}
// Resolve Binary Path & Set MCPI_DIRECTORY
char *resolved_path = NULL;
{
// Log
DEBUG("Resolving File Paths...");
// Resolve Full Binary Path
char *full_path = NULL;
safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory);
resolved_path = realpath(full_path, NULL);
ALLOC_CHECK(resolved_path);
free(full_path);
}
// Fix MCPI Dependencies
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
{
// Log
DEBUG("Patching ELF Dependencies...");
// Find Linker
char *linker = NULL;
// Select Linker
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
// Use ARM Sysroot Linker
safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory);
#else
// Use Current Linker
linker = patch_get_interpreter();
#endif
// Patch
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker);
// Free Linker Path
if (linker != NULL) {
free(linker);
}
// Verify
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
IMPOSSIBLE();
}
}
// Set MCPI_VANILLA_ASSETS_PATH
{
char *assets_path = strdup(resolved_path);
ALLOC_CHECK(assets_path);
chop_last_component(&assets_path);
string_append(&assets_path, "/data");
set_and_print_env("MCPI_VANILLA_ASSETS_PATH", assets_path);
free(assets_path);
}
// Free Resolved Path
free(resolved_path);
// Configure Library Search Path
{
// Log
DEBUG("Setting Linker Search Paths...");
// Prepare
char *transitive_ld_path = NULL;
char *mcpi_ld_path = NULL;
// Library Search Path For Native Components
{
// Add Native Library Directory
safe_asprintf(&transitive_ld_path, "%s/lib/native", binary_directory);
// Add Host LD_LIBRARY_PATH
{
char *value = getenv("LD_LIBRARY_PATH");
if (value != NULL && strlen(value) > 0) {
string_append(&transitive_ld_path, ":%s", value);
}
}
// Set
set_and_print_env("MCPI_NATIVE_LD_LIBRARY_PATH", transitive_ld_path);
free(transitive_ld_path);
}
// Library Search Path For ARM Components
{
// Add ARM Library Directory
safe_asprintf(&mcpi_ld_path, "%s/lib/arm", binary_directory);
// Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System)
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
string_append(&mcpi_ld_path, ":%s/sysroot/lib:%s/sysroot/lib/arm-linux-gnueabihf:%s/sysroot/usr/lib:%s/sysroot/usr/lib/arm-linux-gnueabihf", binary_directory, binary_directory, binary_directory, binary_directory);
#endif
// Add Host LD_LIBRARY_PATH
{
char *value = getenv("LD_LIBRARY_PATH");
if (value != NULL && strlen(value) > 0) {
string_append(&mcpi_ld_path, ":%s", value);
}
}
// Set
set_and_print_env("MCPI_ARM_LD_LIBRARY_PATH", mcpi_ld_path);
free(mcpi_ld_path);
}
}
// Configure Preloaded Objects
{
// Log
DEBUG("Locating Mods...");
// Native Components
char *host_ld_preload = getenv("LD_PRELOAD");
set_and_print_env("MCPI_NATIVE_LD_PRELOAD", host_ld_preload);
// ARM Components
{
// Prepare
char *preload = NULL;
// ~/.minecraft-pi/mods
{
// Get Mods Folder
char *mods_folder = NULL;
safe_asprintf(&mods_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA "/mods/", getenv("HOME"));
// Load Mods From ./mods
load(&preload, mods_folder);
// Free Mods Folder
free(mods_folder);
}
// Built-In Mods
{
// Get Mods Folder
char *mods_folder = NULL;
safe_asprintf(&mods_folder, "%s/mods/", binary_directory);
// Load Mods From ./mods
load(&preload, mods_folder);
// Free Mods Folder
free(mods_folder);
}
// Add LD_PRELOAD
{
char *value = getenv("LD_PRELOAD");
if (value != NULL && strlen(value) > 0) {
string_append(&preload, ":%s", value);
}
}
// Set
set_and_print_env("MCPI_ARM_LD_PRELOAD", preload);
free(preload);
}
}
// 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] = new_mcpi_exe_path;
// Non-ARM Systems Need QEMU
#ifdef USE_QEMU
argv_start--;
new_args[argv_start] = QEMU_BINARY;
// Use 4k Page Size
set_and_print_env("QEMU_PAGESIZE", STR(REQUIRED_PAGE_SIZE));
#endif
// Setup Environment
setup_exec_environment(1);
// Pass LD_* Variables Through QEMU
#ifdef USE_QEMU
char *qemu_set_env = NULL;
#define pass_variable_through_qemu(name) string_append(&qemu_set_env, "%s%s=%s", qemu_set_env == NULL ? "" : ",", name, getenv(name));
for_each_special_environmental_variable(pass_variable_through_qemu);
set_and_print_env("QEMU_SET_ENV", qemu_set_env);
free(qemu_set_env);
// Treat QEMU Itself As A Native Component
setup_exec_environment(0);
#endif
// Run
const char **new_argv = &new_args[argv_start];
safe_execvpe(new_argv, (const char *const *) environ);
}

226
launcher/src/bootstrap.cpp Normal file
View File

@ -0,0 +1,226 @@
#define _FILE_OFFSET_BITS 64
#include <string>
#include <vector>
#include <libreborn/libreborn.h>
#include "util.h"
#include "bootstrap.h"
#include "patchelf.h"
#define MCPI_BINARY "minecraft-pi"
#define QEMU_BINARY "qemu-arm"
#define REQUIRED_PAGE_SIZE 4096
#define _STR(x) #x
#define STR(x) _STR(x)
// Debug Information
static void run_debug_command(const char *const command[], const char *prefix) {
int status = 0;
char *output = run_command(command, &status, nullptr);
if (output != nullptr) {
// Remove Newline
size_t length = strlen(output);
if (length > 0 && output[length - 1] == '\n') {
output[length - 1] = '\0';
}
// Print
DEBUG("%s: %s", prefix, output);
free(output);
}
if (!is_exit_status_success(status)) {
ERR("Unable To Gather Debug Information");
}
}
static void print_debug_information() {
// System Information
const char *const command[] = {"uname", "-a", nullptr};
run_debug_command(command, "System Information");
// Version
DEBUG("Reborn Version: v%s", MCPI_VERSION);
// Architecture
const char *arch = "Unknown";
#ifdef __x86_64__
arch = "AMD64";
#elif defined(__aarch64__)
arch = "ARM64";
#elif defined(__arm__)
arch = "ARM32";
#endif
DEBUG("Reborn Target Architecture: %s", arch);
}
// Bootstrap
void bootstrap() {
// Debug Information
print_debug_information();
// Check Page Size (Not Needed When Using QEMU)
#ifndef MCPI_USE_QEMU
long page_size = sysconf(_SC_PAGESIZE);
if (page_size != REQUIRED_PAGE_SIZE) {
ERR("Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
}
#else
set_and_print_env("QEMU_PAGESIZE", STR(REQUIRED_PAGE_SIZE));
#endif
// Get Binary Directory
char *binary_directory_raw = get_binary_directory();
const std::string binary_directory = binary_directory_raw;
free(binary_directory_raw);
DEBUG("Binary Directory: %s", binary_directory.c_str());
// Copy SDK
copy_sdk(binary_directory, true);
// Set MCPI_REBORN_ASSETS_PATH
{
char *assets_path = realpath("/proc/self/exe", nullptr);
ALLOC_CHECK(assets_path);
chop_last_component(&assets_path);
string_append(&assets_path, "/data");
set_and_print_env("MCPI_REBORN_ASSETS_PATH", assets_path);
free(assets_path);
}
// Resolve Binary Path & Set MCPI_DIRECTORY
char *resolved_path = nullptr;
{
// Log
DEBUG("Resolving File Paths...");
// Resolve Full Binary Path
const std::string full_path = binary_directory + ("/" MCPI_BINARY);
resolved_path = realpath(full_path.c_str(), nullptr);
ALLOC_CHECK(resolved_path);
}
// Fix MCPI Dependencies
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
{
// Log
DEBUG("Patching ELF Dependencies...");
// Find Linker
char *linker = nullptr;
// Select Linker
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
// Use ARM Sysroot Linker
safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory.c_str());
#else
// Use Current Linker
linker = patch_get_interpreter();
#endif
// Patch
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker);
// Free Linker Path
if (linker != nullptr) {
free(linker);
}
// Verify
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
IMPOSSIBLE();
}
}
// Set MCPI_VANILLA_ASSETS_PATH
{
char *assets_path = strdup(resolved_path);
ALLOC_CHECK(assets_path);
chop_last_component(&assets_path);
string_append(&assets_path, "/data");
set_and_print_env("MCPI_VANILLA_ASSETS_PATH", assets_path);
free(assets_path);
}
// Free Resolved Path
free(resolved_path);
// Configure Library Search Path
{
// Log
DEBUG("Setting Linker Search Paths...");
// Prepare
std::string mcpi_ld_path = "";
// Library Search Path For ARM Components
{
// Add ARM Library Directory
mcpi_ld_path += binary_directory + "/lib/arm:";
// Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System)
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
mcpi_ld_path += binary_directory + "/sysroot/lib:";
mcpi_ld_path += binary_directory + "/sysroot/lib/arm-linux-gnueabihf:";
mcpi_ld_path += binary_directory + "/sysroot/usr/lib:";
mcpi_ld_path += binary_directory + "/sysroot/usr/lib/arm-linux-gnueabihf:";
#endif
// Add Host LD_LIBRARY_PATH
{
char *value = getenv("LD_LIBRARY_PATH");
if (value != nullptr && strlen(value) > 0) {
mcpi_ld_path += value;
}
}
// Set
set_and_print_env(MCPI_LD_VARIABLE_PREFIX "LD_LIBRARY_PATH", mcpi_ld_path.c_str());
}
}
// Configure Preloaded Objects
{
// Log
DEBUG("Locating Mods...");
// ARM Components
bootstrap_mods(binary_directory);
}
// Start Game
INFO("Starting Game...");
// Arguments
std::vector<std::string> args;
// Non-ARM Systems Need QEMU
#ifdef MCPI_USE_QEMU
args.insert(args.begin(), QEMU_BINARY);
#endif
// Preserve Existing LD_* Variables
#define preserve_variable(name) set_and_print_env(MCPI_ORIGINAL_LD_VARIABLE_PREFIX name, getenv(name))
for_each_special_environmental_variable(preserve_variable);
set_and_print_env(MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV, "1");
// Setup Environment
setup_exec_environment(1);
// Pass LD_* Variables Through QEMU
#ifdef MCPI_USE_QEMU
#define pass_variable_through_qemu(name) args.push_back("-E"); args.push_back(std::string(name) + "=" + getenv(name))
for_each_special_environmental_variable(pass_variable_through_qemu);
// Treat QEMU Itself As A Native Component
setup_exec_environment(0);
#endif
// Specify MCPI Binary
args.push_back(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

@ -1,12 +1,7 @@
#pragma once #pragma once
#ifdef __cplusplus #include <string>
extern "C" {
#endif
void pre_bootstrap(int argc, char *argv[]); void bootstrap();
void bootstrap(int argc, char *argv[]); void copy_sdk(const std::string &binary_directory, bool log_with_debug);
void bootstrap_mods(const std::string &binary_directory);
#ifdef __cplusplus
}
#endif

View File

@ -8,7 +8,13 @@ TRUE Fix Sign Placement
TRUE Show Block Outlines TRUE Show Block Outlines
FALSE Expand Creative Mode Inventory FALSE Expand Creative Mode Inventory
FALSE Remove Creative Mode Restrictions FALSE Remove Creative Mode Restrictions
FALSE Display Slot Count In Creative Mode
FALSE Force Survival Mode Inventory UI
FALSE Force Survival Mode Inventory Behavior
FALSE Maximize Creative Mode Inventory Stack Size
TRUE Animated Water TRUE Animated Water
TRUE Animated Lava
TRUE Animated Fire
TRUE Remove Invalid Item Background TRUE Remove Invalid Item Background
TRUE Disable "gui_blocks" Atlas TRUE Disable "gui_blocks" Atlas
TRUE Fix Camera Rendering TRUE Fix Camera Rendering
@ -51,3 +57,13 @@ TRUE Disable Hostile AI In Creative Mode
TRUE Load Custom Skins TRUE Load Custom Skins
TRUE 3D Chest Model TRUE 3D Chest Model
TRUE Replace Block Highlight With Outline TRUE Replace Block Highlight With Outline
TRUE Add Cake
TRUE Use Java Beta 1.3 Light Ramp
TRUE Send Full Level When Hosting Game
FALSE Food Overlay
TRUE Add Splashes
TRUE Display Date In Select World Screen
TRUE Optimized Chunk Sorting
TRUE Fix Held Item Caching
TRUE Add Reborn Info To Options
FALSE Track FPS

View File

@ -8,13 +8,13 @@
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#include "launcher.h" #include "configuration.h"
#include "cache.h" #include "cache.h"
// Get Cache Path // Get Cache Path
static std::string get_cache_path() { static std::string get_cache_path() {
const char *home = getenv("HOME"); const char *home = getenv("HOME");
if (home == NULL) { if (home == nullptr) {
IMPOSSIBLE(); IMPOSSIBLE();
} }
return std::string(home) + HOME_SUBDIRECTORY_FOR_GAME_DATA "/.launcher-cache"; return std::string(home) + HOME_SUBDIRECTORY_FOR_GAME_DATA "/.launcher-cache";

View File

@ -10,25 +10,24 @@
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#include "../util.h" #include "../util.h"
#include "../bootstrap.h" #include "configuration.h"
#include "launcher.h"
#include "cache.h" #include "cache.h"
// Strip Feature Flag Default // Strip Feature Flag Default
std::string strip_feature_flag_default(std::string flag, bool *default_ret) { std::string strip_feature_flag_default(const std::string &flag, bool *default_ret) {
// Valid Values // Valid Values
std::string true_str = "TRUE "; std::string true_str = "TRUE ";
std::string false_str = "FALSE "; std::string false_str = "FALSE ";
// Test // Test
if (flag.rfind(true_str, 0) == 0) { if (flag.rfind(true_str, 0) == 0) {
// Enabled By Default // Enabled By Default
if (default_ret != NULL) { if (default_ret != nullptr) {
*default_ret = true; *default_ret = true;
} }
return flag.substr(true_str.length(), std::string::npos); return flag.substr(true_str.length(), std::string::npos);
} else if (flag.rfind(false_str, 0) == 0) { } else if (flag.rfind(false_str, 0) == 0) {
// Disabled By Default // Disabled By Default
if (default_ret != NULL) { if (default_ret != nullptr) {
*default_ret = false; *default_ret = false;
} }
return flag.substr(false_str.length(), std::string::npos); return flag.substr(false_str.length(), std::string::npos);
@ -41,7 +40,7 @@ std::string strip_feature_flag_default(std::string flag, bool *default_ret) {
// Load Available Feature Flags // Load Available Feature Flags
extern unsigned char available_feature_flags[]; extern unsigned char available_feature_flags[];
extern size_t available_feature_flags_len; extern size_t available_feature_flags_len;
void load_available_feature_flags(std::function<void(std::string)> callback) { void load_available_feature_flags(const std::function<void(std::string)> &callback) {
// Get Path // Get Path
char *binary_directory = get_binary_directory(); char *binary_directory = get_binary_directory();
std::string path = std::string(binary_directory) + "/available-feature-flags"; std::string path = std::string(binary_directory) + "/available-feature-flags";
@ -55,7 +54,7 @@ void load_available_feature_flags(std::function<void(std::string)> callback) {
{ {
std::string line; std::string line;
while (std::getline(stream, line)) { while (std::getline(stream, line)) {
if (line.length() > 0) { if (!line.empty()) {
// Verify Line // Verify Line
if (line.find('|') == std::string::npos) { if (line.find('|') == std::string::npos) {
lines.push_back(line); lines.push_back(line);
@ -67,15 +66,15 @@ void load_available_feature_flags(std::function<void(std::string)> callback) {
} }
} }
// Sort // Sort
std::sort(lines.begin(), lines.end(), [](std::string a, std::string b) { std::sort(lines.begin(), lines.end(), [](const std::string &a, const std::string &b) {
// Strip Defaults // Strip Defaults
std::string stripped_a = strip_feature_flag_default(a, NULL); std::string stripped_a = strip_feature_flag_default(a, nullptr);
std::string stripped_b = strip_feature_flag_default(b, NULL); std::string stripped_b = strip_feature_flag_default(b, nullptr);
// Sort // Sort
return stripped_a < stripped_b; return stripped_a < stripped_b;
}); });
// Run Callbacks // Run Callbacks
for (std::string &line : lines) { for (const std::string &line : lines) {
callback(line); callback(line);
} }
} }
@ -83,11 +82,11 @@ void load_available_feature_flags(std::function<void(std::string)> callback) {
// Run Command And Set Environmental Variable // Run Command And Set Environmental Variable
static void run_command_and_set_env(const char *env_name, const char *command[]) { static void run_command_and_set_env(const char *env_name, const char *command[]) {
// Only Run If Environmental Variable Is NULL // Only Run If Environmental Variable Is NULL
if (getenv(env_name) == NULL) { if (getenv(env_name) == nullptr) {
// Run // Run
int return_code; int return_code;
char *output = run_command(command, &return_code, NULL); char *output = run_command(command, &return_code, nullptr);
if (output != NULL) { if (output != nullptr) {
// Trim // Trim
int length = strlen(output); int length = strlen(output);
if (output[length - 1] == '\n') { if (output[length - 1] == '\n') {
@ -122,14 +121,14 @@ static void run_zenity_and_set_env(const char *env_name, std::vector<std::string
for (std::vector<std::string>::size_type i = 0; i < full_command.size(); i++) { for (std::vector<std::string>::size_type i = 0; i < full_command.size(); i++) {
full_command_array[i] = full_command[i].c_str(); full_command_array[i] = full_command[i].c_str();
} }
full_command_array[full_command.size()] = NULL; full_command_array[full_command.size()] = nullptr;
// Run // Run
run_command_and_set_env(env_name, full_command_array); run_command_and_set_env(env_name, full_command_array);
} }
// Set Variable If Not Already Set // Set Variable If Not Already Set
static void set_env_if_unset(const char *env_name, std::function<std::string()> callback) { static void set_env_if_unset(const char *env_name, const std::function<std::string()> &callback) {
if (getenv(env_name) == NULL) { if (getenv(env_name) == nullptr) {
char *value = strdup(callback().c_str()); char *value = strdup(callback().c_str());
ALLOC_CHECK(value); ALLOC_CHECK(value);
set_and_print_env(env_name, value); set_and_print_env(env_name, value);
@ -137,76 +136,50 @@ static void set_env_if_unset(const char *env_name, std::function<std::string()>
} }
} }
// Launch // Handle Non-Launch Commands
#define LIST_DIALOG_SIZE "400" void handle_non_launch_client_only_commands(const options_t &options) {
int main(int argc, char *argv[]) { // Print Available Feature Flags
// Don't Run As Root if (options.print_available_feature_flags) {
if (getenv("_MCPI_SKIP_ROOT_CHECK") == NULL && (getuid() == 0 || geteuid() == 0)) { load_available_feature_flags([](const std::string &line) {
ERR("Don't Run As Root"); printf("%s\n", line.c_str());
fflush(stdout);
});
exit(EXIT_SUCCESS);
}
} }
// Ensure HOME // Check Environment
if (getenv("HOME") == NULL) { void check_environment_client() {
ERR("$HOME Isn't Set"); // Don't Run As Root
if (getenv("_MCPI_SKIP_ROOT_CHECK") == nullptr && (getuid() == 0 || geteuid() == 0)) {
ERR("Don't Run As Root");
} }
// Check For Display // Check For Display
#ifndef MCPI_HEADLESS_MODE #ifndef MCPI_HEADLESS_MODE
if (getenv("DISPLAY") == NULL && getenv("WAYLAND_DISPLAY") == NULL) { if (getenv("DISPLAY") == nullptr && getenv("WAYLAND_DISPLAY") == nullptr) {
ERR("No display attached! Make sure $DISPLAY or $WAYLAND_DISPLAY is set."); ERR("No display attached! Make sure $DISPLAY or $WAYLAND_DISPLAY is set.");
} }
#endif #endif
// Print Features
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--print-available-feature-flags") == 0) {
// Print Available Feature Flags
load_available_feature_flags([](std::string line) {
printf("%s\n", line.c_str());
fflush(stdout);
});
return 0;
}
} }
// Pre-Bootstrap // Configure Client Options
pre_bootstrap(argc, argv); #define LIST_DIALOG_SIZE "400"
void configure_client(const options_t &options) {
// Create ~/.minecraft-pi If Needed // Wipe Cache If Needed
{ if (options.wipe_cache) {
char *minecraft_folder = NULL;
safe_asprintf(&minecraft_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA, getenv("HOME"));
const char *const command[] = {"mkdir", "-p", minecraft_folder, NULL};
run_simple_command(command, "Unable To Create Data Directory");
free(minecraft_folder);
}
// --wipe-cache
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--wipe-cache") == 0) {
wipe_cache(); wipe_cache();
break;
}
} }
// --no-cache
bool no_cache = false;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--no-cache") == 0) {
no_cache = true;
break;
}
}
// Load Cache // Load Cache
launcher_cache cache = no_cache ? empty_cache : load_cache(); launcher_cache cache = options.no_cache ? empty_cache : load_cache();
// --default // --default
for (int i = 1; i < argc; i++) { if (options.use_default) {
if (strcmp(argv[i], "--default") == 0) {
// Use Default Feature Flags // Use Default Feature Flags
set_env_if_unset("MCPI_FEATURE_FLAGS", [&cache]() { set_env_if_unset("MCPI_FEATURE_FLAGS", [&cache]() {
std::string feature_flags = ""; std::string feature_flags = "";
load_available_feature_flags([&feature_flags, &cache](std::string flag) { load_available_feature_flags([&feature_flags, &cache](const std::string &flag) {
bool value; bool value;
// Strip Default Value // Strip Default Value
std::string stripped_flag = strip_feature_flag_default(flag, &value); std::string stripped_flag = strip_feature_flag_default(flag, &value);
@ -220,7 +193,7 @@ int main(int argc, char *argv[]) {
feature_flags += stripped_flag + '|'; feature_flags += stripped_flag + '|';
} }
}); });
if (feature_flags.length() > 0 && feature_flags[feature_flags.length() - 1] == '|') { if (!feature_flags.empty() && feature_flags[feature_flags.length() - 1] == '|') {
feature_flags.pop_back(); feature_flags.pop_back();
} }
return feature_flags; return feature_flags;
@ -231,8 +204,6 @@ int main(int argc, char *argv[]) {
set_env_if_unset("MCPI_USERNAME", [&cache]() { set_env_if_unset("MCPI_USERNAME", [&cache]() {
return cache.username; return cache.username;
}); });
break;
}
} }
// Setup MCPI_FEATURE_FLAGS // Setup MCPI_FEATURE_FLAGS
@ -248,7 +219,7 @@ int main(int argc, char *argv[]) {
command.push_back("Enabled"); command.push_back("Enabled");
command.push_back("--column"); command.push_back("--column");
command.push_back("Feature"); command.push_back("Feature");
load_available_feature_flags([&command, &cache](std::string flag) { load_available_feature_flags([&command, &cache](const std::string &flag) {
bool value; bool value;
// Strip Default Value // Strip Default Value
std::string stripped_flag = strip_feature_flag_default(flag, &value); std::string stripped_flag = strip_feature_flag_default(flag, &value);
@ -287,7 +258,7 @@ int main(int argc, char *argv[]) {
command.push_back("Name"); command.push_back("Name");
std::string render_distances[] = {"Far", "Normal", "Short", "Tiny"}; std::string render_distances[] = {"Far", "Normal", "Short", "Tiny"};
for (std::string &render_distance : render_distances) { for (std::string &render_distance : render_distances) {
command.push_back(render_distance.compare(cache.render_distance) == 0 ? "TRUE" : "FALSE"); command.push_back(render_distance == cache.render_distance ? "TRUE" : "FALSE");
command.push_back(render_distance); command.push_back(render_distance);
} }
// Run // Run
@ -306,10 +277,7 @@ int main(int argc, char *argv[]) {
} }
// Save Cache // Save Cache
if (!no_cache) { if (!options.no_cache) {
save_cache(); save_cache();
} }
// Bootstrap
bootstrap(argc, argv);
} }

View File

@ -0,0 +1,23 @@
#pragma once
#include <string>
#include <functional>
#include "../options/parser.h"
// Defaults
#define DEFAULT_USERNAME "StevePi"
#define DEFAULT_RENDER_DISTANCE "Short"
// Feature Flags
std::string strip_feature_flag_default(const std::string& flag, bool *default_ret);
void load_available_feature_flags(const std::function<void(std::string)> &callback);
// Handle Non-Launch Commands
void handle_non_launch_client_only_commands(const options_t &options);
// Check Environment
void check_environment_client();
// Configure Client Options
void configure_client(const options_t &options);

View File

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

View File

@ -34,7 +34,7 @@ static void show_report(const char *log_filename) {
"--width", CRASH_REPORT_DIALOG_WIDTH, "--width", CRASH_REPORT_DIALOG_WIDTH,
"--height", CRASH_REPORT_DIALOG_HEIGHT, "--height", CRASH_REPORT_DIALOG_HEIGHT,
"--text-info", "--text-info",
"--text", MCPI_APP_BASE_TITLE " has crashed!\n\nNeed help? Consider asking on the <a href=\"https://discord.com/invite/aDqejQGMMy\">Discord server</a>! <i>If you believe this is a problem with " MCPI_APP_BASE_TITLE " itself, please upload this crash report to the #bugs Discord channel.</i>", "--text", MCPI_APP_BASE_TITLE " has crashed!\n\nNeed help? Consider asking on the <a href=\"" MCPI_DISCORD_INVITE "\">Discord server</a>! <i>If you believe this is a problem with " MCPI_APP_BASE_TITLE " itself, please upload this crash report to the #bugs Discord channel.</i>",
"--filename", log_filename, "--filename", log_filename,
"--no-wrap", "--no-wrap",
"--font", "Monospace", "--font", "Monospace",
@ -58,7 +58,6 @@ static void exit_handler(__attribute__((unused)) int signal) {
#define PIPE_WRITE 1 #define PIPE_WRITE 1
#define MCPI_LOGS_DIR "/tmp/.minecraft-pi-logs" #define MCPI_LOGS_DIR "/tmp/.minecraft-pi-logs"
static char log_filename[] = MCPI_LOGS_DIR "/XXXXXX"; static char log_filename[] = MCPI_LOGS_DIR "/XXXXXX";
static int log_file_fd = -1;
void setup_log_file() { void setup_log_file() {
// Ensure Temporary Directory // Ensure Temporary Directory
{ {
@ -74,16 +73,12 @@ void setup_log_file() {
} }
// Create Temporary File // Create Temporary File
log_file_fd = mkstemp(log_filename); int log_file_fd = mkstemp(log_filename);
if (log_file_fd == -1) { if (log_file_fd == -1) {
ERR("Unable To Create Log File: %s", strerror(errno)); ERR("Unable To Create Log File: %s", strerror(errno));
} }
close(log_file_fd);
// Setup Environment reborn_set_log(log_filename);
char *log_file_fd_env = NULL;
safe_asprintf(&log_file_fd_env, "%i", log_file_fd);
set_and_print_env("MCPI_LOG_FILE_FD", log_file_fd_env);
free(log_file_fd_env);
} }
void setup_crash_report() { void setup_crash_report() {
// Store Output // Store Output
@ -121,13 +116,11 @@ void setup_crash_report() {
track_child(ret); track_child(ret);
// Install Signal Handlers // Install Signal Handlers
struct sigaction act_sigint; struct sigaction act_sigint = {0};
memset((void *) &act_sigint, 0, sizeof (struct sigaction));
act_sigint.sa_flags = SA_RESTART; act_sigint.sa_flags = SA_RESTART;
act_sigint.sa_handler = &exit_handler; act_sigint.sa_handler = &exit_handler;
sigaction(SIGINT, &act_sigint, NULL); sigaction(SIGINT, &act_sigint, NULL);
struct sigaction act_sigterm; struct sigaction act_sigterm = {0};
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
act_sigterm.sa_flags = SA_RESTART; act_sigterm.sa_flags = SA_RESTART;
act_sigterm.sa_handler = &exit_handler; act_sigterm.sa_handler = &exit_handler;
sigaction(SIGTERM, &act_sigterm, NULL); sigaction(SIGTERM, &act_sigterm, NULL);
@ -178,17 +171,17 @@ void setup_crash_report() {
bytes_available = 0; bytes_available = 0;
} }
// Read // Read
ssize_t bytes_read = read(poll_fds[i].fd, (void *) buf, BUFFER_SIZE); ssize_t bytes_read = read(poll_fds[i].fd, buf, BUFFER_SIZE);
if (bytes_read == -1) { if (bytes_read == -1) {
ERR("Unable To Read Log Data: %s", strerror(errno)); ERR("Unable To Read Input: %s", strerror(errno));
} }
// Write To Child // Write To Child
if (write(input_pipe[PIPE_WRITE], (void *) buf, bytes_read) == -1) { if (write(input_pipe[PIPE_WRITE], buf, bytes_read) == -1) {
ERR("Unable To Write Input To Child: %s", strerror(errno)); ERR("Unable To Write Input To Child: %s", strerror(errno));
} }
} else { } else {
// Data Available From Child's stdout/stderr // Data Available From Child's stdout/stderr
ssize_t bytes_read = read(poll_fds[i].fd, (void *) buf, BUFFER_SIZE - 1 /* Account For NULL-Terminator */); ssize_t bytes_read = read(poll_fds[i].fd, buf, BUFFER_SIZE - 1 /* Account For NULL-Terminator */);
if (bytes_read == -1) { if (bytes_read == -1) {
ERR("Unable To Read Log Data: %s", strerror(errno)); ERR("Unable To Read Log Data: %s", strerror(errno));
} }
@ -198,9 +191,11 @@ void setup_crash_report() {
fprintf(poll_fds[i].fd == output_pipe[PIPE_READ] ? stdout : stderr, "%s", buf); fprintf(poll_fds[i].fd == output_pipe[PIPE_READ] ? stdout : stderr, "%s", buf);
// Write To log // Write To log
if (write(log_file_fd, (void *) buf, bytes_read) == -1) { reborn_lock_log();
if (write(reborn_get_log_fd(), buf, bytes_read) == -1) {
ERR("Unable To Write Log Data: %s", strerror(errno)); ERR("Unable To Write Log Data: %s", strerror(errno));
} }
reborn_unlock_log();
} }
} else { } else {
// File Descriptor No Longer Accessible // File Descriptor No Longer Accessible
@ -234,18 +229,19 @@ void setup_crash_report() {
fprintf(stderr, "%s", exit_code_line); fprintf(stderr, "%s", exit_code_line);
// Write Exit Code Log Line // Write Exit Code Log Line
if (write(log_file_fd, (void *) exit_code_line, strlen(exit_code_line)) == -1) { reborn_lock_log();
if (write(reborn_get_log_fd(), exit_code_line, strlen(exit_code_line)) == -1) {
ERR("Unable To Write Exit Code To Log: %s", strerror(errno)); ERR("Unable To Write Exit Code To Log: %s", strerror(errno));
} }
reborn_unlock_log();
// Free Exit Code Log Line // Free Exit Code Log Line
free(exit_code_line); free(exit_code_line);
} }
// Close Log File FD // Close Log File
if (close(log_file_fd) == -1) { reborn_close_log();
ERR("Unable To Close Log File Descriptor: %s", strerror(errno)); unsetenv(MCPI_LOG_ENV);
}
// Show Crash Log // Show Crash Log
#ifndef MCPI_HEADLESS_MODE #ifndef MCPI_HEADLESS_MODE

155
launcher/src/main.cpp Normal file
View File

@ -0,0 +1,155 @@
#include <cstdlib>
#include <libreborn/libreborn.h>
#include <sys/stat.h>
#include "bootstrap.h"
#include "options/parser.h"
#include "crash-report.h"
#include "util.h"
#ifndef MCPI_SERVER_MODE
#include "client/configuration.h"
#endif
// Bind Options To Environmental Variable
static void bind_to_env(const char *env, const bool value) {
const bool force = env[0] == '_';
if (force || value) {
set_and_print_env(env, value ? "1" : nullptr);
}
}
static void setup_environment(const options_t &options) {
// Passthrough Options To Game
#ifndef MCPI_SERVER_MODE
bind_to_env("_MCPI_BENCHMARK", options.benchmark);
#else
bind_to_env("_MCPI_ONLY_GENERATE", options.only_generate);
#endif
// GTK Dark Mode
#ifndef MCPI_HEADLESS_MODE
set_and_print_env("GTK_THEME", "Adwaita:dark");
#endif
// Configure PATH
{
// Get Binary Directory
char *binary_directory = get_binary_directory();
std::string new_path = std::string(binary_directory) + "/bin";
free(binary_directory);
// Add Existing PATH
{
char *value = getenv("PATH");
if (value != nullptr && strlen(value) > 0) {
new_path += std::string(":") + value;
}
}
// Set And Free
set_and_print_env("PATH", new_path.c_str());
}
}
// Non-Launch Commands
static void handle_non_launch_commands(const options_t &options) {
if (options.copy_sdk) {
char *binary_directory = get_binary_directory();
copy_sdk(binary_directory, false);
free(binary_directory);
fflush(stdout);
exit(EXIT_SUCCESS);
}
}
// Exit Handler
static void exit_handler(__attribute__((unused)) int signal_id) {
// Pass Signal To Child
murder_children();
while (wait(nullptr) > 0) {}
_exit(EXIT_SUCCESS);
}
// Start The Game
static void start_game(const options_t &options) {
// Disable stdout Buffering
setvbuf(stdout, nullptr, _IONBF, 0);
// Environemntal Variable Options
setup_environment(options);
// Setup Crash Reporting
if (!options.disable_crash_report) {
setup_log_file();
setup_crash_report();
}
// Install Signal Handlers
struct sigaction act_sigint = {};
act_sigint.sa_flags = SA_RESTART;
act_sigint.sa_handler = &exit_handler;
sigaction(SIGINT, &act_sigint, nullptr);
struct sigaction act_sigterm = {};
act_sigterm.sa_flags = SA_RESTART;
act_sigterm.sa_handler = &exit_handler;
sigaction(SIGTERM, &act_sigterm, nullptr);
// Setup Home
#ifndef MCPI_SERVER_MODE
// Ensure $HOME
const char *home = getenv("HOME");
if (home == nullptr) {
ERR("$HOME Isn't Set");
}
// Create If Needed
{
std::string minecraft_folder = std::string(home) + HOME_SUBDIRECTORY_FOR_GAME_DATA;
struct stat tmp_stat = {};
bool exists = stat(minecraft_folder.c_str(), &tmp_stat) != 0 ? false : S_ISDIR(tmp_stat.st_mode);
if (!exists) {
// Doesn't Exist
if (mkdir(minecraft_folder.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
ERR("Unable To Create Data Directory: %s", strerror(errno));
}
}
}
#else
// Set Home To Current Directory, So World Data Is Stored There
char *launch_directory = getcwd(NULL, 0);
set_and_print_env("HOME", launch_directory);
free(launch_directory);
#endif
// Configure Client Options
#ifndef MCPI_SERVER_MODE
configure_client(options);
#endif
// Bootstrap
bootstrap();
}
// Main
int main(int argc, char *argv[]) {
// Parse Options
options_t options = parse_options(argc, argv);
// Set Debug Tag
reborn_debug_tag = "(Launcher) ";
// Debug Logging
unsetenv(MCPI_LOG_ENV);
bind_to_env(MCPI_DEBUG_ENV, options.debug);
// Handle Non-Launch Commands (Copy SDK, Print Feature Flags, Etc)
handle_non_launch_commands(options);
#ifndef MCPI_SERVER_MODE
handle_non_launch_client_only_commands(options);
#endif
// Check Environment
#ifndef MCPI_SERVER_MODE
// Code After This Can Safely Open A Window
check_environment_client();
#endif
// Start The Game
start_game(options);
}

86
launcher/src/mods.cpp Normal file
View File

@ -0,0 +1,86 @@
#include <dirent.h>
#include <cerrno>
#include <sys/stat.h>
#include <unistd.h>
#include <libreborn/libreborn.h>
#include "bootstrap.h"
// Get All Mods In Folder
static void load(std::string &ld_preload, const std::string &folder) {
// Open Folder
DIR *dp = opendir(folder.c_str());
if (dp != nullptr) {
// Loop Through Folder
while (true) {
errno = 0;
dirent *entry = readdir(dp);
if (entry != nullptr) {
// Check If File Is Regular
if (entry->d_type == DT_REG) {
// Get Full Name
std::string name = folder + entry->d_name;
// Check If File Is Accessible
int result = access(name.c_str(), R_OK);
if (result == 0) {
// Add To LD_PRELOAD
ld_preload += name + ":";
} else if (result == -1 && errno != 0) {
// Fail
WARN("Unable To Access: %s: %s", name.c_str(), strerror(errno));
errno = 0;
}
}
} else if (errno != 0) {
// Error Reading Contents Of Folder
ERR("Error Reading Directory: %s: %s", folder.c_str(), strerror(errno));
} else {
// Done!
break;
}
}
// Close Folder
closedir(dp);
} else if (errno == ENOENT) {
// Folder Doesn't Exist
} else {
// Unable To Open Folder
ERR("Error Opening Directory: %s: %s", folder.c_str(), strerror(errno));
}
}
// Bootstrap Mods
#define SUBDIRECTORY_FOR_MODS "/mods/"
void bootstrap_mods(const std::string &binary_directory) {
// Prepare
std::string preload = "";
// ~/.minecraft-pi/mods
{
// Get Mods Folder
std::string mods_folder = std::string(getenv("HOME")) + HOME_SUBDIRECTORY_FOR_GAME_DATA SUBDIRECTORY_FOR_MODS;
// Load Mods From ./mods
load(preload, mods_folder);
}
// Built-In Mods
{
// Get Mods Folder
std::string mods_folder = binary_directory + SUBDIRECTORY_FOR_MODS;
// Load Mods From ./mods
load(preload, mods_folder);
}
// Add LD_PRELOAD
{
const char *value = getenv("LD_PRELOAD");
if (value != nullptr && strlen(value) > 0) {
preload += value;
}
}
// Set
set_and_print_env(MCPI_LD_VARIABLE_PREFIX "LD_PRELOAD", preload.c_str());
}

View File

@ -0,0 +1,12 @@
OPTION(debug, "debug", 'd', "Enable Debug Logging (" MCPI_DEBUG_ENV ")")
OPTION(copy_sdk, "copy-sdk", -2, "Extract Modding SDK And Exit")
OPTION(disable_crash_report, "disable-crash-report", -1, "Disable Crash Report Dialog")
#ifndef MCPI_SERVER_MODE
OPTION(use_default, "default", -3, "Skip Configuration Dialogs")
OPTION(no_cache, "no-cache", -4, "Disable Configuration Cache")
OPTION(wipe_cache, "wipe-cache", -5, "Wipe Cached Configuration")
OPTION(print_available_feature_flags, "print-available-feature-flags", -6, "Print Available Feature Flags")
OPTION(benchmark, "benchmark", -7, "Run Benchmark")
#else
OPTION(only_generate, "only-generate", -8, "Generate World And Exit")
#endif

View File

@ -0,0 +1,38 @@
#include <argp.h>
#include "parser.h"
// Globals
const char *argp_program_version = "Reborn v" MCPI_VERSION;
const char *argp_program_bug_address = "<" MCPI_DISCORD_INVITE ">";
static char doc[] = "Minecraft: Pi Edition Modding Project";
// Options
#define OPTION(ignored, name, key, doc) {name, key, nullptr, 0, doc, 0},
static argp_option options_data[] = {
#include "option-list.h"
{nullptr, 0, nullptr, 0, nullptr, 0}
};
#undef OPTION
// Parse Options
#define OPTION(name, ignored, key, ...) \
case key: \
options->name = true; \
break;
static error_t parse_opt(int key, __attribute__((unused)) char *arg, argp_state *state) {
options_t *options = (options_t *) state->input;
switch (key) {
#include "option-list.h"
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
#undef OPTION
static argp argp = {options_data, parse_opt, nullptr, doc, nullptr, nullptr, nullptr};
options_t parse_options(int argc, char *argv[]) {
options_t options = {};
argp_parse(&argp, argc, argv, 0, nullptr, &options);
return options;
}

View File

@ -0,0 +1,10 @@
#pragma once
#include <libreborn/libreborn.h>
#define OPTION(name, ...) bool name;
struct options_t {
#include "option-list.h"
};
#undef OPTION
options_t parse_options(int argc, char *argv[]);

View File

@ -3,6 +3,9 @@
#include <LIEF/ELF.hpp> #include <LIEF/ELF.hpp>
#include <dlfcn.h>
#include <link.h>
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#include "patchelf.h" #include "patchelf.h"

59
launcher/src/sdk.cpp Normal file
View File

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

View File

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

View File

@ -5,7 +5,7 @@ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/libreborn")
configure_file(include/libreborn/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/libreborn/config.h" ESCAPE_QUOTES @ONLY) configure_file(include/libreborn/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/libreborn/config.h" ESCAPE_QUOTES @ONLY)
# Util # Util
add_library(reborn-util SHARED src/util/elf.c src/util/exec.c src/util/string.c src/util/util.c src/util/log.c src/util/cp437.cpp) add_library(reborn-util SHARED src/util/exec.c src/util/string.c src/util/util.c src/util/log.c src/util/cp437.cpp)
target_include_directories( target_include_directories(
reborn-util reborn-util
PUBLIC PUBLIC
@ -25,7 +25,7 @@ endif()
# Patch # Patch
if(BUILD_ARM_COMPONENTS) if(BUILD_ARM_COMPONENTS)
add_library(reborn-patch SHARED src/patch/patch.c) add_library(reborn-patch SHARED src/patch/patch.cpp src/patch/segments.cpp src/patch/code-block.cpp src/patch/instruction.cpp)
target_link_libraries(reborn-patch dl pthread reborn-util) target_link_libraries(reborn-patch dl pthread reborn-util)
target_compile_definitions(reborn-patch PUBLIC -DREBORN_HAS_PATCH_CODE) target_compile_definitions(reborn-patch PUBLIC -DREBORN_HAS_PATCH_CODE)
# Install # Install
@ -36,13 +36,11 @@ endif()
# Fake LibPNG To Satisy Symbol Versioning Requirement # Fake LibPNG To Satisy Symbol Versioning Requirement
if(BUILD_ARM_COMPONENTS) if(BUILD_ARM_COMPONENTS)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/fake-libpng.c" "") add_library(fake-libpng SHARED src/fake-libpng/empty.c)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/fake-libpng.vers" "PNG12_0 { global: *; };")
add_library(fake-libpng SHARED "${CMAKE_CURRENT_BINARY_DIR}/fake-libpng.c")
set_target_properties(fake-libpng PROPERTIES set_target_properties(fake-libpng PROPERTIES
OUTPUT_NAME "png12" OUTPUT_NAME "png12"
SOVERSION 0 SOVERSION 0
LINK_OPTIONS "LINKER:--version-script=${CMAKE_CURRENT_BINARY_DIR}/fake-libpng.vers" LINK_OPTIONS "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/fake-libpng/empty.vers"
) )
# Install # Install
install(TARGETS fake-libpng DESTINATION "${MCPI_LIB_DIR}") install(TARGETS fake-libpng DESTINATION "${MCPI_LIB_DIR}")

View File

@ -3,6 +3,7 @@
#cmakedefine MCPI_SERVER_MODE #cmakedefine MCPI_SERVER_MODE
#cmakedefine MCPI_HEADLESS_MODE #cmakedefine MCPI_HEADLESS_MODE
#cmakedefine MCPI_IS_APPIMAGE_BUILD #cmakedefine MCPI_IS_APPIMAGE_BUILD
#cmakedefine MCPI_IS_FLATPAK_BUILD
#cmakedefine MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN #cmakedefine MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
#cmakedefine MCPI_USE_GLES1_COMPATIBILITY_LAYER #cmakedefine MCPI_USE_GLES1_COMPATIBILITY_LAYER
#cmakedefine MCPI_APP_BASE_TITLE "@MCPI_APP_BASE_TITLE@" #cmakedefine MCPI_APP_BASE_TITLE "@MCPI_APP_BASE_TITLE@"
@ -12,3 +13,5 @@
#cmakedefine MCPI_VARIANT_NAME "@MCPI_VARIANT_NAME@" #cmakedefine MCPI_VARIANT_NAME "@MCPI_VARIANT_NAME@"
#cmakedefine MCPI_SDK_DIR "@MCPI_SDK_DIR@" #cmakedefine MCPI_SDK_DIR "@MCPI_SDK_DIR@"
#cmakedefine MCPI_SKIN_SERVER "@MCPI_SKIN_SERVER@" #cmakedefine MCPI_SKIN_SERVER "@MCPI_SKIN_SERVER@"
#cmakedefine MCPI_USE_QEMU
#cmakedefine MCPI_DISCORD_INVITE "@MCPI_DISCORD_INVITE@"

View File

@ -1,22 +0,0 @@
#pragma once
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <elf.h>
#include <link.h>
#include "log.h"
#include "exec.h"
#ifdef __cplusplus
extern "C" {
#endif
// Find And Iterate Over All Segments In Current Binary
typedef void (*segment_callback_t)(ElfW(Addr) section, ElfW(Word) size, void *data);
void iterate_segments(segment_callback_t callback, void *data);
#ifdef __cplusplus
}
#endif

View File

@ -20,9 +20,12 @@ extern "C" {
void set_and_print_env(const char *name, const char *value); void set_and_print_env(const char *name, const char *value);
// Safe execvpe() // Safe execvpe()
#define MCPI_LD_VARIABLE_PREFIX "_MCPI_"
#define MCPI_ORIGINAL_LD_VARIABLE_PREFIX MCPI_LD_VARIABLE_PREFIX "ORIGINAL_"
#define MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV MCPI_ORIGINAL_LD_VARIABLE_PREFIX "PRESERVED"
#define for_each_special_environmental_variable(handle) \ #define for_each_special_environmental_variable(handle) \
handle("LD_LIBRARY_PATH"); \ handle("LD_LIBRARY_PATH"); \
handle("LD_PRELOAD"); handle("LD_PRELOAD")
void setup_exec_environment(int is_arm_component); void setup_exec_environment(int is_arm_component);
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]); __attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]);

View File

@ -5,6 +5,5 @@
#include "util.h" #include "util.h"
#include "string.h" #include "string.h"
#include "exec.h" #include "exec.h"
#include "elf.h"
#include "home.h" #include "home.h"
#include "patch.h" #include "patch.h"

View File

@ -7,14 +7,24 @@
extern "C" { extern "C" {
#endif #endif
// Debug // Log File
#define MCPI_LOG_ENV "_MCPI_LOG"
int reborn_get_log_fd();
void reborn_lock_log();
void reborn_unlock_log();
void reborn_close_log();
void reborn_set_log(const char *file);
// Debug Logging
#define MCPI_DEBUG_ENV "MCPI_DEBUG"
extern const char *reborn_debug_tag; extern const char *reborn_debug_tag;
int reborn_get_debug_fd(); int reborn_get_debug_fd();
void reborn_lock_debug();
void reborn_unlock_debug();
// Logging // Logging
#define INFO(format, ...) { fprintf(stderr, "[INFO]: " format "\n", ##__VA_ARGS__); } #define INFO(format, ...) { fprintf(stderr, "[INFO]: " format "\n", ##__VA_ARGS__); }
#define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", ##__VA_ARGS__); } #define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", ##__VA_ARGS__); }
#define RAW_DEBUG(tag, format, ...) { int debug_fd = reborn_get_debug_fd(); if (debug_fd != -1) { dprintf(debug_fd, "[DEBUG]: %s" format "\n", tag, ##__VA_ARGS__); } } #define RAW_DEBUG(tag, format, ...) { reborn_lock_debug(); dprintf(reborn_get_debug_fd(), "[DEBUG]: %s" format "\n", tag, ##__VA_ARGS__); reborn_unlock_debug(); }
#define DEBUG(format, ...) RAW_DEBUG(reborn_debug_tag, format, ##__VA_ARGS__) #define DEBUG(format, ...) RAW_DEBUG(reborn_debug_tag, format, ##__VA_ARGS__)
#define ERR(format, ...) { fprintf(stderr, "[ERR]: (%s:%i): " format "\n", __FILE__, __LINE__, ##__VA_ARGS__); exit(EXIT_FAILURE); } #define ERR(format, ...) { fprintf(stderr, "[ERR]: (%s:%i): " format "\n", __FILE__, __LINE__, ##__VA_ARGS__); exit(EXIT_FAILURE); }
#define IMPOSSIBLE() ERR("This Should Never Be Called") #define IMPOSSIBLE() ERR("This Should Never Be Called")

View File

@ -1,35 +1,133 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
// Patching Functions // Patching Functions
#ifdef REBORN_HAS_PATCH_CODE #if defined(REBORN_HAS_PATCH_CODE) && defined(__cplusplus)
// Init
void reborn_init_patch();
// Replace Call Located At start With A Call To target
void _overwrite_call(const char *file, int line, void *start, void *target); void _overwrite_call(const char *file, int line, void *start, void *target);
#define overwrite_call(start, target) _overwrite_call(__FILE__, __LINE__, start, target); #define overwrite_call(...) \
_overwrite_call(__FILE__, __LINE__, __VA_ARGS__)
void _overwrite_calls(const char *file, int line, void *start, void *target); // Make Sure Function Is Only Called Once
#define overwrite_calls(start, target) _overwrite_calls(__FILE__, __LINE__, start, target); template <int>
static void _only_call_once() {
static bool _has_run = false;
if (_has_run) {
ERR("\"Fancy\" overwrite*() Functions Can Only Be Called Once");
}
_has_run = true;
}
void _overwrite_calls_within(const char *file, int line, void *from, void *to, void *start, void *target); // Replace All Calls To Method start With target
#define overwrite_calls_within(from, to, start, target) _overwrite_calls(__FILE__, __LINE__, from, to, start, target); void *_overwrite_calls_manual(const char *file, int line, void *start, void *target);
#define overwrite_calls_manual(...) \
_overwrite_calls_manual(__FILE__, __LINE__, __VA_ARGS__)
template <int call_id, typename start_t, typename overwrite_t>
static void _overwrite_calls(const char *file, int line, start_t (*create_helper)(overwrite_t, start_t), start_t &start, overwrite_t target) {
_only_call_once<call_id>();
start_t helper = create_helper(target, start);
start = (start_t) _overwrite_calls_manual(file, line, (void *) start, (void *) helper);
}
#define overwrite_calls(start, ...) \
_overwrite_calls< \
__COUNTER__, \
start##_t, \
__overwrite_##start##_t \
>( \
__FILE__, __LINE__, \
__create_overwrite_helper_for_##start, \
start, \
__VA_ARGS__ \
)
// Replace All Calls To Virtual Method start With target
template <int call_id, typename start_t, typename overwrite_t>
static void _overwrite_virtual_calls(const char *file, int line, start_t (*create_helper)(overwrite_t, start_t), bool (*is_overwritable)(), start_t start, overwrite_t target) {
_only_call_once<call_id>();
if (!is_overwritable()) {
ERR("Virtual Method Is Not Overwritable");
}
start_t helper = create_helper(target, start);
_overwrite_calls_manual(file, line, (void *) start, (void *) helper);
}
#define overwrite_virtual_calls(start, ...) \
_overwrite_virtual_calls< \
__COUNTER__, \
start##_t, \
__overwrite_##start##_t \
>( \
__FILE__, __LINE__, \
__create_overwrite_helper_for_##start, \
__is_overwritable_##start, \
*start##_vtable_addr, \
__VA_ARGS__ \
)
// Replace All Calls To start With target Within [to, from)
void _overwrite_calls_within_manual(const char *file, int line, void *from, void *to, void *start, void *target);
#define overwrite_calls_within_manual(...) \
_overwrite_calls_within(__FILE__, __LINE__, __VA_ARGS__)
template <typename start_t>
void _overwrite_calls_within(const char *file, int line, void *from, void *to, start_t start, start_t target) {
_overwrite_calls_within_manual(file, line, from, to, (void *) start, (void *) target);
}
#define overwrite_calls_within(from, to, start, ...) \
_overwrite_calls_within< \
start##_t \
>( \
__FILE__, __LINE__, \
from, to, \
start, \
__VA_ARGS__ \
)
// Get Target Address From BL Instruction
void *extract_from_bl_instruction(unsigned char *from); void *extract_from_bl_instruction(unsigned char *from);
void _overwrite(const char *file, int line, void *start, void *target); // Replace Method start With target
#define overwrite(start, target) _overwrite(__FILE__, __LINE__, start, target); void _overwrite_manual(const char *file, int line, void *start, void *target);
#define overwrite_manual(...) \
void _patch(const char *file, int line, void *start, unsigned char patch[4]); _overwrite(__FILE__, __LINE__, __VA_ARGS__)
#define patch(start, patch) _patch(__FILE__, __LINE__, start, patch); template <typename start_t>
void _overwrite(const char *file, int line, start_t start, start_t target) {
void _patch_address(const char *file, int line, void *start, void *target); _overwrite_manual(file, line, (void *) start, (void *) target);
#define patch_address(start, target) _patch_address(__FILE__, __LINE__, start, target);
#endif
#ifdef __cplusplus
} }
#define overwrite(start, ...) \
_overwrite< \
start##_t \
>( \
__FILE__, __LINE__, \
start, \
__VA_ARGS__ \
)
// Patch Instruction
void _patch(const char *file, int line, void *start, unsigned char patch[4]);
#define patch(...) \
_patch(__FILE__, __LINE__, __VA_ARGS__)
// Patch 4 Bytes Of Data
void _patch_address(const char *file, int line, void *start, void *target);
#define patch_address(...) \
_patch_address(__FILE__, __LINE__, __VA_ARGS__)
// Patch VTable Entry
// This does not affect sub-classes.
template <typename start_t>
void _patch_vtable(const char *file, int line, start_t *start, start_t target) {
_patch_address(file, line, (void *) start, (void *) target);
}
#define patch_vtable(start, ...) \
_patch_vtable< \
start##_t \
>( \
__FILE__, __LINE__, \
start##_vtable_addr, \
__VA_ARGS__ \
)
#endif #endif

View File

@ -16,6 +16,11 @@
} }
// Hook Library Function // Hook Library Function
#ifdef __cplusplus
#define hooked_function_setup extern "C"
#else
#define hooked_function_setup
#endif
#define HOOK(name, return_type, args) \ #define HOOK(name, return_type, args) \
typedef return_type (*name##_t)args; \ typedef return_type (*name##_t)args; \
static name##_t real_##name = NULL; \ static name##_t real_##name = NULL; \
@ -30,7 +35,7 @@
} \ } \
} \ } \
\ \
__attribute__((__used__)) return_type name args hooked_function_setup __attribute__((__used__)) return_type name args
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -50,6 +55,25 @@ const char *reborn_get_version();
int reborn_is_headless(); int reborn_is_headless();
int reborn_is_server(); int reborn_is_server();
// Customize VTable
#define CUSTOM_VTABLE(name, parent) \
void _setup_##name##_vtable(parent##_vtable *vtable); \
static parent##_vtable *get_##name##_vtable() { \
static parent##_vtable *vtable = NULL; \
/* Allocate VTable */ \
if (vtable == NULL) { \
/* Init */ \
vtable = dup_##parent##_vtable(parent##_vtable_base); \
ALLOC_CHECK(vtable); \
/* Setup */ \
_setup_##name##_vtable(vtable); \
} \
/* Return */ \
return vtable; \
} \
/* User-Defined Setup Code */ \
void _setup_##name##_vtable(parent##_vtable *vtable)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

View File

@ -0,0 +1 @@
PNG12_0 { global: *; };

View File

@ -0,0 +1,46 @@
#include <sys/mman.h>
#include <libreborn/libreborn.h>
#include "patch-internal.h"
// Limit To 512 overwrite_calls() Uses
#define CODE_BLOCK_SIZE 4096
static unsigned char *code_block = NULL;
#define CODE_SIZE 8
static int code_block_remaining = CODE_BLOCK_SIZE;
// Create Long Overwrite At Current Position
static void long_overwrite(void *start, void *target) {
unsigned char patch_data[4] = {0x04, 0xf0, 0x1f, 0xe5}; // "ldr pc, [pc, #-0x4]"
_patch(NULL, -1, start, patch_data);
_patch_address(NULL, -1, (void *) (((unsigned char *) start) + 4), target);
}
void *update_code_block(void *target) {
// BL Instructions can only access a limited portion of memory.
// So this allocates memory closer to the original instruction,
// that when run, will jump into the actual target.
if (code_block == NULL) {
code_block = (unsigned char *) mmap((void *) 0x200000, CODE_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (code_block == MAP_FAILED) {
ERR("Unable To Allocate Code Block: %s", strerror(errno));
}
DEBUG("Code Block Allocated At: 0x%08x", (uint32_t) code_block);
// Store Segment
segment_data data;
data.start = code_block;
data.end = (void *) (((uintptr_t) code_block) + CODE_BLOCK_SIZE);
data.is_executable = true;
data.is_writable = true;
add_segment(data);
}
if (code_block_remaining < CODE_SIZE) {
ERR("Maximum Amount Of overwrite_calls() Uses Reached");
}
long_overwrite(code_block, target);
// Return
return code_block;
}
void increment_code_block() {
code_block = code_block + CODE_SIZE;
code_block_remaining = code_block_remaining - CODE_SIZE;
}

View File

@ -0,0 +1,50 @@
#include <libreborn/libreborn.h>
#include "patch-internal.h"
// Generate A BL Instruction
#define INSTRUCTION_RANGE 32000000
static uint64_t nice_diff_64(uint64_t a, uint64_t b) {
if (a > b) {
return a - b;
} else {
return b - a;
}
}
uint32_t generate_bl_instruction(void *from, void *to, int use_b_instruction) {
// Check Instruction Range
if (nice_diff_64((uint64_t) to, (uint64_t) from) > INSTRUCTION_RANGE) {
IMPOSSIBLE();
}
// Create New Instruction
uint32_t instruction;
unsigned char *instruction_array = (unsigned char *) &instruction;
instruction_array[3] = use_b_instruction ? B_INSTRUCTION : BL_INSTRUCTION;
// Determine PC
unsigned char *pc = ((unsigned char *) from) + 8;
int32_t offset = (int32_t) to - (int32_t) pc;
int32_t target = offset >> 2;
// Set Instruction Offset
unsigned char *target_array = (unsigned char *) &target;
instruction_array[0] = target_array[0];
instruction_array[1] = target_array[1];
instruction_array[2] = target_array[2];
// Return
return instruction;
}
// Extract Target Address From B(L) Instruction
void *extract_from_bl_instruction(unsigned char *from) {
// Calculate PC
unsigned char *pc = ((unsigned char *) from) + 8;
// Extract Offset From Instruction
int32_t target = *(int32_t *) from;
target = (target << 8) >> 8;
int32_t offset = target << 2;
// Add PC To Offset
return (void *) (pc + offset);
}

View File

@ -0,0 +1,26 @@
#pragma once
#ifndef __arm__
#error "Patching Code Is ARM Only"
#endif
#include <cstdint>
// Segments
struct segment_data {
void *start;
void *end;
bool is_executable;
bool is_writable;
};
__attribute__((visibility("internal"))) segment_data &get_data_for_addr(void *addr);
__attribute__((visibility("internal"))) void add_segment(segment_data data);
// Code Block
__attribute__((visibility("internal"))) void *update_code_block(void *target);
__attribute__((visibility("internal"))) void increment_code_block();
// BL Instruction Magic Number
#define BL_INSTRUCTION 0xeb
#define B_INSTRUCTION 0xea
__attribute__((visibility("internal"))) uint32_t generate_bl_instruction(void *from, void *to, int use_b_instruction);

View File

@ -1,214 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdint.h>
#include <errno.h>
#include <libreborn/libreborn.h>
#ifndef __arm__
#error "Patching Code Is ARM Only"
#endif
// BL Instruction Magic Number
#define BL_INSTRUCTION 0xeb
#define B_INSTRUCTION 0xea
// Generate A BL Instruction
static uint32_t generate_bl_instruction(void *from, void *to, int use_b_instruction) {
if (abs(((int32_t) to) - ((int32_t) from)) > 32000000) {
IMPOSSIBLE();
}
uint32_t instruction;
unsigned char *instruction_array = (unsigned char *) &instruction;
instruction_array[3] = use_b_instruction ? B_INSTRUCTION : BL_INSTRUCTION;
unsigned char *pc = ((unsigned char *) from) + 8;
int32_t offset = (int32_t) to - (int32_t) pc;
int32_t target = offset >> 2;
unsigned char *target_array = (unsigned char *) &target;
instruction_array[0] = target_array[0];
instruction_array[1] = target_array[1];
instruction_array[2] = target_array[2];
return instruction;
}
// Run For Every .text Section
static int _overwrite_calls_within_internal(const char *file, int line, void *from, void *to, void *target, void *replacement) {
int found = 0;
for (uint32_t i = (uint32_t) from; i < (uint32_t) to; i = i + 4) {
unsigned char *addr = (unsigned char *) i;
int use_b_instruction = addr[3] == B_INSTRUCTION;
// Check If Instruction is B Or BL
if (addr[3] == BL_INSTRUCTION || use_b_instruction) {
uint32_t check_instruction = generate_bl_instruction(addr, target, use_b_instruction);
unsigned char *check_instruction_array = (unsigned char *) &check_instruction;
// Check If Instruction Calls Target
if (addr[0] == check_instruction_array[0] && addr[1] == check_instruction_array[1] && addr[2] == check_instruction_array[2]) {
// Patch Instruction
uint32_t new_instruction = generate_bl_instruction(addr, replacement, use_b_instruction);
_patch(file, line, addr, (unsigned char *) &new_instruction);
found++;
}
}
}
return found;
}
struct overwrite_data {
const char *file;
int line;
void *target;
void *replacement;
int found;
};
static void overwrite_calls_callback(ElfW(Addr) section_addr, ElfW(Word) size, void *data) {
struct overwrite_data *args = (struct overwrite_data *) data;
void *section = (void *) section_addr;
args->found += _overwrite_calls_within_internal(args->file, args->line, section, (void *) (section_addr + size), args->target, args->replacement);
}
// Limit To 512 overwrite_calls() Uses
#define CODE_BLOCK_SIZE 4096
static unsigned char *code_block = NULL;
#define CODE_SIZE 8
static int code_block_remaining = CODE_BLOCK_SIZE;
static void _long_overwrite(void *start, void *target) {
unsigned char patch_data[4] = {0x04, 0xf0, 0x1f, 0xe5}; // "ldr pc, [pc, #-0x4]"
_patch(NULL, -1, start, patch_data);
_patch_address(NULL, -1, (void *) (((unsigned char *) start) + 4), target);
}
static void update_code_block(void *target) {
// BL Instructions Can Only Access A Limited Portion of Memory, So This Allocates Memory Closer To The Original Instruction, That When Run, Will Jump Into The Actual Target
if (code_block == NULL) {
code_block = mmap((void *) 0x200000, CODE_BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (code_block == MAP_FAILED) {
ERR("Unable To Allocate Code Block: %s", strerror(errno));
}
DEBUG("Code Block Allocated At: 0x%08x", (uint32_t) code_block);
}
if (code_block_remaining < CODE_SIZE) {
ERR("Maximum Amount Of overwrite_calls() Uses Reached");
}
_long_overwrite(code_block, target);
}
static void increment_code_block() {
code_block = code_block + CODE_SIZE;
code_block_remaining = code_block_remaining - CODE_SIZE;
}
// Overwrite Specific B(L) Instruction
static void _overwrite_call_internal(const char *file, int line, void *start, void *target, int use_b_instruction) {
// Add New Target To Code Block
update_code_block(target);
// Patch
uint32_t new_instruction = generate_bl_instruction(start, code_block, use_b_instruction);
_patch(file, line, start, (unsigned char *) &new_instruction);
// Increment Code Block Position
increment_code_block();
}
void _overwrite_call(const char *file, int line, void *start, void *target) {
int use_b_instruction = ((unsigned char *) start)[3] == B_INSTRUCTION;
_overwrite_call_internal(file, line, start, target, use_b_instruction);
}
// Overwrite All B(L) Intrusctions That Target The Specified Address
#define NO_CALLSITE_ERROR "(%s:%i) Unable To Find Callsites For 0x%08x"
void _overwrite_calls(const char *file, int line, void *start, void *target) {
// Add New Target To Code Block
update_code_block(target);
struct overwrite_data data;
data.file = file;
data.line = line;
data.target = start;
data.replacement = code_block;
data.found = 0;
iterate_segments(overwrite_calls_callback, &data);
// Increment Code Block Position
increment_code_block();
// Check
if (data.found < 1) {
ERR(NO_CALLSITE_ERROR, file, line, (uint32_t) start);
}
}
void _overwrite_calls_within(const char *file, int line, void *from /* inclusive */, void *to /* exclusive */, void *target, void *replacement) {
// Add New Target To Code Block
update_code_block(replacement);
// Patch
int found = _overwrite_calls_within_internal(file, line, from, to, target, code_block);
// Check
if (found < 1) {
ERR(NO_CALLSITE_ERROR, file, line, (uint32_t) target);
}
// Increment Code Block Position
increment_code_block();
}
// Extract Target Address From B(L) Instruction
void *extract_from_bl_instruction(unsigned char *from) {
unsigned char *pc = ((unsigned char *) from) + 8;
int32_t target = *(int32_t *) from;
target = (target << 8) >> 8;
int32_t offset = target << 2;
return (void *) (pc + offset);
}
// Overwrite Function
void _overwrite(const char *file, int line, void *start, void *target) {
_overwrite_call_internal(file, line, start, target, 1);
}
// Print Patch Debug Data
#define PATCH_PRINTF(file, line, start, str) if (file != NULL) DEBUG("(%s:%i): Patching (0x%08x) - " str ": 0x%02x 0x%02x 0x%02x 0x%02x", file, line, (uint32_t) start, data[0], data[1], data[2], data[3]);
// Patch Instruction
void _patch(const char *file, int line, void *start, unsigned char patch[4]) {
if (((uint32_t) start) % 4 != 0) {
ERR("Invalid Address");
}
size_t page_size = sysconf(_SC_PAGESIZE);
uintptr_t end = ((uintptr_t) start) + 4;
uintptr_t page_start = ((uintptr_t) start) & -page_size;
// Allow Writing To Code Memory
mprotect((void *) page_start, end - page_start, PROT_READ | PROT_WRITE | PROT_EXEC); // PROT_EXEC Is Needed Because Other Code In The Page May Be Being Executed
unsigned char *data = (unsigned char *) start;
PATCH_PRINTF(file, line, start, "original");
memcpy(data, patch, 4);
PATCH_PRINTF(file, line, start, "result");
// Reset Code Memory Permissions
mprotect((void *) page_start, end - page_start, PROT_READ | PROT_EXEC);
// Clear ARM Instruction Cache
__clear_cache(start, (void *) end);
}
// Patch Address
void _patch_address(const char *file, int line, void *start, void *target) {
uint32_t addr = (uint32_t) target;
unsigned char *patch_data = (unsigned char *) &addr;
_patch(file, line, start, patch_data);
}

View File

@ -0,0 +1,173 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/mman.h>
#include <cstdint>
#include <cerrno>
#include <libreborn/libreborn.h>
#include "patch-internal.h"
// Overwrite Specific B(L) Instruction
static void _overwrite_call_internal(const char *file, int line, void *start, void *target, int use_b_instruction) {
// Add New Target To Code Block
void *code_block = update_code_block(target);
// Patch
uint32_t new_instruction = generate_bl_instruction(start, code_block, use_b_instruction);
_patch(file, line, start, (unsigned char *) &new_instruction);
// Increment Code Block Position
increment_code_block();
}
void _overwrite_call(const char *file, int line, void *start, void *target) {
int use_b_instruction = ((unsigned char *) start)[3] == B_INSTRUCTION;
_overwrite_call_internal(file, line, start, target, use_b_instruction);
}
// .rodata Information
#define RODATA_START 0x1020c8
#define RODATA_END 0x11665c
// .data.rel.ro Information
#define DATA_REL_RO_START 0x1352b8
#define DATA_REL_RO_END 0x135638
// Search And Patch VTables Containing Function
#define scan_vtables(section) \
for (uintptr_t i = section##_START; i < section##_END; i = i + 4) { \
uint32_t *addr = (uint32_t *) i; \
if (*addr == (uintptr_t) target) { \
/* Found VTable Entry */ \
_patch_address(file, line, addr, replacement); \
found++; \
} \
}
static int _patch_vtables(const char *file, int line, void *target, void *replacement) {
int found = 0;
scan_vtables(RODATA);
scan_vtables(DATA_REL_RO);
return found;
}
#undef scan_vtables
// Patch Calls Within Range
static int _overwrite_calls_within_internal(const char *file, int line, void *from, void *to, void *target, void *replacement) {
int found = 0;
for (uintptr_t i = (uintptr_t) from; i < (uintptr_t) to; i = i + 4) {
unsigned char *addr = (unsigned char *) i;
int use_b_instruction = addr[3] == B_INSTRUCTION;
// Check If Instruction is B Or BL
if (addr[3] == BL_INSTRUCTION || use_b_instruction) {
uint32_t check_instruction = generate_bl_instruction(addr, target, use_b_instruction);
unsigned char *check_instruction_array = (unsigned char *) &check_instruction;
// Check If Instruction Calls Target
if (addr[0] == check_instruction_array[0] && addr[1] == check_instruction_array[1] && addr[2] == check_instruction_array[2]) {
// Patch Instruction
uint32_t new_instruction = generate_bl_instruction(addr, replacement, use_b_instruction);
_patch(file, line, addr, (unsigned char *) &new_instruction);
found++;
}
}
}
return found;
}
// .text Information
#define TEXT_START 0xde60
#define TEXT_END 0x1020c0
// Overwrite All B(L) Intrusctions That Target The Specified Address
#define NO_CALLSITE_ERROR "(%s:%i) Unable To Find Callsites For %p"
void *_overwrite_calls_manual(const char *file, int line, void *start, void *target) {
// Add New Target To Code Block
void *code_block = update_code_block(target);
// Patch Code
int found = _overwrite_calls_within_internal(file, line, (void *) TEXT_START, (void *) TEXT_END, start, code_block);
// Patch VTables
found += _patch_vtables(file, line, start, code_block);
// Increment Code Block Position
increment_code_block();
// Check
if (found < 1) {
ERR(NO_CALLSITE_ERROR, file, line, start);
}
// Return
return code_block;
}
void _overwrite_calls_within_manual(const char *file, int line, void *from /* inclusive */, void *to /* exclusive */, void *target, void *replacement) {
// Add New Target To Code Block
void *code_block = update_code_block(replacement);
// Patch
int found = _overwrite_calls_within_internal(file, line, from, to, target, code_block);
// Check
if (found < 1) {
ERR(NO_CALLSITE_ERROR, file, line, target);
}
// Increment Code Block Position
increment_code_block();
}
// Overwrite Function
void _overwrite_manual(const char *file, int line, void *start, void *target) {
// Replace the function's start with a call
// to the replacement function.
_overwrite_call_internal(file, line, start, target, 1);
}
// Print Patch Debug Data
#define PATCH_PRINTF(file, line, start, str) if (file != NULL) DEBUG("(%s:%i): Patching (%p) - " str ": %02x %02x %02x %02x", file, line, start, data[0], data[1], data[2], data[3]);
// Patch Instruction
static void safe_mprotect(void *addr, size_t len, int prot) {
long page_size = sysconf(_SC_PAGESIZE);
long diff = ((uintptr_t) addr) % page_size;
void *aligned_addr = (void *) (((uintptr_t) addr) - diff);
size_t aligned_len = len + diff;
int ret = mprotect(aligned_addr, aligned_len, prot);
if (ret == -1) {
ERR("Unable To Set Permissions: %p: %s", addr, strerror(errno));
}
}
void _patch(const char *file, int line, void *start, unsigned char patch[4]) {
if (((uint32_t) start) % 4 != 0) {
ERR("Invalid Address: %p", start);
}
// Get Current Permissions
segment_data &segment_data = get_data_for_addr(start);
int prot = PROT_READ;
if (segment_data.is_executable) {
prot |= PROT_EXEC;
}
if (segment_data.is_writable) {
prot |= PROT_WRITE;
}
// Allow Writing To Code Memory
uint32_t size = 4;
safe_mprotect(start, size, prot | PROT_WRITE);
// Patch
unsigned char *data = (unsigned char *) start;
PATCH_PRINTF(file, line, start, "original");
memcpy(data, patch, 4);
PATCH_PRINTF(file, line, start, "result");
// Reset Code Memory Permissions
safe_mprotect(start, size, prot);
// Clear ARM Instruction Cache
__clear_cache(start, (void *) (((uintptr_t) start) + size));
}
// Patch Address
void _patch_address(const char *file, int line, void *start, void *target) {
uint32_t addr = (uint32_t) target;
unsigned char *patch_data = (unsigned char *) &addr;
_patch(file, line, start, patch_data);
}

View File

@ -0,0 +1,50 @@
#include <vector>
#include <elf.h>
#include <dlfcn.h>
#include <link.h>
#include <libreborn/libreborn.h>
#include "patch-internal.h"
// Track Segments
static std::vector<segment_data> &get_segments() {
static std::vector<segment_data> data;
return data;
}
// Functions
segment_data &get_data_for_addr(void *addr) {
for (segment_data &data : get_segments()) {
if (addr >= data.start && addr < data.end) {
return data;
}
}
ERR("Address Not Part Of Main Program: %p", addr);
}
void add_segment(segment_data data) {
get_segments().push_back(data);
}
// Init
void reborn_init_patch() {
dl_iterate_phdr([](struct dl_phdr_info *info, __attribute__((unused)) size_t size, __attribute__((unused)) void *user_data) {
// Only Search Current Program
if (strcmp(info->dlpi_name, "") == 0) {
for (int i = 0; i < info->dlpi_phnum; i++) {
// Only Loaded Segemnts
if (info->dlpi_phdr[i].p_type == PT_LOAD) {
// Store
segment_data data;
data.start = (void *) (info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
data.end = (void *) (((uintptr_t) data.start) + info->dlpi_phdr[i].p_memsz);
data.is_executable = info->dlpi_phdr[i].p_flags & PF_X;
data.is_writable = info->dlpi_phdr[i].p_flags & PF_W;
add_segment(data);
}
}
}
// Return
return 0;
}, nullptr);
}

View File

@ -16,7 +16,7 @@ static std::string to_utf8(const std::u32string &s) {
// Minecraft-Flavored CP437 // Minecraft-Flavored CP437
#define CP437_CHARACTERS 256 #define CP437_CHARACTERS 256
static const std::string cp437_characters_map[CP437_CHARACTERS] = { static const std::string cp437_characters_map[CP437_CHARACTERS] = {
"\0", "", "", "", "", "", "", "", "", "", "\n", "", "", "\r", "", "", "\0", "", "", "", "", "", "", "", "", "", "\n", "", "", "", "", "",
"", "", "", "", "", "§", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "§", "", "", "", "", "", "", "", "", "", "",
" ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",

View File

@ -1,28 +0,0 @@
#include <libreborn/elf.h>
// Find And Iterate Over All Segments In Current Binary
typedef struct {
segment_callback_t callback;
void *data;
} dl_iterate_callback_data;
static int dl_iterate_callback(struct dl_phdr_info *info, __attribute__((unused)) size_t size, void *data) {
dl_iterate_callback_data *callback_data = (dl_iterate_callback_data *) data;
// Only Search Current Program
if (strcmp(info->dlpi_name, "") == 0) {
for (int i = 0; i < info->dlpi_phnum; i++) {
// Only Executable Segemnts
if (info->dlpi_phdr[i].p_type == PT_LOAD && (info->dlpi_phdr[i].p_flags & PF_X) != 0) {
// Callback
(*callback_data->callback)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr, info->dlpi_phdr[i].p_memsz, callback_data->data);
}
}
}
return 0;
}
void iterate_segments(segment_callback_t callback, void *data) {
dl_iterate_callback_data callback_data = {
.callback = callback,
.data = data
};
dl_iterate_phdr(dl_iterate_callback, (void *) &callback_data);
}

View File

@ -21,13 +21,15 @@ void set_and_print_env(const char *name, const char *value) {
// Safe execvpe() // Safe execvpe()
#define handle_environmental_variable(var) \ #define handle_environmental_variable(var) \
{ \ { \
const char *full_var = is_arm_component ? "MCPI_ARM_" var : "MCPI_NATIVE_" var; \ const char *full_var = is_arm_component ? MCPI_LD_VARIABLE_PREFIX var : MCPI_ORIGINAL_LD_VARIABLE_PREFIX var; \
const char *var_value = getenv(full_var); \ const char *var_value = getenv(full_var); \
set_and_print_env(var, var_value); \ set_and_print_env(var, var_value); \
} }
void setup_exec_environment(int is_arm_component) { void setup_exec_environment(int is_arm_component) {
if (is_arm_component || getenv(MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV) != NULL) {
for_each_special_environmental_variable(handle_environmental_variable); for_each_special_environmental_variable(handle_environmental_variable);
} }
}
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) { __attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) {
// Log // Log
DEBUG("Running Command:"); DEBUG("Running Command:");
@ -64,13 +66,8 @@ char *run_command(const char *const command[], int *exit_status, size_t *output_
close(output_pipe[1]); close(output_pipe[1]);
// Setup stderr // Setup stderr
if (getenv("MCPI_DEBUG") == NULL) { reborn_lock_debug(); // Lock Released On Process Exit
const char *log_file_fd_env = getenv("MCPI_LOG_FILE_FD"); dup2(reborn_get_debug_fd(), STDERR_FILENO);
if (log_file_fd_env == NULL) {
IMPOSSIBLE();
}
dup2(atoi(log_file_fd_env), STDERR_FILENO);
}
// Setup Environment // Setup Environment
setup_exec_environment(0); setup_exec_environment(0);
@ -89,7 +86,7 @@ char *run_command(const char *const command[], int *exit_status, size_t *output_
char buf[BUFFER_SIZE]; char buf[BUFFER_SIZE];
size_t position = 0; size_t position = 0;
ssize_t bytes_read = 0; ssize_t bytes_read = 0;
while ((bytes_read = read(output_pipe[0], (void *) buf, BUFFER_SIZE)) > 0) { while ((bytes_read = read(output_pipe[0], buf, BUFFER_SIZE)) > 0) {
// Grow Output If Needed // Grow Output If Needed
size_t needed_size = position + bytes_read; size_t needed_size = position + bytes_read;
if (needed_size > size) { if (needed_size > size) {

View File

@ -1,23 +1,73 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/file.h>
#include <libreborn/log.h> #include <libreborn/log.h>
#include <libreborn/exec.h>
// Debug Tag // Debug Tag
const char *reborn_debug_tag = ""; const char *reborn_debug_tag = "";
// Debug FD // Log File
static int log_fd = -1;
int reborn_get_log_fd() {
if (log_fd >= 0) {
return log_fd;
}
// Open Log File
const char *file = getenv(MCPI_LOG_ENV);
if (file == NULL) {
file = "/dev/null";
}
log_fd = open(file, O_WRONLY | O_APPEND | O_CLOEXEC);
// Check FD
if (log_fd < 0) {
ERR("Unable To Open Log: %s", strerror(errno));
}
// Return
return reborn_get_log_fd();
}
void reborn_lock_log() {
int ret = flock(reborn_get_log_fd(), LOCK_EX);
if (ret != 0) {
ERR("Unable To Lock Log: %s", strerror(errno));
}
}
void reborn_unlock_log() {
int ret = flock(reborn_get_log_fd(), LOCK_UN);
if (ret != 0) {
ERR("Unable To Unlock Log: %s", strerror(errno));
}
}
__attribute__((destructor)) void reborn_close_log() {
if (log_fd >= 0) {
close(log_fd);
log_fd = -1;
}
}
void reborn_set_log(const char *file) {
// Close Current Log
reborn_close_log();
// Set Variable
set_and_print_env(MCPI_LOG_ENV, file);
}
// Debug Logging
static int should_print_debug_to_stderr() {
return getenv(MCPI_DEBUG_ENV) != NULL;
}
int reborn_get_debug_fd() { int reborn_get_debug_fd() {
if (getenv("MCPI_DEBUG") != NULL) { return should_print_debug_to_stderr() ? STDERR_FILENO : reborn_get_log_fd();
return STDERR_FILENO;
} else {
static int debug_fd = -1;
if (debug_fd == -1) {
const char *log_file_fd_env = getenv("MCPI_LOG_FILE_FD");
if (log_file_fd_env == NULL) {
return -1;
} }
debug_fd = atoi(log_file_fd_env); void reborn_lock_debug() {
} if (!should_print_debug_to_stderr()) {
return debug_fd; reborn_lock_log();
}
}
void reborn_unlock_debug() {
if (!should_print_debug_to_stderr()) {
reborn_unlock_log();
} }
} }

View File

@ -14,7 +14,7 @@ void sanitize_string(char **str, int max_length, unsigned int allow_newlines) {
// Loop Through Message // Loop Through Message
if (!allow_newlines) { if (!allow_newlines) {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
if ((*str)[i] == '\n' || (*str)[i] == '\r') { if ((*str)[i] == '\n') {
// Replace Newline // Replace Newline
(*str)[i] = ' '; (*str)[i] = ' ';
} }

View File

@ -33,7 +33,7 @@ if(BUILD_MEDIA_LAYER_CORE)
add_subdirectory(core) add_subdirectory(core)
endif() endif()
# Add Proxy # Add Trampoline
if(MCPI_USE_MEDIA_LAYER_PROXY OR BUILD_ARM_COMPONENTS) if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE OR BUILD_ARM_COMPONENTS)
add_subdirectory(proxy) add_subdirectory(trampoline)
endif() endif()

View File

@ -13,10 +13,12 @@
// Load Symbol From ELF File // Load Symbol From ELF File
static void load_symbol(const char *source, const char *name, std::function<void(const unsigned char *, uint32_t)> callback) { static void load_symbol(const char *source, const char *name, std::function<void(const unsigned char *, uint32_t)> callback) {
static std::unique_ptr<LIEF::ELF::Binary> binary = NULL; static std::unordered_map<std::string, std::unique_ptr<LIEF::ELF::Binary>> sources = {};
if (binary == NULL) { std::string cpp_source = source;
binary = LIEF::ELF::Parser::parse(source); if (sources.count(cpp_source) == 0) {
sources[cpp_source] = LIEF::ELF::Parser::parse(source);
} }
std::unique_ptr<LIEF::ELF::Binary> &binary = sources[cpp_source];
const LIEF::ELF::Symbol *symbol = binary->get_dynamic_symbol(name); const LIEF::ELF::Symbol *symbol = binary->get_dynamic_symbol(name);
if (symbol != NULL) { if (symbol != NULL) {
LIEF::span<const uint8_t> data = binary->get_content_from_virtual_address(symbol->value(), symbol->size(), LIEF::Binary::VA_TYPES::VA); LIEF::span<const uint8_t> data = binary->get_content_from_virtual_address(symbol->value(), symbol->size(), LIEF::Binary::VA_TYPES::VA);

View File

@ -1,10 +1,10 @@
#include <cstdlib>
#include <vector> #include <vector>
#include <SDL/SDL.h> #include <SDL/SDL.h>
#include <media-layer/internal.h> #include <media-layer/internal.h>
#include <media-layer/core.h> #include <media-layer/core.h>
#include <libreborn/libreborn.h>
// SDL Is Replaced With GLFW // SDL Is Replaced With GLFW

View File

@ -40,6 +40,9 @@ static volatile int is_running = 0;
static int cursor_grabbed = 0; static int cursor_grabbed = 0;
static int cursor_visible = 1; static int cursor_visible = 1;
// Track If Raw Mouse Motion Is Enabled
static int raw_mouse_motion_enabled = 1;
// GLFW Code Not Needed In Headless Mode // GLFW Code Not Needed In Headless Mode
#ifndef MCPI_HEADLESS_MODE #ifndef MCPI_HEADLESS_MODE
@ -123,6 +126,8 @@ static SDLKey glfw_key_to_sdl_key(int key) {
return SDLK_RETURN; return SDLK_RETURN;
case GLFW_KEY_BACKSPACE: case GLFW_KEY_BACKSPACE:
return SDLK_BACKSPACE; return SDLK_BACKSPACE;
case GLFW_KEY_DELETE:
return SDLK_DELETE;
// Fullscreen // Fullscreen
case GLFW_KEY_F11: case GLFW_KEY_F11:
return SDLK_F11; return SDLK_F11;
@ -217,7 +222,7 @@ static void glfw_char(__attribute__((unused)) GLFWwindow *window, unsigned int c
memset(str, 0, str_size); memset(str, 0, str_size);
codepoint_to_utf8((unsigned char *) str, codepoint); codepoint_to_utf8((unsigned char *) str, codepoint);
char *cp437_str = to_cp437(str); char *cp437_str = to_cp437(str);
// Send Event· // Send Event
for (int i = 0; cp437_str[i] != '\0'; i++) { for (int i = 0; cp437_str[i] != '\0'; i++) {
character_event(cp437_str[i]); character_event(cp437_str[i]);
} }
@ -232,8 +237,31 @@ static double last_mouse_y = 0;
// Ignore Relative Cursor Motion // Ignore Relative Cursor Motion
static int ignore_relative_motion = 0; static int ignore_relative_motion = 0;
// Convert Screen Coordinates To Pixels
static void convert_to_pixels(GLFWwindow *window, double *xpos, double *ypos) {
// Skip If Cursor Is Grabbed
if (cursor_grabbed && raw_mouse_motion_enabled) {
return;
}
// Get Window Size
int window_width;
int window_height;
glfwGetWindowSize(window, &window_width, &window_height);
// Get Framebuffer Size
int framebuffer_width;
int framebuffer_height;
glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
// Calculate Ratios
double width_ratio = ((double) framebuffer_width) / ((double) window_width);
double height_ratio = ((double) framebuffer_height) / ((double) window_height);
// Multiply
*xpos *= width_ratio;
*ypos *= height_ratio;
}
// Pass Mouse Movement To SDL // Pass Mouse Movement To SDL
static void glfw_motion(__attribute__((unused)) GLFWwindow *window, double xpos, double ypos) { static void glfw_motion(__attribute__((unused)) GLFWwindow *window, double xpos, double ypos) {
convert_to_pixels(window, &xpos, &ypos);
if (is_interactable) { if (is_interactable) {
SDL_Event event; SDL_Event event;
event.type = SDL_MOUSEMOTION; event.type = SDL_MOUSEMOTION;
@ -407,6 +435,7 @@ static void glfw_controller_look(float x, float y) {
verify_controller_axis_value(y, CONTROLLER_LOOK_AXIS_THRESHOLD); verify_controller_axis_value(y, CONTROLLER_LOOK_AXIS_THRESHOLD);
// Send Event // Send Event
if (is_interactable) {
SDL_Event event; SDL_Event event;
event.type = SDL_MOUSEMOTION; event.type = SDL_MOUSEMOTION;
event.motion.x = last_mouse_x; event.motion.x = last_mouse_x;
@ -416,6 +445,7 @@ static void glfw_controller_look(float x, float y) {
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
} }
}
// Controller Place/Mine Triggers // Controller Place/Mine Triggers
#define CONTROLLER_TRIGGER_THRESHOLD 0 #define CONTROLLER_TRIGGER_THRESHOLD 0
@ -527,8 +557,7 @@ static void emit_events_after_is_interactable_change() {
#endif #endif
// Track If Raw Mouse Motion Is Enabled // Enable/Disable Raw Mouse Motion
static int raw_mouse_motion_enabled = 1;
void media_set_raw_mouse_motion_enabled(int enabled) { void media_set_raw_mouse_motion_enabled(int enabled) {
raw_mouse_motion_enabled = enabled; raw_mouse_motion_enabled = enabled;
#ifndef MCPI_HEADLESS_MODE #ifndef MCPI_HEADLESS_MODE

View File

@ -28,6 +28,7 @@ typedef enum {
SDLK_s = 115, SDLK_s = 115,
SDLK_t = 116, SDLK_t = 116,
SDLK_w = 119, SDLK_w = 119,
SDLK_DELETE = 127,
SDLK_UP = 273, SDLK_UP = 273,
SDLK_DOWN = 274, SDLK_DOWN = 274,
SDLK_RIGHT = 275, SDLK_RIGHT = 275,

View File

@ -4,10 +4,8 @@
extern "C" { extern "C" {
#endif #endif
// Internal Methods (Not Handled By Media Layer Proxy) // Internal Methods
__attribute__((visibility("internal"))) void _media_handle_SDL_PollEvent(); __attribute__((visibility("internal"))) void _media_handle_SDL_PollEvent();
__attribute__((visibility("internal"))) void _media_handle_SDL_Quit();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,24 +0,0 @@
project(media-layer-proxy)
# Configuration
set(MEDIA_LAYER_PROXY_SRC src/common/common.c src/media-layer-core.c src/GLESv1_CM.c) # Media Layer Proxy Source
# Build
if(BUILD_NATIVE_COMPONENTS)
# Build Media Layer Proxy Client
add_executable(media-layer-proxy-client src/client/client.cpp ${MEDIA_LAYER_PROXY_SRC})
target_link_libraries(media-layer-proxy-client media-layer-headers reborn-util media-layer-core GLESv1_CM)
target_compile_definitions(media-layer-proxy-client PRIVATE -DMEDIA_LAYER_PROXY_CLIENT)
# Install
install(TARGETS media-layer-proxy-client DESTINATION "${MCPI_BIN_DIR}")
elseif(BUILD_ARM_COMPONENTS)
# Build Media Layer Proxy Server
add_library(media-layer-core SHARED src/server/server.cpp ${MEDIA_LAYER_PROXY_SRC} $<TARGET_OBJECTS:media-layer-extras>)
target_link_libraries(media-layer-core media-layer-headers reborn-util)
target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_PROXY_SERVER)
# Install
if(MCPI_USE_MEDIA_LAYER_PROXY)
install(TARGETS media-layer-core DESTINATION "${MCPI_LIB_DIR}")
endif()
install(TARGETS media-layer-core EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
endif()

File diff suppressed because it is too large Load Diff

View File

@ -1,107 +0,0 @@
#include <vector>
#include <cerrno>
#include <unistd.h>
#include <cstring>
#include <sys/prctl.h>
#include <csignal>
#include <exception>
#include "../common/common.h"
// Store Handlers
#define MAX_HANDLERS 100
static proxy_handler_t handlers[MAX_HANDLERS];
void _add_handler(unsigned char unique_id, proxy_handler_t handler) {
if (unique_id >= MAX_HANDLERS) {
PROXY_ERR("ID Too Big: %i", (int) unique_id);
}
if (handlers[unique_id] != NULL) {
PROXY_ERR("Duplicate ID: %i", (int) unique_id);
}
handlers[unique_id] = handler;
}
// Store Parent PID
static int parent_is_alive = 1;
static void sigusr1_handler(__attribute__((unused)) int sig) {
// Mark Parent As Dead
parent_is_alive = 0;
}
// Check State Of Proxy And Exit If Invalid
void _check_proxy_state() {
// Check Server State
if (!parent_is_alive) {
void_write_cache(); // Parent Is Dead, No Reason To Send A Dead Process Data
PROXY_ERR("Server Terminated");
}
}
// Exit Handler
static volatile int exit_requested = 0;
static void exit_handler(__attribute__((unused)) int signal_id) {
// Request Exit
exit_requested = 1;
}
// Main
int main(int argc, char *argv[]) {
// Set Debug Tag
reborn_debug_tag = PROXY_LOG_TAG;
// Install Signal Handlers
signal(SIGINT, SIG_IGN);
struct sigaction act_sigterm;
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
act_sigterm.sa_handler = &exit_handler;
sigaction(SIGTERM, &act_sigterm, NULL);
// Send Signal On Parent Death To Interrupt Connection Read/Write And Exit
prctl(PR_SET_PDEATHSIG, SIGUSR1);
struct sigaction sa;
memset((void *) &sa, 0, sizeof (struct sigaction));
sa.sa_flags = SA_NOCLDSTOP;
sa.sa_handler = &sigusr1_handler;
if (sigaction(SIGUSR1, &sa, NULL) == -1) {
PROXY_ERR("Unable To Install Signal Handler: %s", strerror(errno));
}
// Get Connection
if (argc != 3) {
PROXY_ERR("Invalid Arguments");
}
char *read_str = argv[1];
char *write_str = argv[2];
set_connection(atoi(read_str), atoi(write_str));
PROXY_INFO("Connected");
// Send Connection Message
write_string((char *) CONNECTED_MSG);
flush_write_cache();
// Loop
int running = is_connection_open();
while (running && !exit_requested) {
unsigned char unique_id = read_byte();
if (handlers[unique_id] != NULL) {
// Run Method
handlers[unique_id]();
// Check If Connection Is Still Open
if (!is_connection_open()) {
// Exit
running = 0;
} else {
// Flush Write Cache
flush_write_cache();
}
} else {
PROXY_ERR("Invalid Method ID: %i", (int) unique_id);
}
}
if (is_connection_open()) {
close_connection();
}
// Exit
PROXY_INFO("Stopped");
return 0;
}

View File

@ -1,13 +0,0 @@
#pragma once
#define PROXY_LOG_TAG "(Media Layer Proxy Client) "
typedef void (*proxy_handler_t)();
__attribute__((visibility("internal"))) void _add_handler(unsigned char id, proxy_handler_t handler);
#define CALL(unique_id, name, return_type, args) \
static void _run_##name (); \
__attribute__((constructor)) static void _init_##name() { \
_add_handler(unique_id, _run_##name); \
} \
static void _run_##name ()

View File

@ -1,245 +0,0 @@
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <sys/ioctl.h>
#include "common.h"
// Safely Send/Receive Data From The Connection
#define CHECK_CONNECTION() \
{ \
_check_proxy_state(); \
if (!is_connection_open()) { \
PROXY_ERR("Attempting To Access Closed Connection"); \
} \
}
// Buffer Reads
static void *_read_cache = NULL;
__attribute__((destructor)) static void _free_read_cache() {
if (_read_cache != NULL) {
free(_read_cache);
}
}
static size_t _read_cache_size = 0;
static size_t _read_cache_actual_size = 0;
static size_t _read_cache_position = 0;
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
void safe_read(void *buf, size_t len) {
// Check Data
if (buf == NULL) {
PROXY_ERR("Attempting To Read Into NULL Buffer");
}
// Setup
size_t to_read = len;
// Copy From Read Buffer
if (_read_cache != NULL && _read_cache_size > 0) {
char *read_cache = (void *) (((unsigned char *) _read_cache) + _read_cache_position);
size_t read_cache_size = _read_cache_size - _read_cache_position;
if (read_cache_size > 0) {
size_t to_copy = min(to_read, read_cache_size);
memcpy(buf, read_cache, to_copy);
to_read -= to_copy;
_read_cache_position += to_copy;
}
}
// Check If Done
if (to_read < 1) {
return;
}
if (_read_cache_position < _read_cache_size) {
IMPOSSIBLE();
}
// Flush Write Cache
flush_write_cache();
// Read Remaining Data
size_t to_read_to_cache = 0;
while (to_read_to_cache < 1) {
CHECK_CONNECTION();
int bytes_available;
if (ioctl(get_connection_read(), FIONREAD, &bytes_available) == -1) {
bytes_available = 0;
}
to_read_to_cache = max((size_t) bytes_available, to_read);
}
// Resize Buffer
_read_cache_position = 0;
_read_cache_size = to_read_to_cache;
if (_read_cache == NULL) {
_read_cache_actual_size = _read_cache_size;
_read_cache = malloc(_read_cache_actual_size);
} else if (_read_cache_size > _read_cache_actual_size) {
_read_cache_actual_size = _read_cache_size;
_read_cache = realloc(_read_cache, _read_cache_actual_size);
}
ALLOC_CHECK(_read_cache);
// Read Into Buffer
while (to_read_to_cache > 0) {
CHECK_CONNECTION();
ssize_t x = read(get_connection_read(), (void *) (((unsigned char *) _read_cache) + (_read_cache_size - to_read_to_cache)), to_read_to_cache);
if (x == -1 && errno != EINTR) {
PROXY_ERR("Failed Reading Data To Connection: %s", strerror(errno));
}
to_read_to_cache -= x;
}
// Copy Remaining Data
safe_read((void *) (((unsigned char *) buf) + (len - to_read)), to_read);
}
// Buffer Writes
static void *_write_cache = NULL;
__attribute__((destructor)) static void _free_write_cache() {
if (_write_cache != NULL) {
free(_write_cache);
}
}
static size_t _write_cache_size = 0;
static size_t _write_cache_position = 0;
void safe_write(void *buf, size_t len) {
// Check Data
if (buf == NULL) {
PROXY_ERR("Attempting To Send NULL Data");
}
// Expand Write Cache If Needed
size_t needed_size = _write_cache_position + len;
if (_write_cache == NULL) {
_write_cache_size = needed_size;
_write_cache = malloc(_write_cache_size);
} else if (needed_size > _write_cache_size) {
_write_cache_size = needed_size;
_write_cache = realloc(_write_cache, _write_cache_size);
}
ALLOC_CHECK(_write_cache);
// Copy Data
memcpy((void *) (((unsigned char *) _write_cache) + _write_cache_position), buf, len);
// Advance Position
_write_cache_position += len;
}
// Flush Write Cache
void flush_write_cache() {
// Check Cache
if (_write_cache == NULL || _write_cache_position < 1) {
// Nothing To Write
return;
}
// Check Connection
if (!is_connection_open()) {
// Connection Closed
return;
}
// Write & Reset
size_t to_write = _write_cache_position;
size_t old_write_cache_position = _write_cache_position;
_write_cache_position = 0;
while (to_write > 0) {
CHECK_CONNECTION();
ssize_t x = write(get_connection_write(), (void *) (((unsigned char *) _write_cache) + (old_write_cache_position - to_write)), to_write);
if (x == -1 && errno != EINTR) {
PROXY_ERR("Failed Writing Data To Connection: %s", strerror(errno));
}
to_write -= x;
}
}
void void_write_cache() {
_write_cache_position = 0;
}
// Read/Write 32-Bit Integers
uint32_t read_int() {
uint32_t ret = 0;
safe_read((void *) &ret, sizeof (ret));
return ret;
}
void write_int(uint32_t x) {
safe_write((void *) &x, sizeof (x));
}
// Read/Write Floats
float read_float() {
float ret = 0;
safe_read((void *) &ret, sizeof (ret));
return ret;
}
void write_float(float x) {
safe_write((void *) &x, sizeof (x));
}
// Read/Write Bytes
unsigned char read_byte() {
unsigned char ret = 0;
safe_read((void *) &ret, sizeof (ret));
return ret;
}
void write_byte(unsigned char x) {
safe_write((void *) &x, sizeof (x));
}
// Read/Write Strings
char *read_string() {
// Check NULL
unsigned char is_null = read_byte();
if (is_null) {
return NULL;
}
// Allocate String
unsigned char length = read_byte();
char *str = malloc((size_t) length + 1);
// Read String
safe_read((void *) str, length);
// Add Terminator
str[length] = '\0';
// Return String
return strdup(str);
}
#define MAX_STRING_SIZE 256
void write_string(const char *str) {
unsigned char is_null = str == NULL;
write_byte(is_null);
if (!is_null) {
int length = strlen(str);
if (length > MAX_STRING_SIZE) {
PROXY_ERR("Unable To Write String To Connection: Larger Than %i Bytes", MAX_STRING_SIZE);
}
write_byte((unsigned char) length);
safe_write((void *) str, length);
}
}
// Close Connection
void close_connection() {
// Flush Write Cache
flush_write_cache();
// Close
int state_changed = 0;
if (get_connection_read() != -1) {
close(get_connection_read());
state_changed = 1;
}
if (get_connection_write() != -1) {
close(get_connection_write());
state_changed = 1;
}
set_connection(-1, -1);
if (state_changed) {
PROXY_INFO("Connection Closed");
}
}
// Check If Connection Is Open
int is_connection_open() {
return get_connection_read() != -1 && get_connection_write() != -1;
}
// Pipe
static int _read = -1;
static int _write = -1;
// Set Pipe
void set_connection(int read, int write) {
_read = read;
_write = write;
}
// Get Pipe
int get_connection_read() {
return _read;
}
int get_connection_write() {
return _write;
}

View File

@ -1,62 +0,0 @@
#pragma once
#include <stdint.h>
#include <libreborn/libreborn.h>
#ifdef __cplusplus
extern "C" {
#endif
#if __BYTE_ORDER != __LITTLE_ENDIAN
#error "Only Little Endian Is Supported"
#endif
#if defined(MEDIA_LAYER_PROXY_SERVER)
#include "../server/server.h"
#elif defined(MEDIA_LAYER_PROXY_CLIENT)
#include "../client/client.h"
#else
#error "Invalid Configuration"
#endif
#define CONNECTED_MSG "Connected"
#define PROXY_INFO(format, ...) RAW_DEBUG(PROXY_LOG_TAG, format, ##__VA_ARGS__);
#define PROXY_ERR(format, ...) { close_connection(); ERR(PROXY_LOG_TAG format, ##__VA_ARGS__); }
// Safely Send/Receive Data From The Connection
__attribute__((visibility("internal"))) void safe_read(void *buf, size_t len);
__attribute__((visibility("internal"))) void safe_write(void *buf, size_t len);
__attribute__((visibility("internal"))) void flush_write_cache();
__attribute__((visibility("internal"))) void void_write_cache();
// Read/Write 32-Bit Integers
__attribute__((visibility("internal"))) uint32_t read_int();
__attribute__((visibility("internal"))) void write_int(uint32_t x);
// Read/Write Bytes
__attribute__((visibility("internal"))) unsigned char read_byte();
__attribute__((visibility("internal"))) void write_byte(unsigned char x);
// Read/Write Floats
__attribute__((visibility("internal"))) float read_float();
__attribute__((visibility("internal"))) void write_float(float x);
// Read/Write Strings
__attribute__((visibility("internal"))) char *read_string(); // Remember To free()
__attribute__((visibility("internal"))) void write_string(const char *str);
// Manipulate Connection
__attribute__((visibility("internal"))) void set_connection(int read, int write);
__attribute__((visibility("internal"))) int get_connection_read();
__attribute__((visibility("internal"))) int get_connection_write();
__attribute__((visibility("internal"))) void close_connection();
__attribute__((visibility("internal"))) int is_connection_open();
// Check State Of Proxy And Exit If Invalid
__attribute__((visibility("internal"))) void _check_proxy_state();
#ifdef __cplusplus
}
#endif

View File

@ -1,354 +0,0 @@
#include <stdint.h>
#include <SDL/SDL.h>
#include <libreborn/libreborn.h>
#include <media-layer/core.h>
#include <media-layer/audio.h>
#include <media-layer/internal.h>
#include "common/common.h"
// SDL Functions
CALL(0, SDL_Init, int, (uint32_t flags)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Arguments
write_int(flags);
// Get Return Value
int32_t ret = (int32_t) read_int();
// Release Proxy
end_proxy_call();
// Return
return ret;
#else
uint32_t flags = read_int();
// Run
int ret = SDL_Init(flags);
// Return Values
write_int((uint32_t) ret);
#endif
}
CALL(1, SDL_PollEvent, int, (SDL_Event *event)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// No Arguments
// Get Return Value
int32_t ret = (int32_t) read_int();
if (ret) {
safe_read((void *) event, sizeof (SDL_Event));
}
// Release Proxy
end_proxy_call();
// Return Value
return ret;
#else
SDL_Event event;
// Run
int ret = (int32_t) SDL_PollEvent(&event);
// Return Values
write_int(ret);
if (ret) {
safe_write((void *) &event, sizeof (SDL_Event));
}
#endif
}
CALL(2, SDL_PushEvent, int, (SDL_Event *event)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Arguments
safe_write((void *) event, sizeof (SDL_Event));
// Get Return Value
int32_t ret = (int32_t) read_int();
// Release Proxy
end_proxy_call();
// Return Value
return ret;
#else
SDL_Event event;
safe_read((void *) &event, sizeof (SDL_Event));
// Run
int ret = SDL_PushEvent(&event);
// Return Value
write_int((uint32_t) ret);
#endif
}
CALL(3, SDL_WM_SetCaption, void, (const char *title, const char *icon)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Arguments
write_string((char *) title);
write_string((char *) icon);
// Release Proxy
end_proxy_call();
#else
char *title = read_string();
char *icon = read_string();
// Run
SDL_WM_SetCaption(title, icon);
// Free
free(title);
free(icon);
#endif
}
CALL(4, media_toggle_fullscreen, void, ()) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Release Proxy
end_proxy_call();
#else
// Run
media_toggle_fullscreen();
#endif
}
CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Arguments
write_int((uint32_t) mode);
// Get Return Value
SDL_GrabMode ret = (SDL_GrabMode) read_int();
// Release Proxy
end_proxy_call();
// Return Value
return ret;
#else
SDL_GrabMode mode = (SDL_GrabMode) read_int();
// Run
SDL_GrabMode ret = SDL_WM_GrabInput(mode);
// Return Value
write_int((uint32_t) ret);
#endif
}
CALL(6, SDL_ShowCursor, int, (int32_t toggle)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Arguments
write_int((uint32_t) toggle);
// Get Return Value
int32_t ret = (int32_t) read_int();
// Release Proxy
end_proxy_call();
// Return Value
return ret;
#else
int mode = (int) read_int();
// Run
int ret = SDL_ShowCursor(mode);
// Return Value
write_int((uint32_t) ret);
#endif
}
CALL(8, media_swap_buffers, void, ()) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Release Proxy
end_proxy_call();
flush_write_cache();
#else
// Run
media_swap_buffers();
#endif
}
// This Method May Be Called In A Situation Where The Proxy Is Disconnected
CALL(9, media_cleanup, void, ()) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Check Connection
if (is_connection_open()) {
// Lock Proxy
start_proxy_call();
// Block Until Cleanup Is Complete
flush_write_cache();
read_byte();
// Close The Connection
close_connection();
// Release Proxy
end_proxy_call();
}
#else
// Run
media_cleanup();
// Confirm Cleanup
write_byte(0);
// Close The Connection
close_connection();
#endif
}
CALL(10, media_get_framebuffer_size, void, (int *width, int *height)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Get Return Values
*width = (int) read_int();
*height = (int) read_int();
// Release Proxy
end_proxy_call();
#else
int width;
int height;
// Run
media_get_framebuffer_size(&width, &height);
// Return Values
write_int((uint32_t) width);
write_int((uint32_t) height);
#endif
}
CALL(59, media_audio_update, void, (float volume, float x, float y, float z, float yaw)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Arguments
write_float(volume);
write_float(x);
write_float(y);
write_float(z);
write_float(yaw);
// Release Proxy
end_proxy_call();
#else
float volume = read_float();
float x = read_float();
float y = read_float();
float z = read_float();
float yaw = read_float();
// Run
media_audio_update(volume, x, y, z, yaw);
#endif
}
CALL(60, media_audio_play, void, (const char *source, const char *name, float x, float y, float z, float pitch, float volume, int is_ui)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Arguments
write_string(source);
write_string(name);
write_float(x);
write_float(y);
write_float(z);
write_float(pitch);
write_float(volume);
write_int(is_ui);
// Release Proxy
end_proxy_call();
#else
char *source = read_string();
char *name = read_string();
float x = read_float();
float y = read_float();
float z = read_float();
float pitch = read_float();
float volume = read_float();
int is_ui = read_int();
// Run
media_audio_play(source, name, x, y, z, pitch, volume, is_ui);
// Free
free(source);
free(name);
#endif
}
CALL(62, media_set_interactable, void, (int is_interactable)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Arguments
write_int(is_interactable);
// Release Proxy
end_proxy_call();
#else
int is_interactable = read_int();
// Run
media_set_interactable(is_interactable);
#endif
}
CALL(63, media_disable_vsync, void, ()) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Release Proxy
end_proxy_call();
#else
// Run
media_disable_vsync();
#endif
}
CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled)) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Arguments
write_int(enabled);
// Release Proxy
end_proxy_call();
#else
int enabled = read_int();
// Run
media_set_raw_mouse_motion_enabled(enabled);
#endif
}
CALL(66, media_force_egl, void, ()) {
#if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy
start_proxy_call();
// Release Proxy
end_proxy_call();
#else
// Run
media_force_egl();
#endif
}

View File

@ -1,170 +0,0 @@
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <csignal>
#include <sys/wait.h>
#include <fcntl.h>
#include <string>
#include <unordered_map>
#include <fstream>
#include <media-layer/core.h>
#include "../common/common.h"
// Track Client State
static int _client_is_alive = 0;
static int _client_status = 0;
static void update_client_state(int is_alive, int status) {
_client_is_alive = is_alive;
_client_status = status;
}
// Check State Of Proxy And Exit If Invalid
void _check_proxy_state() {
// Check Client State
if (!_client_is_alive) {
void_write_cache(); // Child Is Dead, No Reason To Send A Dead Process Data
char *exit_status = NULL;
get_exit_status_string(_client_status, &exit_status);
PROXY_ERR("Client Terminated%s", exit_status);
}
}
// Start Proxy Client
static pid_t _client_pid;
static void sigchld_handler(__attribute__((unused)) int sig) {
// Track
int status;
// Reap
int saved_errno = errno;
// Only waitpid() Proxy Client, Other Sub-Processes Are Handled By pclose()
if (waitpid(_client_pid, &status, WNOHANG) == _client_pid) {
// Handle Client Death
untrack_child(_client_pid);
update_client_state(0, status);
}
errno = saved_errno;
}
static void start_media_layer_proxy_client(int read, int write) {
// Reap Children
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NOCLDSTOP;
sa.sa_handler = &sigchld_handler;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
PROXY_ERR("Unable To Install Signal Handler: %s", strerror(errno));
}
// Fork And Start
pid_t ret = fork();
if (ret == -1) {
PROXY_ERR("Unable To Launch Client: %s", strerror(errno));
} else if (ret == 0) {
// Child Process
// Set Debug Tag
reborn_debug_tag = CHILD_PROCESS_TAG;
// Prepare Arguments
char *read_str = NULL;
safe_asprintf(&read_str, "%i", read);
char *write_str = NULL;
safe_asprintf(&write_str, "%i", write);
const char *argv[] = {"media-layer-proxy-client", read_str, write_str, NULL};
// Setup Environment
setup_exec_environment(0);
// Run
safe_execvpe(argv, (const char *const *) environ);
} else {
// Parent Process
_client_pid = ret;
track_child(_client_pid);
}
update_client_state(1, 0);
}
// Maximize Pipe Buffer Size
static void maximize_pipe_fd_size(int fd) {
// Read Maximum Pipe Size
std::ifstream max_size_file("/proc/sys/fs/pipe-max-size");
if (!max_size_file.good()) {
PROXY_ERR("%s", "Unable To Open Maximum Pipe Size File");
}
// Read One Line
int max_size;
std::string line;
if (std::getline(max_size_file, line) && line.size() > 0) {
max_size = std::stoi(line);
} else {
PROXY_ERR("%s", "Unable To Read Maximum Pipe Size File");
}
// Close
max_size_file.close();
// Set Maximum Pipe Size
errno = 0;
if (fcntl(fd, F_SETPIPE_SZ, max_size) < max_size) {
PROXY_ERR("Unable To Set Maximum Pipe Size: %s", errno != 0 ? strerror(errno) : "Unknown Error");
}
}
static void maximize_pipe_size(int pipe[2]) {
maximize_pipe_fd_size(pipe[0]);
maximize_pipe_fd_size(pipe[1]);
}
// Start Server
static int loaded = 0;
__attribute__((constructor)) void media_ensure_loaded() {
if (!loaded) {
loaded = 1;
// Log
PROXY_INFO("Starting...");
// Create Connection
int server_to_client_pipe[2];
safe_pipe2(server_to_client_pipe, 0);
maximize_pipe_size(server_to_client_pipe);
int client_to_server_pipe[2];
safe_pipe2(client_to_server_pipe, 0);
maximize_pipe_size(client_to_server_pipe);
// Set Connection
set_connection(client_to_server_pipe[0], server_to_client_pipe[1]);
// Start Client
start_media_layer_proxy_client(server_to_client_pipe[0], client_to_server_pipe[1]);
// Wait For Connection Message
char *str = read_string();
if (strcmp(str, CONNECTED_MSG) == 0) {
PROXY_INFO("Connected");
} else {
PROXY_ERR("Unable To Connect");
}
// Free
free(str);
}
}
// Assign Unique ID To Function
static std::unordered_map<std::string, unsigned char> &get_unique_ids() {
static std::unordered_map<std::string, unsigned char> unique_ids;
return unique_ids;
}
void _assign_unique_id(const char *name, unsigned char id) {
get_unique_ids()[name] = id;
}
unsigned char _get_unique_id(const char *name) {
return get_unique_ids()[name]; // Assume ID Exists
}
// Proxy Call Functions
void _start_proxy_call(unsigned char call_id) {
// Start Call
write_byte(call_id);
}
void end_proxy_call() {
}

View File

@ -1,27 +0,0 @@
#pragma once
#define PROXY_LOG_TAG "(Media Layer Proxy Server) "
// Assign Unique ID To Function
__attribute__((visibility("internal"))) void _assign_unique_id(const char *name, unsigned char id);
__attribute__((visibility("internal"))) unsigned char _get_unique_id(const char *name);
// Must Call After Every Call
__attribute__((visibility("internal"))) void _start_proxy_call(unsigned char call_id);
#define start_proxy_call() \
{ \
static int _loaded_id = 0; \
static unsigned char _call_id; \
if (!_loaded_id) { \
_loaded_id = 1; \
_call_id = _get_unique_id(__func__); \
} \
_start_proxy_call(_call_id); \
}
__attribute__((visibility("internal"))) void end_proxy_call();
#define CALL(unique_id, name, return_type, args) \
__attribute__((constructor)) static void _init_##name() { \
_assign_unique_id(#name, unique_id); \
} \
return_type name args

View File

@ -0,0 +1,30 @@
project(media-layer-trampoline)
# Configuration
set(MEDIA_LAYER_TRAMPOLINE_SRC src/media-layer-core.c) # Media Layer Trampoline Source
if(NOT MCPI_HEADLESS_MODE)
list(APPEND MEDIA_LAYER_TRAMPOLINE_SRC src/GLESv1_CM.c)
endif()
# Build
if(BUILD_NATIVE_COMPONENTS)
# Host Component
add_library(media-layer-trampoline src/host/host.c ${MEDIA_LAYER_TRAMPOLINE_SRC})
target_link_libraries(media-layer-trampoline reborn-util media-layer-core)
if(NOT MCPI_HEADLESS_MODE)
target_link_libraries(media-layer-trampoline GLESv1_CM)
endif()
target_compile_definitions(media-layer-trampoline PRIVATE -DMEDIA_LAYER_TRAMPOLINE_HOST)
# Install
install(TARGETS media-layer-trampoline DESTINATION "${MCPI_LIB_DIR}")
elseif(BUILD_ARM_COMPONENTS)
# Guest Component
add_library(media-layer-core SHARED src/guest/guest.c ${MEDIA_LAYER_TRAMPOLINE_SRC} $<TARGET_OBJECTS:media-layer-extras>)
target_link_libraries(media-layer-core media-layer-headers reborn-util)
target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_TRAMPOLINE_GUEST)
# Install
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
install(TARGETS media-layer-core DESTINATION "${MCPI_LIB_DIR}")
endif()
install(TARGETS media-layer-core EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
endif()

View File

@ -0,0 +1,581 @@
#include <stdint.h>
#include <GLES/gl.h>
#include <libreborn/libreborn.h>
#include "common/common.h"
CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pname, (uint32_t) params);
#else
GLenum pname = next_int();
GLfloat *params = next_ptr();
// Run
func(pname, params);
#endif
}
// 'pointer' Is Only Supported As An Integer, Not As An Actual Pointer
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
#define CALL_GL_POINTER(unique_id, name) \
CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) \
trampoline(size, type, stride, (uint32_t) pointer); \
}
#else
#define CALL_GL_POINTER(unique_id, name) \
CALL(unique_id, name, unused, unused) \
GLint size = next_int(); \
GLenum type = next_int(); \
GLsizei stride = next_int(); \
const void *pointer = (const void *) (uint64_t) next_int(); \
/* Run */ \
func(size, type, stride, pointer); \
}
#endif
CALL_GL_POINTER(12, glVertexPointer)
CALL(13, glLineWidth, void, (GLfloat width))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pun_to(uint32_t, width));
#else
GLfloat width = next_float();
// Run
func(width);
#endif
}
CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(sfactor, dfactor);
#else
GLenum sfactor = next_int();
GLenum dfactor = next_int();
// Run
func(sfactor, dfactor);
#endif
}
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(mode, first, count);
#else
GLenum mode = next_int();
GLint first = next_int();
GLsizei count = next_int();
// Run
func(mode, first, count);
#endif
}
CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pun_to(uint32_t, red), pun_to(uint32_t, green), pun_to(uint32_t, blue), pun_to(uint32_t, alpha));
#else
GLfloat red = next_float();
GLfloat green = next_float();
GLfloat blue = next_float();
GLfloat alpha = next_float();
// Run
func(red, green, blue, alpha);
#endif
}
CALL(17, glClear, void, (GLbitfield mask))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(mask);
#else
GLbitfield mask = next_int();
// Run
func(mask);
#endif
}
CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(target, size, (uint32_t) data, usage);
#else
GLenum target = next_int();
GLsizeiptr size = next_int();
const void *data = next_ptr();
GLenum usage = next_int();
// Run
func(target, size, data, usage);
#endif
}
CALL(19, glFogx, void, (GLenum pname, GLfixed param))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pname, param);
#else
GLenum pname = next_int();
GLfixed param = next_int();
// Run
func(pname, param);
#endif
}
CALL(20, glFogf, void, (GLenum pname, GLfloat param))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pname, pun_to(uint32_t, param));
#else
GLenum pname = next_int();
GLfloat param = next_float();
// Run
func(pname, param);
#endif
}
CALL(21, glMatrixMode, void, (GLenum mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(mode);
#else
GLenum mode = next_int();
// Run
func(mode);
#endif
}
CALL_GL_POINTER(22, glColorPointer)
CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(x, y, width, height);
#else
GLint x = next_int();
GLint y = next_int();
GLsizei width = next_int();
GLsizei height = next_int();
// Run
func(x, y, width, height);
#endif
}
CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(target, pname, param);
#else
GLenum target = next_int();
GLenum pname = next_int();
GLint param = next_int();
// Run
func(target, pname, param);
#endif
}
CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(target, level, internalformat, width, height, border, format, type, (uint32_t) pixels);
#else
GLenum target = next_int();
GLint level = next_int();
GLint internalformat = next_int();
GLsizei width = next_int();
GLsizei height = next_int();
GLint border = next_int();
GLenum format = next_int();
GLenum type = next_int();
const void *pixels = next_ptr();
// Run
func(target, level, internalformat, width, height, border, format, type, pixels);
#endif
}
CALL(26, glEnable, void, (GLenum cap))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(cap);
#else
GLenum cap = next_int();
// Run
func(cap);
#endif
}
CALL(27, glEnableClientState, void, (GLenum array))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(array);
#else
GLenum array = next_int();
// Run
func(array);
#endif
}
CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pun_to(uint32_t, factor), pun_to(uint32_t, units));
#else
GLfloat factor = next_float();
GLfloat units = next_float();
// Run
func(factor, units);
#endif
}
CALL_GL_POINTER(41, glTexCoordPointer)
CALL(29, glDisableClientState, void, (GLenum array))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(array);
#else
GLenum array = next_int();
// Run
func(array);
#endif
}
CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pun_to(uint32_t, near), pun_to(uint32_t, far));
#else
GLclampf near = next_float();
GLclampf far = next_float();
// Run
func(near, far);
#endif
}
CALL(31, glDepthFunc, void, (GLenum func))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(func);
#else
GLenum func2 = next_int();
// Run
func(func2);
#endif
}
CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(target, buffer);
#else
GLenum target = next_int();
GLenum buffer = next_int();
// Run
func(target, buffer);
#endif
}
CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pun_to(uint32_t, red), pun_to(uint32_t, green), pun_to(uint32_t, blue), pun_to(uint32_t, alpha));
#else
GLclampf red = next_float();
GLclampf green = next_float();
GLclampf blue = next_float();
GLclampf alpha = next_float();
// Run
func(red, green, blue, alpha);
#endif
}
CALL(34, glPopMatrix, void, ())
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline();
#else
// Run
func();
#endif
}
CALL(35, glLoadIdentity, void, ())
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline();
#else
// Run
func();
#endif
}
CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z));
#else
GLfloat x = next_float();
GLfloat y = next_float();
GLfloat z = next_float();
// Run
func(x, y, z);
#endif
}
CALL(37, glPushMatrix, void, ())
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline();
#else
// Run
func();
#endif
}
CALL(38, glDepthMask, void, (GLboolean flag))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(flag);
#else
GLboolean flag = next_int();
// Run
func(flag);
#endif
}
CALL(39, glHint, void, (GLenum target, GLenum mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(target, mode);
#else
GLenum target = next_int();
GLenum mode = next_int();
// Run
func(target, mode);
#endif
}
CALL(40, glMultMatrixf, void, (const GLfloat *m))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline((uint32_t) m);
#else
GLfloat *m = next_ptr();
// Run
func(m);
#endif
}
CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(n, (uint32_t) buffers);
#else
GLsizei n = next_int();
GLuint *buffers = next_ptr();
// Run
func(n, buffers);
#endif
}
CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(red, green, blue, alpha);
#else
GLboolean red = next_int();
GLboolean green = next_int();
GLboolean blue = next_int();
GLboolean alpha = next_int();
// Run
func(red, green, blue, alpha);
#endif
}
CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(target, level, xoffset, yoffset, width, height, format, type, (uint32_t) pixels);
#else
GLenum target = next_int();
GLint level = next_int();
GLint xoffset = next_int();
GLint yoffset = next_int();
GLsizei width = next_int();
GLsizei height = next_int();
GLenum format = next_int();
GLenum type = next_int();
const void *pixels = next_ptr();
// Run
func(target, level, xoffset, yoffset, width, height, format, type, pixels);
#endif
}
CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(n, (uint32_t) textures);
#else
GLsizei n = next_int();
GLuint *textures = next_ptr();
// Run
func(n, textures);
#endif
}
CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(n, (uint32_t) textures);
#else
GLsizei n = next_int();
GLuint *textures = next_ptr();
// Run
func(n, textures);
#endif
}
CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(func, pun_to(uint32_t, ref));
#else
GLenum func2 = next_int();
GLclampf ref = next_float();
// Run
func(func2, ref);
#endif
}
CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pname, (uint32_t) params);
#else
GLenum pname = next_int();
GLfloat *params = next_ptr();
// Run
func(pname, params);
#endif
}
CALL(49, glBindTexture, void, (GLenum target, GLuint texture))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(target, texture);
#else
GLenum target = next_int();
GLuint texture = next_int();
// Run
func(target, texture);
#endif
}
CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z));
#else
GLfloat x = next_float();
GLfloat y = next_float();
GLfloat z = next_float();
// Run
func(x, y, z);
#endif
}
CALL(51, glShadeModel, void, (GLenum mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(mode);
#else
GLenum mode = next_int();
// Run
func(mode);
#endif
}
CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pun_to(uint32_t, left), pun_to(uint32_t, right), pun_to(uint32_t, bottom), pun_to(uint32_t, top), pun_to(uint32_t, near), pun_to(uint32_t, far));
#else
GLfloat left = next_float();
GLfloat right = next_float();
GLfloat bottom = next_float();
GLfloat top = next_float();
GLfloat near = next_float();
GLfloat far = next_float();
// Run
func(left, right, bottom, top, near, far);
#endif
}
CALL(53, glDisable, void, (GLenum cap))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(cap);
#else
GLenum cap = next_int();
// Run
func(cap);
#endif
}
CALL(54, glCullFace, void, (GLenum mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(mode);
#else
GLenum mode = next_int();
// Run
func(mode);
#endif
}
CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pun_to(uint32_t, angle), pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z));
#else
GLfloat angle = next_float();
GLfloat x = next_float();
GLfloat y = next_float();
GLfloat z = next_float();
// Run
func(angle, x, y, z);
#endif
}
CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(x, y, width, height);
#else
GLint x = next_int();
GLint y = next_int();
GLsizei width = next_int();
GLsizei height = next_int();
// Run
func(x, y, width, height);
#endif
}
CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pun_to(uint32_t, nx), pun_to(uint32_t, ny), pun_to(uint32_t, nz));
#else
GLfloat nx = next_float();
GLfloat ny = next_float();
GLfloat nz = next_float();
// Run
func(nx, ny, nz);
#endif
}
CALL(58, glIsEnabled, GLboolean, (GLenum cap))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
return trampoline(cap);
#else
GLenum cap = next_int();
// Run
ret(func(cap));
#endif
}
CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(pname, (uint32_t) params);
#else
GLenum pname = next_int();
GLint *params = next_ptr();
// Run
func(pname, params);
#endif
}
CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(x, y, width, height, format, type, (uint32_t) data);
#else
GLint x = next_int();
GLint y = next_int();
GLsizei width = next_int();
GLsizei height = next_int();
GLenum format = next_int();
GLenum type = next_int();
void *data = next_ptr();
// Run
func(x, y, width, height, format, type, data);
#endif
}
CALL(67, glGenBuffers, void, (GLsizei n, GLuint *buffers))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(n, (uint32_t) buffers);
#else
GLsizei n = next_int();
GLuint *buffers = next_ptr();
// Run
func(n, buffers);
#endif
}

View File

@ -0,0 +1,21 @@
#pragma once
#if __BYTE_ORDER != __LITTLE_ENDIAN
#error "Only Little Endian Is Supported"
#endif
#if defined(MEDIA_LAYER_TRAMPOLINE_HOST)
#include "../host/host.h"
#elif defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
#include "../guest/guest.h"
#else
#error "Invalid Configuration"
#endif
//#define pun_to(type, x) (*(type *) &(x))
#define pun_to(type, x) \
({ \
union { typeof(x) a; type b; } _pun; \
_pun.a = x; \
_pun.b; \
})

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