Compare commits
844 Commits
Author | SHA1 | Date | |
---|---|---|---|
6f5f405327 | |||
489615d47f | |||
00fee9c410 | |||
b055980103 | |||
b767b9d4ec | |||
c5f9a519c5 | |||
9428a5a1e1 | |||
013c1db336 | |||
a80b5fb5c2 | |||
bf24ace78e | |||
2568b05053 | |||
dcafeb5c44 | |||
3771666a14 | |||
b71c089fb3 | |||
71946d2087 | |||
b2ec2728e3 | |||
71042da861 | |||
5d8aa28113 | |||
aea31dd4c8 | |||
f0005ff002 | |||
587ba38ffe | |||
c6048ec4fb | |||
0ccf578478 | |||
814217a259 | |||
cfac7d0a12 | |||
c531e7ba7d | |||
bddc299664 | |||
cc060accaf | |||
09c8af0396 | |||
a740814354 | |||
890bd537b2 | |||
983e474b33 | |||
2c3bb41293 | |||
3d89fb691a | |||
4e1476bcfd | |||
8ed425392a | |||
b2c13c8257 | |||
2eb6a1c5be | |||
ef3292c5e0 | |||
67ceb4ad00 | |||
e1d9fc492b | |||
acec86b9b5 | |||
66d2e43f55 | |||
596ff01f75 | |||
57aed4d0b3 | |||
fd26000fd4 | |||
454734ab68 | |||
d3b70878be | |||
7f9d1d843e | |||
900169a728 | |||
633b165af0 | |||
86e8c0dd67 | |||
332acd49fb | |||
c2750bbaec | |||
70ef421780 | |||
ed59e19c52 | |||
dd760cc6f2 | |||
00f90afc2a | |||
4a91937b0a | |||
a6cc0b88b5 | |||
0b542701c5 | |||
fc7ecd528a | |||
2785e3f138 | |||
386f52a85f | |||
871288ee12 | |||
5d7056645d | |||
ecbbcef203 | |||
bbae01a471 | |||
6b5105e74d | |||
57503d6a31 | |||
58a6706cf9 | |||
f501f9a7c9 | |||
203d46c849 | |||
58efe19609 | |||
23b3cbe72f | |||
b339b53f42 | |||
a8d0962491 | |||
a63125f335 | |||
eeace9cf14 | |||
dd25805af9 | |||
a6dad72778 | |||
9ae6cd17cf | |||
644e9e421b | |||
419ad9c98c | |||
a0a566f594 | |||
e6deab9664 | |||
69fcc6cdb3 | |||
ee44a0ce88 | |||
62d3512a38 | |||
d011d76f20 | |||
dc7d3a5b8f | |||
0f5d8730b0 | |||
f5da0f60e5 | |||
fbb3152a70 | |||
18f7d64405 | |||
1001427309 | |||
b2db67b4bf | |||
d289f40a5e | |||
e7b0932f60 | |||
8bc335b479 | |||
73b3cd10af | |||
463ede508e | |||
0c92551e8a | |||
6388663b6c | |||
5668dcc852 | |||
d4ab0099f0 | |||
3d8525a321 | |||
b11cc95e50 | |||
661cfd02ad | |||
66f4f11a68 | |||
52ca5bb734 | |||
916902ab68 | |||
9bdde40f3f | |||
cbca78ec16 | |||
65190afe73 | |||
be3ccae7c1 | |||
00d193e732 | |||
65ee4d8a78 | |||
3598fbc922 | |||
b5e9a91f75 | |||
18c6247e0c | |||
c525d69dc3 | |||
72eb1945cf | |||
5ca2a63b5e | |||
72e2c4947d | |||
be1f3bf50e | |||
e2c82071c7 | |||
9bb6b86c73 | |||
c0156336df | |||
f1fe1c140c | |||
8ef6e0885a | |||
c5937e6794 | |||
07f5e188f7 | |||
18b25486e7 | |||
72372c7457 | |||
63e2525ee9 | |||
98c4ee306d | |||
5f2923b789 | |||
036d0a0653 | |||
e837610380 | |||
88f59d951a | |||
0521b540fd | |||
d2b07f7661 | |||
688bee1aaa | |||
d4c0f54245 | |||
f08afbf654 | |||
f7bc756063 | |||
7718fe5b12 | |||
6a2ecb23ed | |||
5e229fb6a8 | |||
cecd61ed72 | |||
57df81e425 | |||
a830f66c41 | |||
6fb1c8d59a | |||
6740eb595e | |||
99a7407404 | |||
0977f557b8 | |||
3b5149abff | |||
b2db6bcfd2 | |||
36fe263ede | |||
74ee75e12f | |||
38d7dda1a7 | |||
460cd38ddf | |||
b71f6c7008 | |||
8bc90dae04 | |||
1bf19268f0 | |||
69a9613e4f | |||
a0f32a15a7 | |||
d52c16e722 | |||
2d9659f273 | |||
3414fb817c | |||
c60428c600 | |||
4e2437dbd6 | |||
a1ea91ad89 | |||
f9e0f54620 | |||
804c9da179 | |||
cdc1a82142 | |||
04b9ad5efd | |||
8203e20971 | |||
4dc69885f2 | |||
36cb84b672 | |||
f53f405bdd | |||
60a5accff2 | |||
c9fafd6cd4 | |||
668552e354 | |||
fedc006a4b | |||
1dc23fe615 | |||
ef3f8da720 | |||
eca42150cb | |||
db45df1e52 | |||
0e44bb5f06 | |||
3088a13725 | |||
56d93f0150 | |||
3132f9442d | |||
b129f0a503 | |||
97bc124d72 | |||
b23f7f1618 | |||
bbaa69edeb | |||
6cfc1a7e20 | |||
f25a2adcef | |||
6ae475785e | |||
51bbad15f4 | |||
73454adc22 | |||
4d54a9d28c | |||
d7616419bc | |||
823495a811 | |||
03c7c50d48 | |||
f15625ff79 | |||
e2d32cad21 | |||
eeef63d9ef | |||
e1f0787e48 | |||
37e1abbdd3 | |||
c88db307d7 | |||
75fc48da24 | |||
cd39733177 | |||
592d6c4e63 | |||
d519142a8a | |||
09bae1cf3e | |||
4523935d62 | |||
|
f3f8e342d8 | ||
|
f010e51c3a | ||
|
91ee97f005 | ||
|
a6b01da677 | ||
|
2549670ee4 | ||
|
d0954a22f3 | ||
49a54a7396 | |||
a305cf9e38 | |||
cf6989bed2 | |||
b2a7fe3eaf | |||
7739fb6b9b | |||
f3755387e8 | |||
b1b28defd5 | |||
18c5d34974 | |||
|
76a66a0ba5 | ||
|
a6ad1994de | ||
|
8de638eb1a | ||
|
5e5088e3ef | ||
|
a6e0cd8f13 | ||
|
3ff24c2a92 | ||
d74d1501ce | |||
fb84bcc06b | |||
117c5d2702 | |||
9556d13791 | |||
|
f8bd6d380b | ||
|
5d57253d56 | ||
|
6ac808919f | ||
|
5353bc188d | ||
|
f57c0a6190 | ||
b033912633 | |||
a2b3bb128b | |||
180ba9dcaf | |||
71cc24104c | |||
6951ebe620 | |||
28dbb2eacd | |||
d86018717e | |||
db22caa50f | |||
ecbcfb2922 | |||
781377005e | |||
6e306e500d | |||
7e300a6e1b | |||
f5a680af7b | |||
|
c62d5264a8 | ||
|
93498ce9c0 | ||
90a2b0ac85 | |||
|
2d9d4a638a | ||
|
8c265a69d9 | ||
b5e9486460 | |||
7fc5638143 | |||
7ba9daa84e | |||
930d0120f3 | |||
31fcff13e9 | |||
41fcc942fa | |||
ddd9226e9e | |||
a336cd1c7b | |||
eaf6dd2fe2 | |||
99b43ddb5a | |||
4f32cfab45 | |||
69211eb31d | |||
58713976d4 | |||
d175f692e0 | |||
6d4ff44092 | |||
1771919cc1 | |||
522cee2d3b | |||
ccc7e5b190 | |||
7c9d16d662 | |||
49f56bd90d | |||
0b252faa5f | |||
|
233e8d691b | ||
|
83a282551d | ||
|
29b49ac70a | ||
|
118fc6f396 | ||
|
e95236023c | ||
46241c9aa0 | |||
f7be586a4c | |||
|
5c5538df2f | ||
|
2995d1c9ad | ||
|
b9b44a62bc | ||
|
7e546a4a09 | ||
|
be5bcf24c4 | ||
91ff082c97 | |||
40cd1b0a14 | |||
5c607d96b8 | |||
6e9b364f81 | |||
67a0d3017b | |||
e4d9ee4f20 | |||
d32fa2d265 | |||
34c24378f3 | |||
b7b60876d8 | |||
4dff667749 | |||
aa92da6fdd | |||
0be1f4fce8 | |||
631cbc07d0 | |||
5f8c700081 | |||
ac55d7d6b3 | |||
ef29e4fc0e | |||
35c6adf94b | |||
1d08b8a29e | |||
7296fcee83 | |||
97b46ad01a | |||
17d11647e7 | |||
48137f9665 | |||
c956151603 | |||
73b51be43f | |||
71b11b314b | |||
168b825bf4 | |||
edca3ad394 | |||
1aed33a48b | |||
177c5262a6 | |||
7969fb2127 | |||
b0aac13057 | |||
80c0f24a5d | |||
0f9da6148b | |||
ea48728a68 | |||
3e7037f621 | |||
11230c120d | |||
1f05424651 | |||
98db527a13 | |||
85e04fbcc6 | |||
018e506c80 | |||
945ce81fe1 | |||
fab66319ea | |||
99424546f8 | |||
cef22a5325 | |||
67ef365505 | |||
588eb5feb0 | |||
c711c8b019 | |||
864c096785 | |||
9ef0868889 | |||
5b792fbf3a | |||
c908d46d54 | |||
db03d964de | |||
c0cd9b8b1f | |||
a8835153b0 | |||
e1f2867d78 | |||
7a5fef7024 | |||
da9edee160 | |||
9e517f5e60 | |||
85e3cb6228 | |||
1dd0526197 | |||
7ecc6cb00b | |||
4189f3fd1d | |||
de18189b44 | |||
a622858a18 | |||
b005106b44 | |||
61add936cc | |||
d3b78acbef | |||
07a27d4dd9 | |||
6779905830 | |||
c3fda82642 | |||
e0ab968fa3 | |||
45b93534fa | |||
5273d6cdf9 | |||
06af8c821f | |||
7b4729b8ec | |||
ffad36224e | |||
236f7e385d | |||
f506b10051 | |||
9b4a9994ba | |||
32cd0c426f | |||
5690df3ebe | |||
b4bebfb701 | |||
1fa444f810 | |||
f3dc145d4a | |||
5d65b4092f | |||
81aa01daf9 | |||
2edfa62c25 | |||
4870afcc7f | |||
c178e5e5eb | |||
57b0bce12c | |||
95345a5f1b | |||
717b4a11a7 | |||
40a527bb23 | |||
2766611878 | |||
8532e7707f | |||
703ced337b | |||
bedd5ea53a | |||
eb3c5d2e6f | |||
ab1dbd2996 | |||
29bc6faf3d | |||
5aae95fd37 | |||
5739c5f999 | |||
34ef2d51aa | |||
f328800ce8 | |||
02c73176a5 | |||
16ce586e9c | |||
6378a18494 | |||
6994671c6d | |||
58f329bb4f | |||
d03a1a96ff | |||
35cafec1ee | |||
4ab6b7aed1 | |||
edd346dd66 | |||
0d9f498aa7 | |||
d761ad8614 | |||
4977898bcd | |||
513628d91f | |||
9a521ebca2 | |||
deae36ed94 | |||
00d6ee4f9a | |||
8dd562a20f | |||
c11c7203ef | |||
379da809cd | |||
96baf9627a | |||
279b101e46 | |||
b190851d36 | |||
c3c7d22006 | |||
3abbb0cb16 | |||
dda511f8ff | |||
0ccc1ba6e8 | |||
9d3a0964b0 | |||
ed9bef8492 | |||
c4e26c5be2 | |||
0c82db4116 | |||
ce168c1c16 | |||
93eb7807aa | |||
12074e15d9 | |||
010aaa89e3 | |||
0e32fd36c8 | |||
6c89e64f8b | |||
9fe6a2fb39 | |||
c87a6fa3c0 | |||
69d3832815 | |||
67002006f3 | |||
eb96d80e5a | |||
968001897d | |||
68519f06fd | |||
b3b935dd1d | |||
006243d02f | |||
3c1bce876c | |||
484d3e7f90 | |||
23df63abb7 | |||
126c3d618d | |||
3937f88084 | |||
4bd2fecfa2 | |||
b539491713 | |||
ea4c5c77a1 | |||
e506dbb1bb | |||
699d83c61b | |||
329f92c0a4 | |||
bfa0567ac9 | |||
a94708a1ae | |||
905a569c09 | |||
53f602403a | |||
2f64552926 | |||
2b920f50ba | |||
d859a16b5a | |||
78e17d8c18 | |||
0e7a108a0a | |||
ca21877000 | |||
f1ec29ec86 | |||
13ac816baa | |||
6ba86b9193 | |||
49f8da2a80 | |||
e8faee62fa | |||
a8ff58f0c4 | |||
daccf65361 | |||
3d508d7609 | |||
0061edb3b2 | |||
baeeceeaac | |||
211bf265ff | |||
0dd0706f52 | |||
1743626113 | |||
4ed11b67e7 | |||
365e238c29 | |||
36c4ed7e4d | |||
cf1faf4835 | |||
cb4560a602 | |||
b3a96dc3e2 | |||
be300a2809 | |||
77d7b82a14 | |||
b59c580f6a | |||
524a390921 | |||
ead7e575f3 | |||
f2a9b274d2 | |||
dd4972172d | |||
8822a22987 | |||
53cb68beee | |||
47ae13ac51 | |||
492725ed63 | |||
7c2d0d5625 | |||
9449cdf747 | |||
d95a9e1871 | |||
8a83702c3c | |||
be7e44fd3c | |||
651c49980e | |||
46a53ba3cf | |||
186728ca5f | |||
9412c07c45 | |||
2717e062b3 | |||
0723fb1894 | |||
16f919d147 | |||
e18fc9fc63 | |||
3ebdffd396 | |||
82b6252927 | |||
4a35935daf | |||
89c29f14b1 | |||
4edfaeead4 | |||
bfcdd3c7e9 | |||
5467b5178f | |||
8f49c550ba | |||
50eb4801a0 | |||
a3eef9fc3b | |||
f455780833 | |||
0150879d2b | |||
623cf06516 | |||
0b1849a9ad | |||
157d51e6b6 | |||
ed58356dd8 | |||
fae728061a | |||
353565ce5a | |||
efa21bc8a5 | |||
61f9a329ea | |||
3c0c260920 | |||
0592db9bdf | |||
3fee57ce60 | |||
b3c32b211b | |||
ea92e5188e | |||
9a4b70b5ca | |||
b5974f3f46 | |||
709de17558 | |||
3894e98a04 | |||
bf890d190b | |||
a40da62b70 | |||
59b8fd9f54 | |||
55a815643b | |||
aa471fb4ba | |||
4c33b6da9a | |||
3048b3bf50 | |||
03312f44b6 | |||
bdeb45eed2 | |||
9f63fa712f | |||
e319d46ea0 | |||
c88cbd151e | |||
46abc4c4bd | |||
00f8ed4752 | |||
0fd8ba7de9 | |||
07baea7b5a | |||
8792e5749d | |||
53b2c20b8b | |||
244a69d1aa | |||
a1f777f632 | |||
5d8a1e4230 | |||
742ead51e1 | |||
c33a27b2ea | |||
c1377d4f2a | |||
e0ebc7fc32 | |||
0fcda17120 | |||
e9e9b90bdb | |||
0fd562af40 | |||
1eb06b6b60 | |||
c6983ac6c5 | |||
4a69d38e35 | |||
5636abc051 | |||
33c7d025a5 | |||
7f7bc08201 | |||
b36df1d8ff | |||
bf58129164 | |||
654c719187 | |||
e1e2977c29 | |||
a85fc1f5fa | |||
e3a4cabf61 | |||
4c3fefae89 | |||
729eff232a | |||
560c040416 | |||
ea49470450 | |||
5a5fe4c731 | |||
406aa3f9a6 | |||
55679dd54c | |||
dbee357ebc | |||
bc461d39d5 | |||
21de7487bb | |||
7ad36d0ce1 | |||
d17416421a | |||
154adea292 | |||
291e560c8f | |||
472f5d67a5 | |||
a79a601c59 | |||
e85231bf69 | |||
da0aef568d | |||
f8b7af1370 | |||
6a7d881258 | |||
2e9ee42d75 | |||
941572063e | |||
43d27e8e11 | |||
7e3cfaa1a8 | |||
320e0c652a | |||
e5fc2a61aa | |||
5cf4d7f915 | |||
51d7974ded | |||
16ebea9ed6 | |||
05587efc04 | |||
9ad6cc3906 | |||
12de038f37 | |||
1daede7dba | |||
28a6d59c2d | |||
f2bd893241 | |||
28424aa86a | |||
637f1c1132 | |||
74d14ecaa6 | |||
f3eaa57041 | |||
015235b889 | |||
8c356dd65c | |||
6a9a22ac25 | |||
c45211ad22 | |||
7498c1e932 | |||
734bded289 | |||
b7b130e675 | |||
0a65c91d14 | |||
55475a3a0c | |||
f9acb08e4f | |||
db64afc550 | |||
0465dc75a7 | |||
68a252c3df | |||
866ebfe159 | |||
1f3036c7e1 | |||
a338c11f9d | |||
647a482fbd | |||
6c791d6c9d | |||
d18afddf1b | |||
d851a8f3e1 | |||
a762654e35 | |||
4aeb2fd95b | |||
c60fb51fae | |||
4597e824bb | |||
d372169c79 | |||
99b709fea7 | |||
578bb1c89f | |||
80d5674781 | |||
a925463fdf | |||
a9830c3bba | |||
d114a2d668 | |||
8f782099da | |||
99f33cab61 | |||
4652efcd65 | |||
665fe30a5f | |||
e8ae2a9230 | |||
7b4a8a4d4f | |||
6e6537eea1 | |||
a196581bbe | |||
b32c6013fb | |||
1877996874 | |||
bf14e71c87 | |||
07d79b66ea | |||
0bce0d17ac | |||
0c0a61cd23 | |||
989dd7983b | |||
73f900f8b4 | |||
053bf4aa5f | |||
2b0d1d55ff | |||
b1d81e860f | |||
bf937f8c86 | |||
d72c65b7ab | |||
9d1b6aea65 | |||
f0439e9683 | |||
6d79beeeb6 | |||
747d2032e6 | |||
0f6c3c2e43 | |||
4fad749cdf | |||
f84ffebf8c | |||
e73596fd57 | |||
005492fad4 | |||
80d6385d68 | |||
42ef5b9b8b | |||
d0c2b98ca6 | |||
e252afbe22 | |||
352c9de936 | |||
9efaf5ec42 | |||
97e7655b12 | |||
0bbcf91466 | |||
1582066d0d | |||
19f8228058 | |||
c36f89e523 | |||
7b6fa15893 | |||
615a3a28a0 | |||
f8836fb2ae | |||
521d10a9fd | |||
d36d3aafea | |||
24ec820932 | |||
c1b52370dd | |||
71fadf1645 | |||
5da52a962b | |||
b10616905d | |||
4f4cdf915f | |||
6a6e973867 | |||
032490c7b2 | |||
b037ff6d98 | |||
05ec8f6059 | |||
04e6f345e5 | |||
6ab07f04db | |||
4de452517a | |||
2b0f2b4cc1 | |||
b81d29095b | |||
4d8c8ae3c1 | |||
e7d0d66e54 | |||
d10274988e | |||
cd91a2fd12 | |||
096b442988 | |||
6279ff2f6e | |||
c29f6e4938 | |||
57fd287b74 | |||
530e31820b | |||
04668f223e | |||
9666e4c7f6 | |||
26d956da6a | |||
118bca3fa5 | |||
77275693de | |||
b92ec85221 | |||
f6dd4a17e6 | |||
b5556e91c3 | |||
7b89f7604f | |||
d824b0f878 | |||
d2fffeafc1 | |||
b2f6695cb0 | |||
7c8e9dbe04 | |||
c664193170 | |||
0ccc05ad90 | |||
62204aa1bf | |||
88843f6cbe | |||
7a55ac09fa | |||
565603821e | |||
59ab4a44fe | |||
f4e0861c29 | |||
5ee784a333 | |||
fdc547c4bc | |||
e7b2365a33 | |||
f1c95b433d | |||
46cb46d6a1 | |||
c1490a9685 | |||
554fed869e | |||
c539c42de2 | |||
f81bf3c67f | |||
3533830669 | |||
28bcb0d5b5 | |||
db6d943bf5 | |||
37a0121f73 | |||
e0423c5de3 | |||
0dbb53e0e7 | |||
4bf4cfee8e | |||
f9e893d1c3 | |||
43b1231153 | |||
6e18ee44fb | |||
a83cb6d211 | |||
5040e28d14 | |||
4eb271540c | |||
0d6db1e606 | |||
0eb10dea7c | |||
02eaf4e9ef | |||
81f0c6bbc9 | |||
3244b87be0 | |||
e8b2f1c22f | |||
accf6aebc6 | |||
2a01a429ef | |||
2f5692afc7 | |||
2e06017429 | |||
f2c2799f7e | |||
bc442034e2 | |||
64ced5655f | |||
1bdb5287e5 | |||
cdbb6bac21 | |||
9bdb12c6ef | |||
ab8de4e24d | |||
ffe7b0e363 | |||
99aac006f4 | |||
a39476228e | |||
1d14cc5059 | |||
107fa29d8d | |||
7e8a74d1b2 | |||
c0b5026221 | |||
054dcba425 | |||
dd539e434a | |||
c21197324b | |||
cd911f5635 | |||
50af254e2a | |||
55feb34251 | |||
21c67a2339 | |||
8e7dfd85b8 | |||
da3f6739eb | |||
fd003d8df2 | |||
39b226685e | |||
10314afdc3 | |||
9a4efef9f1 | |||
5414913620 | |||
55c789dab2 | |||
b762fdadef | |||
06debcddd2 | |||
28335cf82a | |||
997388d61a | |||
fd12a27a51 | |||
56d84d0133 | |||
d1ba4e3cbb | |||
0abe0c2089 | |||
ca911dd634 | |||
a04cf1e707 | |||
8f1dfecc9a | |||
d3e0310a60 | |||
151e404aab | |||
48d796fa46 | |||
688ce20877 | |||
bd57e4b004 | |||
799d3efed9 | |||
19e2ded9bf | |||
465f3cce81 | |||
be9e9efebc | |||
d098e67ee2 | |||
6ebdb49df0 | |||
76cb02ef46 | |||
e501391142 | |||
27ad6caa3b | |||
d602764f38 | |||
bdb027e1f2 | |||
3b886e055d | |||
c513426e05 | |||
b474564647 | |||
cc6f19c836 | |||
adb9d7b08e | |||
c70199b355 | |||
267530e871 | |||
e12e8b5c0f | |||
32debed934 | |||
0936cd4700 | |||
c756153cfb | |||
b607356c86 | |||
f588300da2 | |||
84bfd9506c |
@ -1,7 +0,0 @@
|
||||
.git
|
||||
.gitignore
|
||||
Dockerfile
|
||||
README.md
|
||||
data
|
||||
install.sh
|
||||
build.sh
|
136
.gitea/workflows/build.yml
Normal file
@ -0,0 +1,136 @@
|
||||
name: 'CI'
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- '*'
|
||||
- '!flatpak'
|
||||
|
||||
# Jobs
|
||||
jobs:
|
||||
# Build Project
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- AMD64
|
||||
- ARM64
|
||||
- ARMHF
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
container: node:lts-bullseye
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
# Dependencies
|
||||
- name: Install Dependencies
|
||||
run: ./scripts/install-dependencies.mjs build ${{ matrix.arch }}
|
||||
# Build
|
||||
- name: Build
|
||||
run: ./scripts/build.mjs appimage ${{ matrix.arch }}
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.arch }}
|
||||
path: ./out/*.AppImage*
|
||||
if-no-files-found: error
|
||||
# Test Project
|
||||
test:
|
||||
needs: build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
mode:
|
||||
- Client
|
||||
- Server
|
||||
arch:
|
||||
- AMD64
|
||||
- ARM64
|
||||
- ARMHF
|
||||
name: Test
|
||||
runs-on: ${{ startsWith(matrix.arch, 'ARM') && 'raspberry-pi' || 'ubuntu-latest' }}
|
||||
container: node:lts-bullseye
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false
|
||||
# Dependencies
|
||||
- name: Install Dependencies
|
||||
run: ./scripts/install-dependencies.mjs test ${{ matrix.arch }}
|
||||
# Download Artifact
|
||||
- name: Download Artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.arch }}
|
||||
path: out
|
||||
# Test
|
||||
- name: Test
|
||||
run: ./scripts/test.sh ${{ matrix.mode }} ${{ matrix.arch }}
|
||||
# Example Mods
|
||||
example-mods:
|
||||
needs: build
|
||||
name: Build Example Mods
|
||||
runs-on: ubuntu-latest
|
||||
container: node:lts-bullseye
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false
|
||||
# Dependencies
|
||||
- name: Install Dependencies
|
||||
run: ./scripts/install-dependencies.mjs sdk amd64
|
||||
# SDK
|
||||
- name: Download SDK
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: AMD64
|
||||
path: out
|
||||
- name: Extract SDK
|
||||
run: |
|
||||
./scripts/fix-appimage-for-docker.sh ./out/*.AppImage
|
||||
chmod +x ./out/*.AppImage
|
||||
./out/*.AppImage --appimage-extract-and-run --copy-sdk
|
||||
# Build Example Mods
|
||||
- name: Build Example Mods
|
||||
run: ./example-mods/build.sh
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Example Mods
|
||||
path: ./example-mods/out/*
|
||||
if-no-files-found: error
|
||||
# Create Release
|
||||
release:
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
needs:
|
||||
- build
|
||||
- test
|
||||
- example-mods
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
container: node:lts-bullseye
|
||||
steps:
|
||||
# Dependencies
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '>=1.20.1'
|
||||
# Download Artifacts
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: out
|
||||
# Create Release
|
||||
- name: Create Release
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: ./out/*/*.AppImage*
|
||||
api_key: ${{ secrets.RELEASE_TOKEN }}
|
||||
title: v${{ github.ref_name }}
|
||||
body: '[View Changelog](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/src/branch/master/docs/CHANGELOG.md)'
|
21
.gitignore
vendored
@ -1,5 +1,18 @@
|
||||
/minecraft-pi
|
||||
/libpng
|
||||
/core/build
|
||||
/mods/build
|
||||
/out
|
||||
/debian/tmp
|
||||
/.vscode
|
||||
/build*
|
||||
/CMakeLists.txt.user
|
||||
*.autosave
|
||||
/AppImageBuilder.yml
|
||||
/appimage-builder-cache
|
||||
/appimage-build
|
||||
/AppDir
|
||||
/*.zsync
|
||||
/*.AppImage
|
||||
/core*
|
||||
/qemu_*
|
||||
/example-mods/out
|
||||
/.testing-tmp
|
||||
/cmake-build-*
|
||||
/.idea
|
||||
|
29
.gitmodules
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
[submodule "dependencies/glfw/src"]
|
||||
path = dependencies/glfw/src
|
||||
url = https://github.com/glfw/glfw.git
|
||||
[submodule "dependencies/LIEF/src"]
|
||||
path = dependencies/LIEF/src
|
||||
url = https://github.com/lief-project/LIEF.git
|
||||
[submodule "dependencies/stb_image/include"]
|
||||
path = dependencies/stb_image/include
|
||||
url = https://github.com/nothings/stb.git
|
||||
[submodule "dependencies/utf8cpp/src"]
|
||||
path = dependencies/utf8cpp/src
|
||||
url = https://github.com/nemtrif/utfcpp.git
|
||||
[submodule "archives"]
|
||||
path = archives
|
||||
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/archives.git
|
||||
shallow = true
|
||||
[submodule "dependencies/symbol-processor/src"]
|
||||
path = dependencies/symbol-processor/src
|
||||
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/symbol-processor.git
|
||||
[submodule "dependencies/runtime/src"]
|
||||
path = dependencies/runtime/src
|
||||
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/runtime.git
|
||||
[submodule "dependencies/imgui/src"]
|
||||
path = dependencies/imgui/src
|
||||
url = https://github.com/ocornut/imgui.git
|
||||
ignore = dirty
|
||||
[submodule "dependencies/imgui/glad/src"]
|
||||
path = dependencies/imgui/glad/src
|
||||
url = https://github.com/Dav1dde/glad.git
|
212
CMakeLists.txt
Normal file
@ -0,0 +1,212 @@
|
||||
cmake_minimum_required(VERSION 3.25.0)
|
||||
|
||||
# Avoid Warning About DOWNLOAD_EXTRACT_TIMESTAMP
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
|
||||
# Core Options
|
||||
include(cmake/options/core-options.cmake)
|
||||
|
||||
# Utility Functions
|
||||
include(cmake/util/util.cmake)
|
||||
|
||||
# Build Mode
|
||||
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(IS_MULTI_CONFIG)
|
||||
force_set(CMAKE_CONFIGURATION_TYPES "Release;Debug" STRING)
|
||||
set(FORCE_BUILD_TYPE "")
|
||||
elseif(NOT DEFINED CMAKE_BUILD_TYPE)
|
||||
set(FORCE_BUILD_TYPE "Release")
|
||||
endif()
|
||||
if(DEFINED FORCE_BUILD_TYPE)
|
||||
force_set(CMAKE_BUILD_TYPE "${FORCE_BUILD_TYPE}" STRING)
|
||||
endif()
|
||||
|
||||
# Start Project
|
||||
project(minecraft-pi-reborn)
|
||||
|
||||
# Sanity Checks
|
||||
string(CONCAT ARM_SANITY_CHECK
|
||||
"include(CheckSymbolExists)\n"
|
||||
"check_symbol_exists(\"__arm__\" \"\" IS_ARM_TARGETING)\n"
|
||||
)
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
string(APPEND ARM_SANITY_CHECK
|
||||
"if(NOT IS_ARM_TARGETING)\n"
|
||||
" message(FATAL_ERROR \"ARM-Targeting Compiler Required\")\n"
|
||||
"endif()\n"
|
||||
)
|
||||
endif()
|
||||
cmake_language(EVAL CODE "${ARM_SANITY_CHECK}")
|
||||
|
||||
# Extra Options
|
||||
include(cmake/options/extra-options.cmake)
|
||||
|
||||
# Paths
|
||||
include(cmake/options/paths.cmake)
|
||||
|
||||
# Required Compile Flags
|
||||
set(RELEASE_MODE_GENERATOR "\$<CONFIG:Release>")
|
||||
string(CONCAT COMPILE_FLAGS_SETUP
|
||||
# Optimizations
|
||||
"add_compile_options(\"\$<IF:${RELEASE_MODE_GENERATOR},-O3,-g>\")\n"
|
||||
"add_link_options(\"\$<${RELEASE_MODE_GENERATOR}:-s>\")\n"
|
||||
|
||||
# PIC
|
||||
"set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)\n"
|
||||
|
||||
# Warnings
|
||||
"add_link_options(-Wl,--no-undefined)\n"
|
||||
|
||||
# C Standard
|
||||
"add_definitions(-D_GNU_SOURCE)\n"
|
||||
"set(CMAKE_C_STANDARD 99)\n"
|
||||
"set(CMAKE_CXX_STANDARD 20)\n"
|
||||
|
||||
# Skip RPath
|
||||
"set(CMAKE_SKIP_BUILD_RPATH TRUE)\n"
|
||||
|
||||
# Always Build Shared Libraries
|
||||
"set(BUILD_SHARED_LIBS TRUE CACHE BOOL \"\" FORCE)\n"
|
||||
)
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
string(APPEND COMPILE_FLAGS_SETUP
|
||||
# Disable C++11 String ABI
|
||||
"add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)\n"
|
||||
)
|
||||
endif()
|
||||
cmake_language(EVAL CODE "${COMPILE_FLAGS_SETUP}")
|
||||
|
||||
# Build Dependencies
|
||||
add_subdirectory(dependencies)
|
||||
|
||||
# Fast Math
|
||||
add_compile_options(-ffast-math)
|
||||
|
||||
# Warnings
|
||||
add_compile_options(-Wall -Wextra -Werror -Wpointer-arith -Wshadow -Wnull-dereference)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
# Prevents False Positives
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 10.0)
|
||||
add_compile_options(-Wno-stringop-overflow)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 11.0)
|
||||
add_compile_options(-Wno-array-bounds -Wno-stringop-overread)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Build libreborn
|
||||
add_subdirectory(libreborn)
|
||||
|
||||
# Build Media Layer
|
||||
add_subdirectory(media-layer)
|
||||
|
||||
# Build Launcher
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
add_subdirectory(launcher)
|
||||
endif()
|
||||
|
||||
# Include Symbols
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
add_subdirectory(symbols)
|
||||
endif()
|
||||
|
||||
# Build Mods
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
add_subdirectory(mods)
|
||||
endif()
|
||||
|
||||
# Include Images
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
add_subdirectory(images)
|
||||
endif()
|
||||
|
||||
# Install Prebuilt ARMHF Toolchain Sysroot
|
||||
if(BUILD_NATIVE_COMPONENTS AND MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
|
||||
install_arm_sysroot()
|
||||
endif()
|
||||
|
||||
# Install SDK
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(EXPORT sdk DESTINATION "${MCPI_SDK_DIR}" FILE "sdk-targets.cmake")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake"
|
||||
# Sanity Check
|
||||
"${ARM_SANITY_CHECK}"
|
||||
# Compile Flags
|
||||
"${COMPILE_FLAGS_SETUP}"
|
||||
# Log
|
||||
"message(STATUS \"Using Reborn SDK v${MCPI_VERSION}\")\n"
|
||||
# Include Targets
|
||||
"include(\"\${CMAKE_CURRENT_LIST_DIR}/sdk-targets.cmake\")\n"
|
||||
)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake" DESTINATION "${MCPI_SDK_DIR}")
|
||||
# Calculate Hash Of SDK
|
||||
string(CONCAT SDK_HASH_SCRIPT
|
||||
# Prepare
|
||||
"set(dir \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${MCPI_SDK_DIR}\")\n"
|
||||
"set(out \"\${dir}/.hash\")\n"
|
||||
# Calculate Hashes
|
||||
"set(content \"\")\n"
|
||||
"file(GLOB_RECURSE files LIST_DIRECTORIES FALSE \"\${dir}/*\")\n"
|
||||
"foreach(file IN LISTS files)\n"
|
||||
" file(SHA256 \"\${file}\" hash)\n"
|
||||
" cmake_path(RELATIVE_PATH file BASE_DIRECTORY \"\${dir}\")\n"
|
||||
" string(APPEND content \"\${hash} \${file}\\n\")\n"
|
||||
"endforeach()\n"
|
||||
# Write File
|
||||
"file(WRITE \"\${out}\" \"\${content}\")\n"
|
||||
)
|
||||
install(CODE "${SDK_HASH_SCRIPT}")
|
||||
endif()
|
||||
|
||||
# Packaging
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
include(cmake/cpack/packaging.cmake)
|
||||
endif()
|
||||
|
||||
# Superbuild
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
include(ExternalProject)
|
||||
# Arguments
|
||||
set(ARM_OPTIONS "${MCPI_OPTIONS}")
|
||||
list(APPEND ARM_OPTIONS "-DMCPI_BUILD_MODE:STRING=arm")
|
||||
list(APPEND ARM_OPTIONS "-DCMAKE_INSTALL_MESSAGE:STRING=NEVER")
|
||||
list(APPEND ARM_OPTIONS "-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>")
|
||||
if(NOT MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
|
||||
if(DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
set(ARM_TOOLCHAIN "${CMAKE_TOOLCHAIN_FILE}")
|
||||
endif()
|
||||
else()
|
||||
set(ARM_TOOLCHAIN "${MCPI_CMAKE_TOOLCHAIN_FILE}")
|
||||
endif()
|
||||
if(DEFINED ARM_TOOLCHAIN)
|
||||
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${ARM_TOOLCHAIN}")
|
||||
endif()
|
||||
# Build
|
||||
ExternalProject_Add(arm-components
|
||||
# Source Directory
|
||||
DOWNLOAD_COMMAND ""
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
# Configure
|
||||
CMAKE_CACHE_ARGS ${ARM_OPTIONS}
|
||||
CMAKE_GENERATOR "Ninja Multi-Config"
|
||||
# Build
|
||||
BUILD_COMMAND
|
||||
"${CMAKE_COMMAND}" "--build" "<BINARY_DIR>" "--config" "$<CONFIG>"
|
||||
# Install
|
||||
INSTALL_COMMAND
|
||||
"${CMAKE_COMMAND}" "-E"
|
||||
"rm" "-rf" "<INSTALL_DIR>/${MCPI_INSTALL_DIR}"
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}" "-E" "env" "DESTDIR="
|
||||
"${CMAKE_COMMAND}" "--install" "<BINARY_DIR>" "--config" "$<CONFIG>"
|
||||
# Use Terminal
|
||||
USES_TERMINAL_CONFIGURE TRUE
|
||||
USES_TERMINAL_BUILD TRUE
|
||||
USES_TERMINAL_INSTALL TRUE
|
||||
# Always Build
|
||||
BUILD_ALWAYS TRUE
|
||||
)
|
||||
# Install
|
||||
ExternalProject_Get_Property(arm-components INSTALL_DIR)
|
||||
install(DIRECTORY "${INSTALL_DIR}/${MCPI_INSTALL_DIR}/" DESTINATION "${MCPI_INSTALL_DIR}")
|
||||
endif()
|
27
Dockerfile
@ -1,27 +0,0 @@
|
||||
FROM arm64v8/debian:bullseye
|
||||
|
||||
RUN dpkg --add-architecture armhf
|
||||
|
||||
RUN \
|
||||
apt-get update && \
|
||||
apt-get upgrade -y && \
|
||||
apt-get install -y libglvnd-dev:armhf libsdl1.2-dev:armhf libx11-dev:armhf build-essential zlib1g-dev:armhf git cmake curl gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libfreeimage-dev:armhf libglfw3-dev:armhf xinput:armhf libxfixes-dev:armhf
|
||||
|
||||
RUN ln -s /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2 /usr/lib/libGLESv2.so
|
||||
RUN ln -s /usr/lib/arm-linux-gnueabihf/libEGL.so.1 /usr/lib/libEGL.so
|
||||
|
||||
ADD ./build /app/build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN ./build/download-minecraft-pi.sh
|
||||
|
||||
RUN ./build/build-libpng12.sh
|
||||
|
||||
ADD . /app
|
||||
|
||||
RUN ./build/build-mods.sh
|
||||
|
||||
WORKDIR ./minecraft-pi
|
||||
|
||||
ENTRYPOINT ./launcher
|
@ -1,3 +0,0 @@
|
||||
FROM ubuntu:focal
|
||||
|
||||
RUN apt-get update && apt-get install -y docker.io
|
38
Jenkinsfile
vendored
@ -1,38 +0,0 @@
|
||||
pipeline {
|
||||
agent {
|
||||
dockerfile {
|
||||
filename 'Dockerfile.build'
|
||||
args '-v /var/run/docker.sock:/var/run/docker.sock'
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Install QEMU') {
|
||||
steps {
|
||||
sh 'docker run --rm --privileged multiarch/qemu-user-static --reset -p yes'
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'DOCKER_BUILD_OPTIONS="--no-cache" ./scripts/build.sh'
|
||||
}
|
||||
}
|
||||
stage('Publish') {
|
||||
steps {
|
||||
withCredentials([usernamePassword(credentialsId: 'docker_hub_login', usernameVariable: 'DOCKER_HUB_USERNAME', passwordVariable: 'DOCKER_HUB_PASSWORD')]) {
|
||||
sh 'docker login -u "${DOCKER_HUB_USERNAME}" -p "${DOCKER_HUB_PASSWORD}"'
|
||||
}
|
||||
sh 'docker push thebrokenrail/minecraft-pi'
|
||||
}
|
||||
}
|
||||
stage('Package') {
|
||||
steps {
|
||||
sh './scripts/package.sh'
|
||||
}
|
||||
post {
|
||||
success {
|
||||
archiveArtifacts artifacts: 'out/**', fingerprint: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 TheBrokenRail
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
82
MODDING.md
@ -1,82 +0,0 @@
|
||||
# Modding
|
||||
Modding Minecraft: Pi Edition is possible by patching the binary at runtime. To make this easier ``minecraft-pi-dcoker`` includes a libary called ``libcore.so`` which provides several functions to help you patch the game.
|
||||
|
||||
## Hex Addresses
|
||||
Minecraft: Pi Edition has no symbols so you must patch the hex address of an instruction instead of using a function name. Hex addresses can be found using tools like [Ghidra](https://ghidra-sre.org) or [RetDec](https://retdec.com). To find out what a function does, you can find its equivalent in Minecraft: Pocket Edition 0.6.1 and use its name for reference because Minecraft: Pocket Edition 0.6.1 includes symbols.
|
||||
|
||||
## Loading Directories
|
||||
``minecraft-pi-docker`` loads mods from two locations, ``/app/minecraft-pi/mods``, and ``~/.minecraft/mods``. The first location only exists in the Docker container and is immutable, so you should place your mods in ``~/.minecraft/mods`` which is mounted on the host as ``~/.minecraft-pi/mods``.
|
||||
|
||||
## ``libcore.so`` API
|
||||
Header files and the shared library can be download from [Jenkins](https://jenkins.thebrokenrail.com/job/minecraft-pi-docker/job/master/lastSuccessfulBuild/artifact/out/lib).
|
||||
|
||||
### ``void *overwrite(void *start, void *target)``
|
||||
This method replaces a function with another function.
|
||||
|
||||
#### Parameters
|
||||
- **start:** The function you are replacing.
|
||||
- **target:** The function you are replacing it with.
|
||||
|
||||
#### Return Value
|
||||
The original contents of the function.
|
||||
|
||||
#### Warning
|
||||
This should never be used on functions that are only 1 byte long because it overwrites 2 bytes.
|
||||
|
||||
#### Example
|
||||
```c
|
||||
static int func_injection(int a, int b) {
|
||||
return a + 4;
|
||||
}
|
||||
|
||||
__attribute__((constructor)) static void init() {
|
||||
overwrite((void *) 0xabcde, func_injection);
|
||||
}
|
||||
```
|
||||
|
||||
### ``void revert_overwrite(void *start, void *original)``
|
||||
This allows you to revert ``overwrite()``. This can be used to call the original version of a function.
|
||||
|
||||
#### Parameters
|
||||
- **start:** The function that was overwritten.
|
||||
- **original:** The return value of ``overwrite()``.
|
||||
|
||||
#### Return Value
|
||||
None
|
||||
|
||||
#### Example
|
||||
```c
|
||||
typedef int (*func_t)(int a, int b);
|
||||
static func_t func = (func_t) 0xabcde;
|
||||
static void *func_original = NULL;
|
||||
|
||||
static int func_injection(int a, int b) {
|
||||
revert_overwrite((void *) func, func_original);
|
||||
(*func)(a, b);
|
||||
revert_overwrite((void *) func, func_original);
|
||||
|
||||
return a + 4;
|
||||
}
|
||||
|
||||
__attribute__((constructor)) static void init() {
|
||||
func_original = overwrite((void *) func, func_injection);
|
||||
}
|
||||
```
|
||||
|
||||
### ``void patch(void *start, unsigned char patch[])``
|
||||
This allows you to replace a specific instruction.
|
||||
|
||||
#### Parameters
|
||||
- **start:** The target instruction.
|
||||
- **patch:** The new instruction (array length must be 4).
|
||||
|
||||
#### Return Value
|
||||
None
|
||||
|
||||
#### Example
|
||||
```c
|
||||
__attribute__((constructor)) static void init() {
|
||||
unsigned char patch_data[4] = {0x00, 0x00, 0x00, 0x00};
|
||||
patch((void *) 0xabcde, patch_data);
|
||||
}
|
||||
```
|
21
README.md
@ -1,8 +1,17 @@
|
||||
# Minecraft: Pi Edition For Docker
|
||||
This is a project allowing Minecraft: Pi Edition to be run without a Raspberry Pi using Docker.
|
||||
<p align="center">
|
||||
<img alt="Start Screen" src="images/start.png">
|
||||
</p>
|
||||
|
||||
## Setup
|
||||
[View Binaries](https://jenkins.thebrokenrail.com/job/minecraft-pi-docker/job/master/lastSuccessfulBuild/artifact/out/)
|
||||
<p align="center">
|
||||
<a href="https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases/latest"><img height="80" alt="Download as an AppImage" src="https://docs.appimage.org/_images/download-appimage-banner.svg" /></a>
|
||||
<a href="https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn"><img height="80" alt="Download on Flathub" src="https://flathub.org/assets/badges/flathub-badge-en.svg" /></a>
|
||||
<a href="https://github.com/Botspot/pi-apps"><img height="80" alt="Get it from Pi-Apps" src="https://github.com/Botspot/pi-apps/blob/master/icons/badge.png?raw=true" /></a>
|
||||
</p>
|
||||
|
||||
## Modding
|
||||
[View Modding](MODDING.md)
|
||||
# Minecraft: Pi Edition: Reborn [![Gitea Actions](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/actions/workflows/build.yml/badge.svg)](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/actions)
|
||||
Minecraft: Pi Edition Modding Project
|
||||
|
||||
Get started [here](docs/GETTING_STARTED.md)!
|
||||
|
||||
## Documentation
|
||||
[View Documentation](docs/README.md)
|
||||
|
1
archives
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 5baa6b1948aeebb5e13af31ff62dc97f00a3b71e
|
@ -1,15 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
git clone --depth 1 https://git.code.sf.net/p/libpng/code libpng -b libpng12
|
||||
|
||||
cd libpng
|
||||
|
||||
./configure --host arm-linux-gnueabihf --prefix /usr/arm-linux-gnueabihf
|
||||
|
||||
make -j$(nproc)
|
||||
make install
|
||||
|
||||
cd ../
|
||||
rm -rf libpng
|
@ -1,19 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd mods
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain.cmake ..
|
||||
make -j$(nproc)
|
||||
|
||||
cd ../../
|
||||
|
||||
mkdir minecraft-pi/mods
|
||||
cp mods/build/lib*.so minecraft-pi/mods
|
||||
|
||||
cp mods/build/core/lib*.so minecraft-pi
|
||||
cp mods/build/core/launcher minecraft-pi
|
@ -1,8 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
URL="https://www.minecraft.net/content/dam/minecraft/edition-pi/minecraft-pi-0.1.1.tar.gz"
|
||||
|
||||
mkdir minecraft-pi
|
||||
curl "${URL}" | tar -xz --strip-components 1 -C minecraft-pi
|
60
cmake/cpack/appimage.cmake
Normal file
@ -0,0 +1,60 @@
|
||||
# Download AppImage Runtime
|
||||
set(RUNTIME_ARCH "unknown")
|
||||
if(CPACK_MCPI_ARCH STREQUAL "armhf")
|
||||
set(RUNTIME_ARCH "armhf")
|
||||
elseif(CPACK_MCPI_ARCH STREQUAL "arm64")
|
||||
set(RUNTIME_ARCH "aarch64")
|
||||
elseif(CPACK_MCPI_ARCH STREQUAL "amd64")
|
||||
set(RUNTIME_ARCH "x86_64")
|
||||
endif()
|
||||
set(RUNTIME "${CPACK_TOPLEVEL_DIRECTORY}/runtime")
|
||||
file(DOWNLOAD
|
||||
"https://github.com/AppImage/type2-runtime/releases/download/continuous/runtime-${RUNTIME_ARCH}"
|
||||
"${RUNTIME}"
|
||||
STATUS DOWNLOAD_STATUS
|
||||
)
|
||||
list(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
||||
list(GET DOWNLOAD_STATUS 1 ERROR_MESSAGE)
|
||||
if(NOT STATUS_CODE EQUAL 0)
|
||||
message(FATAL_ERROR "Unable To Download AppImage Runtime: ${ERROR_MESSAGE}")
|
||||
else()
|
||||
message(STATUS "Downloaded AppImage Runtime: ${RUNTIME}")
|
||||
endif()
|
||||
|
||||
# Package
|
||||
set(APPIMAGE_ARCH "unknown")
|
||||
if(CPACK_MCPI_ARCH STREQUAL "armhf")
|
||||
set(APPIMAGE_ARCH "arm")
|
||||
elseif(CPACK_MCPI_ARCH STREQUAL "arm64")
|
||||
set(APPIMAGE_ARCH "arm_aarch64")
|
||||
elseif(CPACK_MCPI_ARCH STREQUAL "amd64")
|
||||
set(APPIMAGE_ARCH "x86_64")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}" "-E" "env"
|
||||
"ARCH=${APPIMAGE_ARCH}"
|
||||
"VERSION=${CPACK_MCPI_VERSION}"
|
||||
"appimagetool"
|
||||
"--updateinformation" "zsync|${CPACK_MCPI_REPO}/releases/download/latest/${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}"
|
||||
"--runtime-file" "${RUNTIME}"
|
||||
"--comp" "zstd"
|
||||
"${CPACK_TEMPORARY_DIRECTORY}"
|
||||
"${CPACK_PACKAGE_FILE_NAME}${CPACK_MCPI_APPIMAGE_EXT}"
|
||||
WORKING_DIRECTORY "${CPACK_PACKAGE_DIRECTORY}"
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
|
||||
# Rename ZSync File
|
||||
file(RENAME "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}" "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}")
|
||||
|
||||
# Summary Message
|
||||
function(check_file name)
|
||||
if(EXISTS "${CPACK_PACKAGE_DIRECTORY}/${name}")
|
||||
message(STATUS "Generated: ${name}")
|
||||
else()
|
||||
message(FATAL_ERROR "Missing File: ${name}")
|
||||
endif()
|
||||
endfunction()
|
||||
check_file("${CPACK_PACKAGE_FILE_NAME}${CPACK_MCPI_APPIMAGE_EXT}")
|
||||
check_file("${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}")
|
32
cmake/cpack/packaging.cmake
Normal file
@ -0,0 +1,32 @@
|
||||
# CPack
|
||||
set(CPACK_PACKAGE_NAME "${MCPI_APP_NAME}")
|
||||
set(CPACK_PACKAGE_VENDOR "${MCPI_AUTHOR} & Mojang AB")
|
||||
set(CPACK_VERBATIM_VARIABLES TRUE)
|
||||
set(CPACK_MONOLITHIC_INSTALL TRUE)
|
||||
get_package_file_name(CPACK_PACKAGE_FILE_NAME "${MCPI_VERSION}")
|
||||
get_package_file_name(CPACK_PACKAGE_FILE_NAME_ZSYNC "latest")
|
||||
|
||||
# Version
|
||||
string(REPLACE "." ";" VERSION_LIST "${MCPI_VERSION}")
|
||||
list(GET VERSION_LIST 0 CPACK_PACKAGE_VERSION_MAJOR)
|
||||
list(GET VERSION_LIST 1 CPACK_PACKAGE_VERSION_MINOR)
|
||||
list(GET VERSION_LIST 2 CPACK_PACKAGE_VERSION_PATCH)
|
||||
|
||||
# AppImage
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
set(CPACK_GENERATOR "External")
|
||||
set(CPACK_EXTERNAL_ENABLE_STAGING TRUE)
|
||||
set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/appimage.cmake")
|
||||
# Pass Variable To CPack
|
||||
macro(pass_to_cpack var)
|
||||
set("CPACK_MCPI_${var}" "${MCPI_${var}}")
|
||||
endmacro()
|
||||
pass_to_cpack(VERSION)
|
||||
pass_to_cpack(ARCH)
|
||||
pass_to_cpack(REPO)
|
||||
pass_to_cpack(APPIMAGE_EXT)
|
||||
pass_to_cpack(APPIMAGE_ZSYNC_EXT)
|
||||
endif()
|
||||
|
||||
# Package
|
||||
include(CPack)
|
0
cmake/options/appimage.cmake
Normal file
27
cmake/options/core-options.cmake
Normal file
@ -0,0 +1,27 @@
|
||||
# Build Mode
|
||||
set(MCPI_BUILD_MODE "native" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code")
|
||||
set_property(CACHE MCPI_BUILD_MODE PROPERTY STRINGS "arm" "native")
|
||||
if(MCPI_BUILD_MODE STREQUAL "arm")
|
||||
set(BUILD_ARM_COMPONENTS TRUE)
|
||||
set(BUILD_NATIVE_COMPONENTS FALSE)
|
||||
elseif(MCPI_BUILD_MODE STREQUAL "native")
|
||||
set(BUILD_ARM_COMPONENTS FALSE)
|
||||
set(BUILD_NATIVE_COMPONENTS TRUE)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid Mode")
|
||||
endif()
|
||||
|
||||
# Specify Options
|
||||
set(MCPI_OPTIONS "")
|
||||
function(mcpi_option name description type default)
|
||||
set(full_name "MCPI_${name}")
|
||||
set("${full_name}" "${default}" CACHE "${type}" "${description}")
|
||||
list(APPEND MCPI_OPTIONS "-D${full_name}:${type}=${${full_name}}")
|
||||
set(MCPI_OPTIONS "${MCPI_OPTIONS}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Clear External CFLAGS When Building ARM Components
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
unset(ENV{CFLAGS})
|
||||
unset(ENV{CXXFLAGS})
|
||||
endif()
|
89
cmake/options/extra-options.cmake
Normal file
@ -0,0 +1,89 @@
|
||||
# Specify Options
|
||||
mcpi_option(OPEN_SOURCE_ONLY "Only Install Open-Source Code (Will Result In Broken Install)" BOOL FALSE)
|
||||
mcpi_option(IS_APPIMAGE_BUILD "AppImage Build" BOOL FALSE)
|
||||
mcpi_option(IS_FLATPAK_BUILD "Flatpak Build" BOOL FALSE)
|
||||
if(MCPI_IS_APPIMAGE_BUILD AND MCPI_IS_FLATPAK_BUILD)
|
||||
message(FATAL_ERROR "Invalid Build Configuration")
|
||||
endif()
|
||||
|
||||
# Prebuilt ARMHF Toolchain
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
set(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN FALSE)
|
||||
if(NOT IS_ARM_TARGETING)
|
||||
set(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN TRUE)
|
||||
endif()
|
||||
if(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/prebuilt-armhf-toolchain.cmake")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Media Layer
|
||||
set(DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE FALSE)
|
||||
if(BUILD_NATIVE_COMPONENTS AND NOT IS_ARM_TARGETING)
|
||||
set(DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE TRUE)
|
||||
endif()
|
||||
mcpi_option(USE_MEDIA_LAYER_TRAMPOLINE "Whether To Enable The Media Layer Trampoline" BOOL "${DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE}")
|
||||
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
|
||||
set(BUILD_MEDIA_LAYER_CORE "${BUILD_NATIVE_COMPONENTS}")
|
||||
else()
|
||||
set(BUILD_MEDIA_LAYER_CORE "${BUILD_ARM_COMPONENTS}")
|
||||
endif()
|
||||
|
||||
# App Information
|
||||
mcpi_option(APP_NAME "App Name" STRING "minecraft-pi-reborn")
|
||||
mcpi_option(APP_ID "App ID" STRING "com.thebrokenrail.MCPIReborn")
|
||||
mcpi_option(APP_TITLE "App Title" STRING "Minecraft: Pi Edition: Reborn")
|
||||
|
||||
# Skin Server
|
||||
mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data")
|
||||
|
||||
# Discord Invite URL
|
||||
mcpi_option(DISCORD_INVITE "Discord Invite URL" STRING "https://discord.gg/mcpi-revival-740287937727561779")
|
||||
|
||||
# Version
|
||||
set_property(
|
||||
DIRECTORY
|
||||
APPEND
|
||||
PROPERTY CMAKE_CONFIGURE_DEPENDS VERSION
|
||||
)
|
||||
file(STRINGS "${CMAKE_CURRENT_LIST_DIR}/../../VERSION" MCPI_VERSION)
|
||||
file(TIMESTAMP "${CMAKE_CURRENT_LIST_DIR}/../../VERSION" MCPI_VERSION_DATE "%Y-%m-%d" UTC)
|
||||
|
||||
# Author
|
||||
mcpi_option(AUTHOR "Author" STRING "TheBrokenRail")
|
||||
|
||||
# Homepage
|
||||
mcpi_option(REPO_HOST "Repository Host" STRING "https://gitea.thebrokenrail.com")
|
||||
mcpi_option(REPO_PATH "Repository Path" STRING "minecraft-pi-reborn/minecraft-pi-reborn")
|
||||
mcpi_option(REPO "Repository URL" STRING "${MCPI_REPO_HOST}/${MCPI_REPO_PATH}")
|
||||
|
||||
# Documentation URL
|
||||
mcpi_option(DOCS "Documentation URL" STRING "${MCPI_REPO}/src/tag/${MCPI_VERSION}/docs/")
|
||||
|
||||
# Packaging
|
||||
set(MCPI_ARCH "unknown")
|
||||
include(CheckSymbolExists)
|
||||
function(check_arch symbol name)
|
||||
set(CMAKE_REQUIRED_QUIET TRUE)
|
||||
check_symbol_exists("${symbol}" "" "IS_ARCH_${name}")
|
||||
unset(CMAKE_REQUIRED_QUIET)
|
||||
if("${IS_ARCH_${name}}")
|
||||
set(MCPI_ARCH "${name}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
check_arch("__arm__" "armhf")
|
||||
check_arch("__aarch64__" "arm64")
|
||||
check_arch("__x86_64__" "amd64")
|
||||
macro(get_package_file_name out version)
|
||||
set("${out}" "${MCPI_APP_NAME}-${version}-${MCPI_ARCH}")
|
||||
endmacro()
|
||||
|
||||
# AppImage
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
mcpi_option(APPIMAGE_EXT "AppImage Extension" STRING ".AppImage")
|
||||
mcpi_option(APPIMAGE_ZSYNC_EXT "AppImage Update Extension" STRING "${MCPI_APPIMAGE_EXT}.zsync")
|
||||
mcpi_option(APPIMAGE_JSON_URL "AppImage Update Checker URL" STRING "${MCPI_REPO_HOST}/api/v1/repos/${MCPI_REPO_PATH}/releases/latest")
|
||||
mcpi_option(APPIMAGE_VERSION_PLACEHOLDER "Version Placeholder In AppImage Download URL" STRING "%VERSION%")
|
||||
get_package_file_name(appimage_package_file_name "${MCPI_APPIMAGE_VERSION_PLACEHOLDER}")
|
||||
mcpi_option(APPIMAGE_DOWNLOAD_URL "AppImage Download URL" STRING "${MCPI_REPO}/releases/download/${MCPI_APPIMAGE_VERSION_PLACEHOLDER}/${appimage_package_file_name}${MCPI_APPIMAGE_EXT}")
|
||||
endif()
|
33
cmake/options/paths.cmake
Normal file
@ -0,0 +1,33 @@
|
||||
# Specify Installation Paths
|
||||
set(MCPI_INSTALL_DIR "lib/${MCPI_APP_NAME}")
|
||||
set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin")
|
||||
set(MCPI_LEGAL_DIR "${MCPI_INSTALL_DIR}/legal") # For Software Licenses
|
||||
set(MCPI_SDK_DIR "${MCPI_INSTALL_DIR}/sdk")
|
||||
set(MCPI_SDK_LIB_DIR "${MCPI_SDK_DIR}/lib")
|
||||
set(MCPI_SDK_INCLUDE_DIR "${MCPI_SDK_DIR}/include")
|
||||
|
||||
# Library Directory
|
||||
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
string(APPEND MCPI_LIB_DIR "/arm")
|
||||
elseif(BUILD_NATIVE_COMPONENTS)
|
||||
string(APPEND MCPI_LIB_DIR "/native")
|
||||
endif()
|
||||
|
||||
# Share Directory
|
||||
set(MCPI_SHARE_DIR "share")
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
string(PREPEND MCPI_SHARE_DIR "usr/")
|
||||
endif()
|
||||
|
||||
# Specify Default Installation Prefix
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(DEFAULT_PREFIX "/usr")
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
set(DEFAULT_PREFIX "/")
|
||||
elseif(MCPI_IS_FLATPAK_BUILD)
|
||||
set(DEFAULT_PREFIX "/app")
|
||||
endif()
|
||||
set(CMAKE_INSTALL_PREFIX "${DEFAULT_PREFIX}" CACHE PATH "Install Prefix" FORCE)
|
||||
set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT FALSE)
|
||||
endif()
|
88
cmake/options/prebuilt-armhf-toolchain.cmake
Normal file
@ -0,0 +1,88 @@
|
||||
# Target
|
||||
set(target "arm-none-linux-gnueabihf")
|
||||
|
||||
# Pick Archive
|
||||
set(toolchain_version "13.3.rel1")
|
||||
execute_process(COMMAND uname -m OUTPUT_VARIABLE arch OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(arch STREQUAL "x86_64")
|
||||
set(toolchain_file "arm-gnu-toolchain-${toolchain_version}-x86_64-${target}.tar.xz")
|
||||
elseif(arch STREQUAL "aarch64" OR arch STREQUAL "armv8b" OR arch STREQUAL "armv8l")
|
||||
set(toolchain_file "arm-gnu-toolchain-${toolchain_version}-aarch64-${target}.tar.xz")
|
||||
else()
|
||||
message(FATAL_ERROR "Unable To Download Prebuilt ARMHF Toolchain")
|
||||
endif()
|
||||
|
||||
# Download If Needed
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(prebuilt-armhf-toolchain
|
||||
URL "${CMAKE_CURRENT_LIST_DIR}/../../archives/${toolchain_file}"
|
||||
)
|
||||
FetchContent_MakeAvailable(prebuilt-armhf-toolchain)
|
||||
set(toolchain_dir "${prebuilt-armhf-toolchain_SOURCE_DIR}")
|
||||
|
||||
# Force Toolchain
|
||||
file(WRITE "${toolchain_dir}/toolchain.cmake"
|
||||
"set(CMAKE_C_COMPILER \"\${CMAKE_CURRENT_LIST_DIR}/bin/${target}-gcc\")\n"
|
||||
"set(CMAKE_CXX_COMPILER \"\${CMAKE_CURRENT_LIST_DIR}/bin/${target}-g++\")\n"
|
||||
"set(CMAKE_SYSTEM_NAME \"Linux\")\n"
|
||||
"set(CMAKE_SYSTEM_PROCESSOR \"arm\")\n"
|
||||
"set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\n"
|
||||
)
|
||||
force_set(MCPI_CMAKE_TOOLCHAIN_FILE "${toolchain_dir}/toolchain.cmake" FILEPATH)
|
||||
|
||||
# Build Sysroot
|
||||
set(sysroot_dir "${CMAKE_CURRENT_BINARY_DIR}/bundled-armhf-sysroot")
|
||||
set(sysroot_dir_debug "${sysroot_dir}/debug")
|
||||
set(sysroot_dir_release "${sysroot_dir}/release")
|
||||
if("${toolchain_dir}/bin/${target}-gcc" IS_NEWER_THAN "${sysroot_dir}")
|
||||
# Create Directory
|
||||
file(REMOVE_RECURSE "${sysroot_dir}")
|
||||
file(MAKE_DIRECTORY "${sysroot_dir_debug}")
|
||||
file(MAKE_DIRECTORY "${sysroot_dir_release}")
|
||||
|
||||
# Copy Files From Toolchain
|
||||
file(
|
||||
COPY "${toolchain_dir}/${target}/libc/"
|
||||
DESTINATION "${sysroot_dir_debug}"
|
||||
USE_SOURCE_PERMISSIONS
|
||||
FILES_MATCHING
|
||||
PATTERN "*.so*"
|
||||
)
|
||||
|
||||
# Delete Unneeded Files
|
||||
file(REMOVE_RECURSE "${sysroot_dir_debug}/usr/lib/audit")
|
||||
file(REMOVE_RECURSE "${sysroot_dir_debug}/usr/lib/gconv")
|
||||
|
||||
# Strip Files
|
||||
file(COPY "${sysroot_dir_debug}/." DESTINATION "${sysroot_dir_release}")
|
||||
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE "${sysroot_dir_release}/*")
|
||||
foreach(file IN LISTS files)
|
||||
execute_process(
|
||||
COMMAND "${toolchain_dir}/bin/${target}-strip" "${file}"
|
||||
RESULT_VARIABLE ret
|
||||
ERROR_QUIET
|
||||
)
|
||||
# Delete Invalid Files
|
||||
if(NOT ret EQUAL 0)
|
||||
file(REMOVE "${file}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Install Sysroot (Skipping Empty Directories)
|
||||
function(install_arm_sysroot_config config)
|
||||
set(dir "${sysroot_dir_${config}}")
|
||||
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE RELATIVE "${dir}" "${dir}/*")
|
||||
foreach(file IN LISTS files)
|
||||
cmake_path(GET file PARENT_PATH parent)
|
||||
install(
|
||||
PROGRAMS "${dir}/${file}"
|
||||
DESTINATION "${MCPI_INSTALL_DIR}/sysroot/${parent}"
|
||||
CONFIGURATIONS "${config}"
|
||||
)
|
||||
endforeach()
|
||||
endfunction()
|
||||
function(install_arm_sysroot)
|
||||
install_arm_sysroot_config(debug)
|
||||
install_arm_sysroot_config(release)
|
||||
endfunction()
|
@ -1,5 +0,0 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
7
cmake/toolchain/amd64-toolchain.cmake
Normal file
@ -0,0 +1,7 @@
|
||||
# Compile For x86_64
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake")
|
||||
# Use x86_64 Cross-Compiler
|
||||
setup_toolchain("x86_64-linux-gnu")
|
||||
# Details
|
||||
set(CMAKE_SYSTEM_NAME "Linux")
|
||||
set(CMAKE_SYSTEM_PROCESSOR "x86_64")
|
7
cmake/toolchain/arm64-toolchain.cmake
Normal file
@ -0,0 +1,7 @@
|
||||
# Compile For ARM64
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake")
|
||||
# Use ARM64 Cross-Compiler
|
||||
setup_toolchain("aarch64-linux-gnu")
|
||||
# Details
|
||||
set(CMAKE_SYSTEM_NAME "Linux")
|
||||
set(CMAKE_SYSTEM_PROCESSOR "aarch64")
|
7
cmake/toolchain/armhf-toolchain.cmake
Normal file
@ -0,0 +1,7 @@
|
||||
# Compile For ARM
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake")
|
||||
# Use ARM Cross-Compiler
|
||||
setup_toolchain("arm-linux-gnueabihf")
|
||||
# Details
|
||||
set(CMAKE_SYSTEM_NAME "Linux")
|
||||
set(CMAKE_SYSTEM_PROCESSOR "arm")
|
37
cmake/toolchain/base-toolchain.cmake
Normal file
@ -0,0 +1,37 @@
|
||||
# Setup Toolchain
|
||||
macro(setup_toolchain target)
|
||||
# Target Variants
|
||||
set(target_variants "${target}")
|
||||
macro(add_target_variant value)
|
||||
string(REPLACE "-linux" "-${value}-linux" target_variant "${target}")
|
||||
list(APPEND target_variants "${target_variant}")
|
||||
endmacro()
|
||||
add_target_variant(unknown)
|
||||
add_target_variant(none)
|
||||
add_target_variant(pc)
|
||||
|
||||
# Find Compiler
|
||||
macro(find_compiler output name)
|
||||
set(possible_names "")
|
||||
foreach(possible_target IN LISTS target_variants)
|
||||
list(APPEND possible_names "${possible_target}-${name}")
|
||||
endforeach()
|
||||
find_program(
|
||||
"${output}"
|
||||
NAMES ${possible_names}
|
||||
NO_CACHE
|
||||
)
|
||||
if("${${output}}" STREQUAL "${output}-NOTFOUND")
|
||||
message(FATAL_ERROR "Unable To Find ${name}")
|
||||
endif()
|
||||
endmacro()
|
||||
find_compiler(CMAKE_C_COMPILER "gcc")
|
||||
find_compiler(CMAKE_CXX_COMPILER "g++")
|
||||
|
||||
# Extra
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
# Custom Search Paths
|
||||
set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}" "/usr")
|
||||
# pkg-config
|
||||
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/${target}/pkgconfig:/usr/${target}/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig")
|
||||
endmacro()
|
12
cmake/util/embed-resource.cmake
Normal file
@ -0,0 +1,12 @@
|
||||
# Read Hex Data
|
||||
file(READ "${EMBED_IN}" data HEX)
|
||||
# Convert Hex Data For C Compatibility
|
||||
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," data "${data}")
|
||||
# Get C Name
|
||||
cmake_path(GET EMBED_OUT STEM name)
|
||||
# Write Data
|
||||
file(WRITE "${EMBED_OUT}"
|
||||
"#include <stddef.h>\n"
|
||||
"const unsigned char ${name}[] = {${data}};\n"
|
||||
"const size_t ${name}_len = sizeof (${name});\n"
|
||||
)
|
91
cmake/util/util.cmake
Normal file
@ -0,0 +1,91 @@
|
||||
# Symlink Function
|
||||
function(install_symlink target link)
|
||||
cmake_path(GET link PARENT_PATH parent)
|
||||
if(parent STREQUAL "")
|
||||
set(parent ".")
|
||||
endif()
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/symlink/${parent}")
|
||||
file(CREATE_LINK "${target}" "${CMAKE_BINARY_DIR}/symlink/${link}" SYMBOLIC)
|
||||
install(FILES "${CMAKE_BINARY_DIR}/symlink/${link}" DESTINATION "${parent}")
|
||||
endfunction()
|
||||
|
||||
# Embed Resources
|
||||
set(util_list_dir "${CMAKE_CURRENT_LIST_DIR}")
|
||||
function(embed_resource target file)
|
||||
# Get C Name
|
||||
cmake_path(GET file FILENAME name)
|
||||
string(MAKE_C_IDENTIFIER "${name}" name)
|
||||
# Add Command
|
||||
set(in "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
|
||||
set(out "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
|
||||
set(script "${util_list_dir}/embed-resource.cmake")
|
||||
add_custom_command(OUTPUT "${out}"
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
ARGS "-DEMBED_IN=${in}" "-DEMBED_OUT=${out}" "-P" "${script}"
|
||||
DEPENDS "${in}" "${script}"
|
||||
VERBATIM
|
||||
)
|
||||
# Add To Target
|
||||
target_sources("${target}" PRIVATE "${out}")
|
||||
endfunction()
|
||||
|
||||
# Nicer Output
|
||||
function(message log_level)
|
||||
if((NOT MESSAGE_QUIET) OR (NOT (log_level STREQUAL "STATUS" OR log_level MATCHES "^CHECK_")))
|
||||
_message("${log_level}" ${ARGN})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Exporting Targets And Headers
|
||||
macro(_get_sdk_header_dir target)
|
||||
set(sdk_dir "${MCPI_SDK_INCLUDE_DIR}/${target}")
|
||||
endmacro()
|
||||
function(setup_header_dirs target)
|
||||
_get_sdk_header_dir("${target}")
|
||||
# Get Header Type
|
||||
set(header_type "PUBLIC")
|
||||
get_target_property(type "${target}" TYPE)
|
||||
if ("${type}" STREQUAL "INTERFACE_LIBRARY")
|
||||
set(header_type "INTERFACE")
|
||||
endif()
|
||||
# Loop
|
||||
foreach(dir IN LISTS ARGN)
|
||||
# Add To Target
|
||||
target_include_directories("${target}" "${header_type}" "$<BUILD_INTERFACE:${dir}>")
|
||||
# Add To SDK
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(
|
||||
DIRECTORY "${dir}/"
|
||||
DESTINATION "${sdk_dir}"
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
# Add SDK Headers To Target
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
target_include_directories("${target}" "${header_type}" "$<INSTALL_INTERFACE:${sdk_dir}>")
|
||||
endif()
|
||||
endfunction()
|
||||
function(setup_library target should_install should_export)
|
||||
# Install
|
||||
if(should_install)
|
||||
install(TARGETS "${target}" DESTINATION "${MCPI_LIB_DIR}")
|
||||
endif()
|
||||
# SDK
|
||||
if(should_export AND BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS "${target}" EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Force Set Configuration Variable
|
||||
function(force_set name value type)
|
||||
set("${name}" "${value}" CACHE "${type}" "" FORCE)
|
||||
mark_as_advanced(FORCE "${name}")
|
||||
endfunction()
|
||||
|
||||
# Make Directory
|
||||
function(set_and_mkdir name dir)
|
||||
set("${name}" "${dir}" PARENT_SCOPE)
|
||||
file(MAKE_DIRECTORY "${dir}")
|
||||
endfunction()
|
@ -1,9 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.1.0)
|
||||
|
||||
project(core)
|
||||
|
||||
add_compile_options(-Wall -Wextra -Werror)
|
||||
|
||||
add_library(bcm_host SHARED src/bcm_host.c)
|
||||
|
||||
add_executable(launcher src/launcher.c)
|
@ -1,39 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
void bcm_host_init(void) {
|
||||
}
|
||||
|
||||
void bcm_host_deinit(void) {
|
||||
}
|
||||
|
||||
int32_t graphics_get_display_size(__attribute__((unused)) const uint16_t display_number, __attribute__((unused)) uint32_t *width, __attribute__((unused)) uint32_t *height) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned bcm_host_get_peripheral_address(void) {
|
||||
return 0x20000000;
|
||||
}
|
||||
|
||||
unsigned bcm_host_get_peripheral_size(void) {
|
||||
return 0x01000000;
|
||||
}
|
||||
|
||||
unsigned bcm_host_get_sdram_address(void) {
|
||||
return 0x40000000;
|
||||
}
|
||||
|
||||
uint32_t vc_dispmanx_display_open(__attribute__((unused)) uint32_t device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t vc_dispmanx_element_add(__attribute__((unused)) uint32_t update, __attribute__((unused)) uint32_t display, __attribute__((unused)) int32_t layer, __attribute__((unused)) const void *dest_rect, __attribute__((unused)) uint32_t src, __attribute__((unused)) const void *src_rect, __attribute__((unused)) uint32_t protection, __attribute__((unused)) void *alpha, __attribute__((unused)) void *clamp, __attribute__((unused)) uint32_t transform) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t vc_dispmanx_update_start(__attribute__((unused)) int32_t priority) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vc_dispmanx_update_submit_sync(__attribute__((unused)) uint32_t update) {
|
||||
return 0;
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
static int starts_with(const char *s, const char *t) {
|
||||
return strncmp(s, t, strlen(t)) == 0;
|
||||
}
|
||||
|
||||
static int ends_with(const char *s, const char *t) {
|
||||
size_t slen = strlen(s);
|
||||
size_t tlen = strlen(t);
|
||||
if (tlen > slen) return 1;
|
||||
return strcmp(s + slen - tlen, t) == 0;
|
||||
}
|
||||
|
||||
static void trim(char *value) {
|
||||
// Remove Trailing Colon
|
||||
int length = strlen(value);
|
||||
if (value[length - 1] == ':') {
|
||||
value[length - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static void set_and_print_env(char *name, char *value) {
|
||||
// Set Variable With Not Trailing Colon
|
||||
trim(value);
|
||||
|
||||
fprintf(stderr, "Set %s = %s\n", name, value);
|
||||
setenv(name, value, 1);
|
||||
}
|
||||
|
||||
static char *get_env_safe(const char *name) {
|
||||
// Get Variable Or Blank String If Not Set
|
||||
char *ret = getenv(name);
|
||||
return ret != NULL ? ret : "";
|
||||
}
|
||||
|
||||
static void load(char **ld_path, char **ld_preload, char *folder) {
|
||||
int folder_name_length = strlen(folder);
|
||||
while (1) {
|
||||
DIR *dp = opendir(folder);
|
||||
if (dp != NULL) {
|
||||
struct dirent *entry = NULL;
|
||||
errno = 0;
|
||||
while (1) {
|
||||
entry = readdir(dp);
|
||||
if (entry != NULL) {
|
||||
// Check If File Is A Shared Library
|
||||
if (entry->d_type == DT_REG && starts_with(entry->d_name, "lib") && ends_with(entry->d_name, ".so")) {
|
||||
int name_length = strlen(entry->d_name);
|
||||
int total_length = folder_name_length + name_length;
|
||||
char name[total_length + 1];
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
name[total_length] = '\0';
|
||||
|
||||
// Add To LD_PRELOAD
|
||||
asprintf(ld_preload, "%s:%s", name, *ld_preload);
|
||||
}
|
||||
} else if (errno != 0) {
|
||||
// Error Reading Contents Of Folder
|
||||
fprintf(stderr, "Error Reading Directory: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
|
||||
// Add To LD_LIBRARY_PATH
|
||||
asprintf(ld_path, "%s:%s", *ld_path, folder);
|
||||
|
||||
return;
|
||||
} else if (errno == ENOENT) {
|
||||
// Folder Doesn't Exists, Attempt Creation
|
||||
char *cmd = NULL;
|
||||
asprintf(&cmd, "mkdir -p %s", folder);
|
||||
int ret = system(cmd);
|
||||
if (ret != 0) {
|
||||
exit(ret);
|
||||
}
|
||||
} else {
|
||||
// Unable To Open Folder
|
||||
fprintf(stderr, "Error Opening Directory: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(__attribute__((unused)) int argc, char *argv[]) {
|
||||
fprintf(stderr, "Configuring Game...\n");
|
||||
|
||||
// Create Screenshots Folder
|
||||
char *screenshots_cmd = NULL;
|
||||
asprintf(&screenshots_cmd, "mkdir -p %s/.minecraft/screenshots", getenv("HOME"));
|
||||
system(screenshots_cmd);
|
||||
free(screenshots_cmd);
|
||||
|
||||
char *ld_path = NULL;
|
||||
|
||||
// Start Configuring LD_LIBRARY_PATH
|
||||
char *cwd = getcwd(NULL, 0);
|
||||
asprintf(&ld_path, "%s:/usr/arm-linux-gnueabihf/lib", cwd);
|
||||
free(cwd);
|
||||
|
||||
// Start Configuring LD_PRELOAD
|
||||
char *ld_preload = NULL;
|
||||
asprintf(&ld_preload, "%s", get_env_safe("LD_PRELOAD"));
|
||||
|
||||
// Load Mods From ./mods
|
||||
load(&ld_path, &ld_preload, "./mods/");
|
||||
|
||||
// Loads Mods From ~/.minecraft/mods
|
||||
char *home_mods = NULL;
|
||||
asprintf(&home_mods, "%s/.minecraft/mods/", getenv("HOME"));
|
||||
load(&ld_path, &ld_preload, home_mods);
|
||||
free(home_mods);
|
||||
|
||||
// Add Existing LD_LIBRARY_PATH
|
||||
asprintf(&ld_path, "%s:%s", ld_path, get_env_safe("LD_LIBRARY_PATH"));
|
||||
|
||||
// Set LD_LIBRARY_PATH
|
||||
set_and_print_env("LD_LIBRARY_PATH", ld_path);
|
||||
free(ld_path);
|
||||
|
||||
// Set LD_PRELOAD
|
||||
set_and_print_env("LD_PRELOAD", ld_preload);
|
||||
free(ld_preload);
|
||||
|
||||
// Start Game
|
||||
fprintf(stderr, "Starting Game...\n");
|
||||
return execve("./minecraft-pi", argv, environ);
|
||||
}
|
7
debian/DEBIAN/control
vendored
@ -1,7 +0,0 @@
|
||||
Package: minecraft-pi
|
||||
Version: 1.0.0
|
||||
Maintainer: TheBrokenRail <connor24nolan@live.com>
|
||||
Description: Fun with Blocks
|
||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||
Architecture: amd64
|
||||
Depends: docker.io, docker-compose, virgl-server, zenity, policykit-1, adduser, login
|
7
debian/DEBIAN/postinst
vendored
@ -1,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
||||
|
||||
MCPI_FEATURES='' docker-compose -f /usr/share/minecraft-pi/docker-compose.yml pull
|
35
debian/usr/bin/minecraft-pi
vendored
@ -1,35 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
# Ensure Features Are Selected
|
||||
if [ -z "${MCPI_SUBSHELL}" ]; then
|
||||
MCPI_FEATURES="$(zenity --class 'Minecraft - Pi edition' --list --checklist --column 'Enabled' --column 'Feature' TRUE 'Touch GUI' FALSE 'Survival Mode' TRUE 'Fix Bow & Arrow' TRUE 'Fix Attacking' TRUE 'Mob Spawning' TRUE 'Fancy Graphics' TRUE 'Disable Autojump By Default' TRUE 'Fix Sign Placement' TRUE 'Show Block Outlines')"
|
||||
MCPI_USERNAME="$(zenity --class 'Minecraft - Pi edition' --entry --text 'Minecraft Username:' --entry-text 'StevePi')"
|
||||
fi
|
||||
export MCPI_FEATURES
|
||||
export MCPI_USERNAME
|
||||
|
||||
# Start VirGL
|
||||
virgl_test_server &
|
||||
VIRGL_PID="$!"
|
||||
|
||||
# Ensure Groups Are Correct
|
||||
if [ -z "${MCPI_SUBSHELL}" ]; then
|
||||
if ! id -Gn "$(whoami)" | grep '\bdocker\b' > /dev/null; then
|
||||
pkexec adduser "$(whoami)" docker
|
||||
fi
|
||||
exec sg docker "env MCPI_SUBSHELL=1 \"$(realpath -e "$0")\""
|
||||
fi
|
||||
|
||||
# Allow X11 Connections From Root
|
||||
xhost local:root
|
||||
|
||||
# Launch Minecraft
|
||||
DOCKER_COMPOSE="docker-compose -f /usr/share/minecraft-pi/docker-compose.yml"
|
||||
${DOCKER_COMPOSE} pull | zenity --class 'Minecraft - Pi edition' --progress --pulsate --no-cancel --auto-close --text 'Updating Minecraft...'
|
||||
${DOCKER_COMPOSE} up
|
||||
${DOCKER_COMPOSE} down
|
||||
|
||||
# Kill VirGL
|
||||
kill "${VIRGL_PID}"
|
@ -1,10 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=Minecraft: Pi Edition
|
||||
Comment=Fun with Blocks
|
||||
Icon=/usr/share/pixmaps/minecraft-pi.png
|
||||
StartupNotify=false
|
||||
StartupWMClass=Minecraft - Pi edition
|
||||
Exec=/usr/bin/minecraft-pi
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Application;Game;
|
13
debian/usr/share/minecraft-pi/docker-compose.yml
vendored
@ -1,13 +0,0 @@
|
||||
version: '3.7'
|
||||
services:
|
||||
minecraft-pi:
|
||||
image: thebrokenrail/minecraft-pi
|
||||
network_mode: 'host'
|
||||
volumes:
|
||||
- '/tmp/.X11-unix:/tmp/.X11-unix'
|
||||
- '/tmp/.virgl_test:/tmp/.virgl_test'
|
||||
- '~/.minecraft-pi:/root/.minecraft'
|
||||
environment:
|
||||
- 'DISPLAY=unix${DISPLAY}'
|
||||
- 'MCPI_FEATURES=${MCPI_FEATURES}'
|
||||
- 'MCPI_USERNAME=${MCPI_USERNAME}'
|
BIN
debian/usr/share/pixmaps/minecraft-pi.png
vendored
Before Width: | Height: | Size: 100 KiB |
30
dependencies/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
project(dependencies)
|
||||
|
||||
# stb_image
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
add_subdirectory(stb_image)
|
||||
endif()
|
||||
# Minecraft: Pi Edition
|
||||
if(BUILD_ARM_COMPONENTS AND NOT MCPI_OPEN_SOURCE_ONLY)
|
||||
add_subdirectory(minecraft-pi)
|
||||
endif()
|
||||
# LIEF
|
||||
if(BUILD_NATIVE_COMPONENTS OR BUILD_MEDIA_LAYER_CORE)
|
||||
add_subdirectory(LIEF)
|
||||
endif()
|
||||
# Extra Runtime
|
||||
add_subdirectory(runtime)
|
||||
# GLFW
|
||||
if(BUILD_NATIVE_COMPONENTS OR BUILD_MEDIA_LAYER_CORE)
|
||||
add_subdirectory(glfw)
|
||||
endif()
|
||||
# ImGui
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
add_subdirectory(imgui)
|
||||
endif()
|
||||
# UTF8-CPP
|
||||
add_subdirectory(utf8cpp)
|
||||
# Symbol Processor
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
add_subdirectory(symbol-processor)
|
||||
endif()
|
43
dependencies/LIEF/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
project(LIEF)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w -Wno-psabi)
|
||||
|
||||
## LIEF
|
||||
|
||||
# Options
|
||||
force_set(LIEF_C_API FALSE BOOL)
|
||||
force_set(LIEF_EXAMPLES FALSE BOOL)
|
||||
force_set(LIEF_PYTHON_API FALSE BOOL)
|
||||
force_set(LIEF_TESTS FALSE BOOL)
|
||||
force_set(LIEF_USE_CCACHE FALSE BOOL)
|
||||
force_set(LIEF_LOGGING FALSE BOOL)
|
||||
force_set(LIEF_LOGGING_DEBUG FALSE BOOL)
|
||||
force_set(LIEF_ENABLE_JSON FALSE BOOL)
|
||||
force_set(LIEF_ELF TRUE BOOL)
|
||||
force_set(LIEF_PE FALSE BOOL)
|
||||
force_set(LIEF_MACHO FALSE BOOL)
|
||||
force_set(LIEF_DEX FALSE BOOL)
|
||||
force_set(LIEF_ART FALSE BOOL)
|
||||
force_set(LIEF_OAT FALSE BOOL)
|
||||
force_set(LIEF_VDEX FALSE BOOL)
|
||||
|
||||
# Download
|
||||
set(MESSAGE_QUIET TRUE)
|
||||
add_subdirectory(src EXCLUDE_FROM_ALL SYSTEM)
|
||||
unset(MESSAGE_QUIET)
|
||||
|
||||
# Install
|
||||
setup_library(LIB_LIEF TRUE TRUE)
|
||||
|
||||
# License
|
||||
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/LIEF")
|
||||
|
||||
# Fix Flags
|
||||
function(fix_flags property)
|
||||
get_target_property(flags LIB_LIEF "${property}")
|
||||
list(REMOVE_ITEM flags "_GLIBCXX_USE_CXX11_ABI=1")
|
||||
set_target_properties(LIB_LIEF PROPERTIES "${property}" "${flags}")
|
||||
endfunction()
|
||||
fix_flags(COMPILE_DEFINITIONS)
|
||||
fix_flags(INTERFACE_COMPILE_DEFINITIONS)
|
1
dependencies/LIEF/src
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit d4900dab6a9eea864fb14ed1ff7ea5b9f8678e04
|
26
dependencies/glfw/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
project(glfw)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w)
|
||||
|
||||
## GLFW
|
||||
|
||||
# Download
|
||||
force_set(GLFW_BUILD_EXAMPLES FALSE BOOL)
|
||||
force_set(GLFW_BUILD_TESTS FALSE BOOL)
|
||||
force_set(GLFW_BUILD_DOCS FALSE BOOL)
|
||||
force_set(GLFW_INSTALL FALSE BOOL)
|
||||
force_set(GLFW_BUILD_WIN32 FALSE BOOL)
|
||||
force_set(GLFW_BUILD_COCOA FALSE BOOL)
|
||||
force_set(GLFW_BUILD_X11 TRUE BOOL)
|
||||
force_set(GLFW_BUILD_WAYLAND TRUE BOOL)
|
||||
force_set(GLFW_LIBRARY_TYPE "SHARED" STRING)
|
||||
set(MESSAGE_QUIET TRUE)
|
||||
add_subdirectory(src EXCLUDE_FROM_ALL SYSTEM)
|
||||
unset(MESSAGE_QUIET)
|
||||
|
||||
# Install
|
||||
setup_library(glfw TRUE TRUE)
|
||||
|
||||
# License
|
||||
install(FILES src/LICENSE.md DESTINATION "${MCPI_LEGAL_DIR}/GLFW")
|
1
dependencies/glfw/src
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 21fea01161e0d6b70c0c5c1f52dc8e7a7df14a50
|
52
dependencies/imgui/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
project(imgui)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w)
|
||||
|
||||
## ImGui
|
||||
|
||||
# Build
|
||||
add_library(imgui SHARED
|
||||
src/imgui.cpp
|
||||
src/imgui_draw.cpp
|
||||
src/imgui_tables.cpp
|
||||
src/imgui_widgets.cpp
|
||||
src/misc/cpp/imgui_stdlib.cpp
|
||||
src/backends/imgui_impl_glfw.cpp
|
||||
src/backends/imgui_impl_opengl2.cpp
|
||||
)
|
||||
setup_header_dirs(imgui
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/backends"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/misc/cpp"
|
||||
)
|
||||
|
||||
# OpenGL
|
||||
add_subdirectory(glad)
|
||||
target_link_libraries(imgui PUBLIC glfw glad)
|
||||
|
||||
# Fonts
|
||||
embed_resource(imgui src/misc/fonts/Roboto-Medium.ttf)
|
||||
embed_resource(imgui src/misc/fonts/Cousine-Regular.ttf)
|
||||
|
||||
# Configure
|
||||
target_compile_definitions(imgui PUBLIC
|
||||
IMGUI_DISABLE_DEMO_WINDOWS
|
||||
IMGUI_DISABLE_DEBUG_TOOLS
|
||||
IMGUI_DISABLE_DEFAULT_FONT
|
||||
IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
)
|
||||
|
||||
# Patch
|
||||
execute_process(
|
||||
COMMAND "patch" "-p1" "--forward" "--reject-file=-"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/fix-hidpi.patch"
|
||||
OUTPUT_QUIET
|
||||
)
|
||||
|
||||
# Install
|
||||
setup_library(imgui TRUE FALSE)
|
||||
|
||||
# License
|
||||
install(FILES src/LICENSE.txt src/docs/FONTS.md DESTINATION "${MCPI_LEGAL_DIR}/ImGui")
|
55
dependencies/imgui/fix-hidpi.patch
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
--- a/backends/imgui_impl_glfw.cpp
|
||||
+++ b/backends/imgui_impl_glfw.cpp
|
||||
@@ -422,6 +422,21 @@ void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
|
||||
io.AddFocusEvent(focused != 0);
|
||||
}
|
||||
|
||||
+static void ImGui_ImplGlfw_ScaleMousePos(GLFWwindow* window, double &x, double &y) {
|
||||
+ // Get Window Size
|
||||
+ int window_width, window_height;
|
||||
+ glfwGetWindowSize(window, &window_width, &window_height);
|
||||
+ if (window_width <= 0 || window_height <= 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Get Framebuffer Size
|
||||
+ int framebuffer_width, framebuffer_height;
|
||||
+ glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
|
||||
+ // Multiply
|
||||
+ x *= double(framebuffer_width) / double(window_width);
|
||||
+ y *= double(framebuffer_height) / double(window_height);
|
||||
+}
|
||||
+
|
||||
void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
@@ -429,6 +444,7 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
||||
bd->PrevUserCallbackCursorPos(window, x, y);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
+ ImGui_ImplGlfw_ScaleMousePos(window, x, y);
|
||||
io.AddMousePosEvent((float)x, (float)y);
|
||||
bd->LastValidMousePos = ImVec2((float)x, (float)y);
|
||||
}
|
||||
@@ -738,6 +754,7 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
{
|
||||
double mouse_x, mouse_y;
|
||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||
+ ImGui_ImplGlfw_ScaleMousePos(window, mouse_x, mouse_y);
|
||||
bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
|
||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||
}
|
||||
@@ -831,13 +848,9 @@ void ImGui_ImplGlfw_NewFrame()
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?");
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
- int w, h;
|
||||
int display_w, display_h;
|
||||
- glfwGetWindowSize(bd->Window, &w, &h);
|
||||
glfwGetFramebufferSize(bd->Window, &display_w, &display_h);
|
||||
- io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
- if (w > 0 && h > 0)
|
||||
- io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);
|
||||
+ io.DisplaySize = ImVec2((float)display_w, (float)display_h);
|
||||
|
||||
// Setup time step
|
||||
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
|
49
dependencies/imgui/glad/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
project(imgui-glad)
|
||||
|
||||
# Directories
|
||||
set_and_mkdir(GLAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/glad")
|
||||
set_and_mkdir(GLAD_SRC_DIR "${GLAD_DIR}/src")
|
||||
set_and_mkdir(GLAD_INCLUDE_DIR "${GLAD_DIR}/include")
|
||||
|
||||
# Files
|
||||
set(GLAD_SOURCES
|
||||
"${GLAD_INCLUDE_DIR}/KHR/khrplatform.h"
|
||||
"${GLAD_INCLUDE_DIR}/glad/glad.h"
|
||||
"${GLAD_SRC_DIR}/glad.c"
|
||||
)
|
||||
|
||||
# Find Python
|
||||
find_package(Python REQUIRED QUIET)
|
||||
|
||||
# Generate
|
||||
add_custom_command(
|
||||
OUTPUT ${GLAD_SOURCES}
|
||||
COMMAND "${Python_EXECUTABLE}"
|
||||
ARGS "-m" "glad"
|
||||
"--out" "${GLAD_DIR}"
|
||||
"--api" "gl=1.1"
|
||||
"--generator" "c"
|
||||
"--reproducible"
|
||||
"--quiet"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build
|
||||
add_library(glad SHARED ${GLAD_SOURCES})
|
||||
target_compile_definitions(glad
|
||||
PUBLIC GLAD_GLAPI_EXPORT
|
||||
PRIVATE GLAD_GLAPI_EXPORT_BUILD
|
||||
)
|
||||
|
||||
# Link
|
||||
target_link_libraries(glad PRIVATE dl)
|
||||
|
||||
# Headers
|
||||
setup_header_dirs(glad
|
||||
"${GLAD_INCLUDE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
)
|
||||
|
||||
# Install
|
||||
setup_library(glad TRUE FALSE)
|
2
dependencies/imgui/glad/include/GL/gl.h
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
#include <glad/glad.h>
|
1
dependencies/imgui/glad/src
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit e86f90457371c6233053bacf0d6f486a51ddcd67
|
1
dependencies/imgui/src
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 6982ce43f5b143c5dce5fab0ce07dd4867b705ae
|
20
dependencies/minecraft-pi/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
project(minecraft-pi)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
## Minecraft: Pi Edition
|
||||
|
||||
# Download
|
||||
FetchContent_Declare(minecraft-pi
|
||||
URL "${CMAKE_CURRENT_SOURCE_DIR}/minecraft-pi-0.1.1.tar.gz"
|
||||
)
|
||||
FetchContent_MakeAvailable(minecraft-pi)
|
||||
|
||||
# Install
|
||||
install(
|
||||
DIRECTORY "${minecraft-pi_SOURCE_DIR}/"
|
||||
DESTINATION "${MCPI_INSTALL_DIR}/game"
|
||||
USE_SOURCE_PERMISSIONS
|
||||
REGEX "api" EXCLUDE
|
||||
)
|
||||
install_symlink("game/minecraft-pi" "${MCPI_INSTALL_DIR}/minecraft-pi")
|
BIN
dependencies/minecraft-pi/minecraft-pi-0.1.1.tar.gz
vendored
Normal file
12
dependencies/runtime/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
project(runtime)
|
||||
|
||||
## Extra Runtime
|
||||
|
||||
# Build
|
||||
add_subdirectory(src)
|
||||
|
||||
# RPath
|
||||
if(TARGET runtime)
|
||||
set_target_properties(runtime PROPERTIES INSTALL_RPATH "$ORIGIN/../lib/native")
|
||||
target_link_options(runtime PRIVATE "LINKER:--disable-new-dtags")
|
||||
endif()
|
1
dependencies/runtime/src
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 84e37b572b55afb1eaa2ada1e37bc36de1584cfd
|
18
dependencies/stb_image/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
project(stb_image)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w)
|
||||
|
||||
## stb_image
|
||||
|
||||
# Build
|
||||
add_library(stb_image SHARED src/stb_image_impl.c)
|
||||
target_link_libraries(stb_image PRIVATE m)
|
||||
target_compile_definitions(stb_image PUBLIC STBI_ONLY_PNG)
|
||||
setup_header_dirs(stb_image "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
||||
# Install
|
||||
setup_library(stb_image TRUE TRUE)
|
||||
|
||||
# License
|
||||
install(FILES include/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/stb_image")
|
1
dependencies/stb_image/include
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit beebb24b945efdea3b9bba23affb8eb3ba8982e7
|
5
dependencies/stb_image/src/stb_image_impl.c
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_write.h"
|
20
dependencies/symbol-processor/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
project(symbol-processor)
|
||||
|
||||
# Install Dependencies
|
||||
set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
set(NODE_MODULES "${SRC}/node_modules")
|
||||
function(npm_run)
|
||||
execute_process(
|
||||
COMMAND npm ${ARGV}
|
||||
WORKING_DIRECTORY "${SRC}"
|
||||
RESULT_VARIABLE RESULT
|
||||
)
|
||||
if(NOT RESULT EQUAL 0)
|
||||
file(REMOVE_RECURSE "${NODE_MODULES}")
|
||||
message(FATAL_ERROR "Unable To Run NPM Command")
|
||||
endif()
|
||||
endfunction()
|
||||
if(NOT EXISTS "${NODE_MODULES}")
|
||||
npm_run(ci --silent)
|
||||
npm_run(run --silent lint)
|
||||
endif()
|
1
dependencies/symbol-processor/src
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c803572e248998cc9d197f84661fea56bebf7346
|
12
dependencies/utf8cpp/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
project(utf8cpp)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w)
|
||||
|
||||
## stb_image
|
||||
|
||||
# Build
|
||||
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||
|
||||
# License
|
||||
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/UTF8-CPP")
|
1
dependencies/utf8cpp/src
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f6780f77f6824aa0fbe69f9b97ef7d8aba26ed92
|
424
docs/CHANGELOG.md
Normal file
@ -0,0 +1,424 @@
|
||||
# Changelog
|
||||
|
||||
**3.0.0**
|
||||
* Modding API Revamped
|
||||
* `*(unsigned char **)` Is Dead!
|
||||
* Now C++ Only
|
||||
* Add Peaceful Mode To Options Screen
|
||||
* Proper Create New World Screen
|
||||
* Proper Chat Screen
|
||||
* New Feature Flags
|
||||
* New Functionality
|
||||
* `Animated Lava` (Enabled By Default)
|
||||
* `Animated Fire` (Enabled By Default)
|
||||
* `Add Cake` (Enabled By Default)
|
||||
* `Use Java Beta 1.3 Light Ramp` (Enabled By Default)
|
||||
* `Send Full Level When Hosting Game` (Enabled By Default)
|
||||
* `Food Overlay` (Disabled By Default)
|
||||
* `Add Splashes` (Enabled By Default)
|
||||
* `Display Date In Select World Screen` (Enabled By Default)
|
||||
* `Optimized Chunk Sorting` (Enabled By Default)
|
||||
* `Fix Held Item Caching` (Enabled By Default)
|
||||
* `Add Reborn Info To Options` (Enabled By Default)
|
||||
* `Log FPS` (Disabled By Default)
|
||||
* `Add Welcome Screen` (Enabled By Default)
|
||||
* `F3 Debug Information` (Enabled By Default)
|
||||
* `Multidraw Rendering` (Enabled By Default)
|
||||
* `Add Missing Language Strings` (Enabled By Default)
|
||||
* `Fix Pigmen Burning In The Sun` (Enabled By Default)
|
||||
* `Fix Carried Grass's Bottom Texture` (Enabled By Default)
|
||||
* `Hide Crosshair In Third-Person` (Enabled By Default)
|
||||
* `Fix Camera Legs` (Enabled By Default)
|
||||
* `Implement Crafting Remainders` (Enabled By Default)
|
||||
* `Fix Door Duplication` (Enabled By Default)
|
||||
* `Fix Cobweb Lighting` (Enabled By Default)
|
||||
* `Fix Sneaking Syncing` (Enabled By Default)
|
||||
* `Fix Fire Immunity` (Enabled By Default)
|
||||
* `Fix Fire Syncing` (Enabled By Default)
|
||||
* `Fix Sunlight Not Properly Setting Mobs On Fire` (Enabled By Default)
|
||||
* `Stop Creative Players From Burning` (Enabled By Default)
|
||||
* `Render Fire In Third-Person` (Enabled By Default)
|
||||
* `Improved Water Rendering` (Enabled By Default)
|
||||
* `Classic Item Count UI` (Enabled By Default)
|
||||
* `Allow High-Resolution Title` (Enabled By Default)
|
||||
* `Improved Classic Title Positioning` (Enabled By Default)
|
||||
* `Use Updated Title` (Enabled By Default)
|
||||
* `Hide Block Outline When GUI Is Hidden` (Enabled By Default)
|
||||
* `Fix Crash When Generating Certain Seeds` (Enabled By Default)
|
||||
* `Click Buttons On Mouse Down` (Enabled By Default)
|
||||
* `3D Dropped Items` (Enabled By Default)
|
||||
* `Render Entity Shadows` (Enabled By Default)
|
||||
* `Render Vignette` (Enabled By Default)
|
||||
* `Increase Render Chunk Size` (Enabled By Default)
|
||||
* `Proper Entity Shading` (Enabled By Default)
|
||||
* `Fix Sugar Position In Hand` (Enabled By Default)
|
||||
* `Fix Reloading Textures On Resize` (Enabled By Default)
|
||||
* `Improved UI Scaling` (Enabled By Default)
|
||||
* `Text Rendering Fixes` (Enabled By Default)
|
||||
* `Close Editor When Sign Is Destroyed` (Enabled By Default)
|
||||
* `Remove Chest Placement Restrictions` (Enabled By Default)
|
||||
* `Fix Hanging When No Valid Spawn Point Exists` (Enabled By Default)
|
||||
* `Batch Font Rendering` (Enabled By Default)
|
||||
* `Fix Furnace Screen Visual Bug` (Enabled By Default)
|
||||
* `Fix Held Item Poking Through Screen Overlay` (Enabled By Default)
|
||||
* Existing Functionality (All Enabled By Default)
|
||||
* `Fix Screen Rendering When Hiding HUD`
|
||||
* `Sanitize Usernames`
|
||||
* `Patch RakNet Security Bug`
|
||||
* `Log RakNet Startup Errors`
|
||||
* `Prevent Unnecessary Server Pinging`
|
||||
* `Proper OpenGL Buffer Generation`
|
||||
* `Fullscreen Support`
|
||||
* `Always Save Chest Tile Entities`
|
||||
* `Fix Transferring Durability When Using Items`
|
||||
* `Fix Switching Perspective While Sneaking`
|
||||
* `Log Chat Messages`
|
||||
* `Log Game Status`
|
||||
* `Screenshot Support`
|
||||
* `Fix Camera Functionality`
|
||||
* `Property Scale Animated Textures`
|
||||
* `Enable Text Input`
|
||||
* `Update Default Options`
|
||||
* `Fix options.txt Loading/Saving`
|
||||
* `Extend Supported Keycodes`
|
||||
* Split Up `Remove Creative Mode Restrictions` Feature Flag
|
||||
* `Remove Creative Mode Restrictions` (Disabled By Default)
|
||||
* `Display Slot Count In Creative Mode` (Disabled By Default)
|
||||
* `Force Survival Mode Inventory UI` (Disabled By Default)
|
||||
* `Force Survival Mode Inventory Behavior` (Disabled By Default)
|
||||
* `Maximize Creative Mode Inventory Stack Size` (Disabled By Default)
|
||||
* Split Up `Miscellaneous Input Fixes` Feature Flag
|
||||
* `Fix Escape Key Handling` (Enabled By Default)
|
||||
* `Stop Locked Mouse From Interacting With HUD` (Enabled By Default)
|
||||
* Rename Feature Flags
|
||||
* `Disable Buggy Held Item Caching` To `Fix Held Item Caching`
|
||||
* `Disable 'gui_blocks' Atlas` To `Regenerate "gui_blocks" Atlas`
|
||||
* `Fix Sign Placement` To `Enable Sign Screen`
|
||||
* `Force Touch GUI Inventory` To `Force Touch UI Inventory`
|
||||
* `Full Touch GUI` To `Full Touch UI`
|
||||
* `Force Touch GUI Button Behavior` To `Force Touch UI Button Behavior`
|
||||
* `Remove Forced GUI Lag (Can Break Joining Servers)` To `Remove Forced UI Lag (Can Break Joining Servers)`
|
||||
* `Hide Block Outline When GUI Is Hidden` To `Hide Block Outline When UI Is Hidden`
|
||||
* `Fix Camera Functionality` To `Add Camera Functionality`
|
||||
* `Fix Camera Rendering` To `Enable Camera Rendering`
|
||||
* `Fix Camera Legs` To `Render Camera Legs`
|
||||
* Add Milk Buckets
|
||||
* Included In The `Add Buckets` Feature Flag
|
||||
* Removed `Property Scale Animated Textures` Feature Flag
|
||||
* Removed `Remove Invalid Item Background` Feature Flag
|
||||
* Improve Death Messages
|
||||
* Massive Build System Improvements
|
||||
* Fix Item Dropping When Killing Players From The Server Console
|
||||
* Fix Furnace Visual Bug When Using Lava Bucket As Fuel
|
||||
* `overwrite_calls` Now Scans VTables
|
||||
* Unify Server/Client Builds
|
||||
* Controller Support Removed
|
||||
* Brand New Launcher UI!
|
||||
|
||||
**2.5.3**
|
||||
* Add `Replace Block Highlight With Outline` Feature Flag (Enabled By Default)
|
||||
* By Default, The Outline Width Is Set Using The GUI Scale
|
||||
* This Can Be Overridden Using The `MCPI_BLOCK_OUTLINE_WIDTH` Environmental Variable
|
||||
* Added `overwrite_calls_within` Function
|
||||
|
||||
**2.5.2**
|
||||
* Add `3D Chest Model` Feature Flag (Enabled By Default)
|
||||
* Stop Using Jenkins
|
||||
* Replace `iconv`
|
||||
* Replace LibPNG
|
||||
|
||||
**2.5.1**
|
||||
* Allow Overriding Custom Skin Server Using `MCPI_SKIN_SERVER` Environmental Variable
|
||||
* Fix Bug With SDK Generation
|
||||
|
||||
**2.5.0**
|
||||
* [Custom skin support](CUSTOM_SKINS.md)!
|
||||
* Add `Load Custom Skins` Feature Flag (Enabled By Default)
|
||||
|
||||
**2.4.9**
|
||||
* Allow Overriding GUI Scale With `MCPI_GUI_SCALE` Environmental Variable
|
||||
* Add `Disable Block Tinting` Feature Flag (Disabled By Default)
|
||||
* Add `Disable Hostile AI In Creative Mode` Feature Flag (Enabled By Default)
|
||||
* Allow Accessing Configuration At Runtime (Useful For Mods That Need To Support Multiple Versions)
|
||||
|
||||
**2.4.8**
|
||||
* Fix Bug In `extract_from_bl_instruction`
|
||||
* Update LIEF And GLFW
|
||||
* Allow Mods To Access The Original GLFW Keycode For Key Events (But Better)
|
||||
* More Accurate Sound
|
||||
|
||||
**2.4.7**
|
||||
* Improve Server Performance
|
||||
* Add `Add Biome Colors To Grass` Feature Flag (Disabled By Default)
|
||||
* Add `Generate Caves` Feature Flag (Enabled By Default)
|
||||
* Allow Mods To Access The Original GLFW Keycode For Key Events
|
||||
|
||||
**2.4.6**
|
||||
* [Minimal Controller Support](CONTROLS.md)
|
||||
* Fix Holding Left-Click When Attacking
|
||||
* Fix Crashing On ARMHF
|
||||
* Heavily Improved Crash Report Dialog
|
||||
|
||||
**2.4.5**
|
||||
* Bundle QEMU
|
||||
|
||||
**2.4.4**
|
||||
* Cache Previous Launcher Configuration
|
||||
* Add `MCPI_API_PORT` Environmental Variable
|
||||
* Fix Particles In Front-Facing View
|
||||
* Fixed Launch Crash On Ubuntu ARM64
|
||||
* PatchELF Replaced With LIEF
|
||||
* Moved `3D Anaglyph` Feature Flag To Options Screen
|
||||
* Add `Improved Classic Title Screen` Feature Flag (Enabled By Default)
|
||||
* Add Quit button
|
||||
* Add Options Button (Moved From `Fix Options Screen` Feature Flag)
|
||||
* Add `Disable Speed Bridging` Feature Flag (Disabled By Default)
|
||||
* Add `Disable Creative Mode Mining Delay` Feature Flag (Disabled By Default)
|
||||
* Improved Feature Flag Names
|
||||
* Miscellaneous Bug Fixes
|
||||
* Improved Build System
|
||||
|
||||
**2.4.3**
|
||||
* Fix Signs With CP-437
|
||||
|
||||
**2.4.2**
|
||||
* Fix Picking Up Lava
|
||||
* Fix Wayland App ID
|
||||
|
||||
**2.4.1**
|
||||
* Allow More Characters In Usernames And Chat
|
||||
* Fix Running On ARMHF Debian Buster
|
||||
|
||||
**2.4.0**
|
||||
* [Modding SDK](../example-mods/README.md)
|
||||
* Cache Blacklist/Whitelist
|
||||
* More Reliable AppImages
|
||||
* CMake Refactors
|
||||
* Disable Broken Touchscreen-Specific Block Outline Behavior
|
||||
* Add `Remove Forced GUI Lag (Can Break Joining Servers)` Feature Flag (Disabled By Default)
|
||||
* Add `Add Buckets` Feature Flag (Enabled By Default)
|
||||
* Add `Classic HUD` Feature Flag (Enabled By Default)
|
||||
* Add `Translucent Toolbar` Feature Flag (Enabled By Default)
|
||||
* Add `Force EGL` Feature Flag (Disabled By Default)
|
||||
* Fix Sound Pitch/Volume/Attenuation
|
||||
* Fix Holding Left-Click When Attacking
|
||||
* Don't Force EGL (Should Fix Some NVIDIA Systems)
|
||||
* Performance Fixes
|
||||
|
||||
**2.3.13**
|
||||
* Fix Texture Bug
|
||||
|
||||
**2.3.12**
|
||||
* Media Layer Proxy Optimizations
|
||||
* Bug Fixes
|
||||
|
||||
**2.3.11**
|
||||
* `--version` Command Line Option
|
||||
* TPS Measured In Benchmark & Server
|
||||
* Front-Facing Third-Person
|
||||
* GLESv1 Comparability Layer
|
||||
* Miscellaneous Bug Fixes
|
||||
|
||||
**2.3.10**
|
||||
* Add Crash Report Dialog
|
||||
* Disable V-Sync By Default
|
||||
* Refactor Child Process Management
|
||||
* Improve Build System
|
||||
* Support For Building On Ubuntu 22.04
|
||||
|
||||
**2.3.9**
|
||||
* Bundle An ARM Sysroot
|
||||
* Not Used On ARM32 Systems
|
||||
* Based On Debian Bullseye
|
||||
* Colored Log Output
|
||||
|
||||
**2.3.8**
|
||||
* Switch Up Mod Loading Order
|
||||
|
||||
**2.3.7**
|
||||
* Don't Append Hyphens To New World Name, Only Folder Names
|
||||
|
||||
**2.3.6**
|
||||
* Fix `Invert Y-axis` Option Name
|
||||
* Improve Touch GUI Inventory In Non-Touch GUI
|
||||
* New Create World Dialog
|
||||
* Controlled By `Implement Create World Dialog` Feature Flag (Enabled By Default)
|
||||
* Custom World Names
|
||||
* Game-Mode Selection
|
||||
* Custom Seeds
|
||||
|
||||
**2.3.5**
|
||||
* Renamed Some Feature Flags
|
||||
* Add `Improved Title Background` Feature Flag (Enabled By Default)
|
||||
* Non-Touch GUI Rework
|
||||
* Make `Full Touch GUI` Feature Flag Disabled By Default
|
||||
* Add `Force Touch GUI Button Behavior` Feature Flag (Enabled By Default)
|
||||
* Add `Improved Button Hover Behavior` Feature Flag (Enabled By Default)
|
||||
|
||||
**2.3.4**
|
||||
* AppImage Fixes
|
||||
* Make Death Messages Customizable Server-Side
|
||||
* Fix Q-Key Behavior Behavior When Editing Signs
|
||||
* Add `Force Touch Inventory` Feature Flag (Disabled By Default)
|
||||
* Add `Fix Pause Menu` Feature Flag (Enabled By Default)
|
||||
* Enables Server Visibility Toggle Button
|
||||
* Options Changes (Not Supported On Legacy)
|
||||
* Add `Fix Options Screen` Feature Flag (Enabled By Default)
|
||||
* Adds Options Button To Classic UI Start Screen
|
||||
* Removes Useless Options Toggles
|
||||
* Fixes Options Toggles' Default Position
|
||||
* Store Multiple Settings In `options.txt`
|
||||
* `Peaceful Mode` Feature Flag Moved To `game_difficulty`
|
||||
* `Smooth Lighting` Feature Flag Moved To `gfx_ao`
|
||||
* `Fancy Graphics` Feature Flag Moved To `gfx_fancygraphics`
|
||||
* `Disable Hosting LAN Worlds` Feature Flag Moved To `mp_server_visible_default`
|
||||
|
||||
**2.3.3**
|
||||
* Add More Blocks To Expanded Creative Inventory
|
||||
* Add AppStream Metadata
|
||||
|
||||
**2.3.2**
|
||||
* Simplify Launch Sequence
|
||||
* Add More Blocks To Expanded Creative Inventory
|
||||
* Fix Nether Reactor With Creative Restrictions Disabled
|
||||
* Alphabetize Feature Flags
|
||||
* Add `Disable V-Sync` Feature Flag (Disabled By Default)
|
||||
|
||||
**2.3.1**
|
||||
* Internal Refactor Of `libreborn`
|
||||
* Remove Use Of `/bin/sh`
|
||||
* Load Custom Mods First
|
||||
* Use Zenity Dark Mode
|
||||
* Add `Improved Cursor Rendering` Feature Flag (Enabled By Default)
|
||||
|
||||
**2.3.0**
|
||||
* Switch To AppImage For Packaging
|
||||
* Prevent OpenAL From Crashing When Out Of Memory
|
||||
* Vendor GLFW & Zenity
|
||||
* Seamless Wayland Support
|
||||
* Add `MCPI_DEBUG` Environmental Variable
|
||||
* Add `Disable Hosting LAN Worlds` Feature Flag (Disabled By Default)
|
||||
* Add `Fix Furnace Not Checking Item Auxiliary` Feature Flag (Enabled By Default)
|
||||
* Add `Disable Raw Mouse Motion (Not Recommended)` Feature Flag (Disabled By Default) For Broken X11 Setups
|
||||
* Added Back `~/.minecraft-pi/mods`
|
||||
* Improve Build System
|
||||
* Improve Documentation
|
||||
|
||||
**2.2.11**
|
||||
* Add `Close Current Screen On Death` Feature Flag (Enabled By Default) To Prevent Bugs
|
||||
* Fix More Furnace UI Bugs When Using `Disable 'gui_blocks' Atlas`
|
||||
|
||||
**2.2.10**
|
||||
* Fix Bug With Picking Up Items In "Remove Creative Mode Restrictions" Mode
|
||||
|
||||
**2.2.9**
|
||||
* Fix String Sanitization
|
||||
* Store Files In `/usr/lib`
|
||||
|
||||
**2.2.8**
|
||||
* Add `Hide Chat Messages` Optional Feature Flag
|
||||
* Add `Remove Creative Mode Restrictions` Optional Feature Flag
|
||||
* Improve GLFW->SDL Mouse Motion Event Conversion
|
||||
* Performance Optimizations
|
||||
* Make Majority Of Server-Specific Logging Code Also Apply To The Client
|
||||
* Simple Benchmark Mode
|
||||
* Fix Typo When Audio Source File Doesn't Exist
|
||||
* Improve Build System
|
||||
|
||||
**2.2.7**
|
||||
* Fix Crash When OpenAL Is Unavailable
|
||||
* Fix Command Input In Server
|
||||
|
||||
**2.2.5**
|
||||
* Fix Bug In Texture Scaling Code
|
||||
|
||||
**2.2.5**
|
||||
* Scale Animated Textures
|
||||
* Add More Blocks To Expanded Creative Inventory
|
||||
* Reduce Unnecessary Logging
|
||||
* Log IPs In Server Mode
|
||||
|
||||
**2.2.4**
|
||||
* Instead Of Crashing, Disable Polling Block Hits In Survival Mode Using The API
|
||||
|
||||
**2.2.3**
|
||||
* Fix Crash When Taking Odd-Sized Screenshots
|
||||
|
||||
**2.2.2**
|
||||
* Add More Missing Sound Events
|
||||
* Make Missing Sound Event Cause Warning Rather Than Crash
|
||||
|
||||
**2.2.1**
|
||||
* Prevent `random.burp` Sound From Crashing Game
|
||||
* Always Cleanup Media Layer, Even On Crash
|
||||
* Resolve All Sounds On Startup
|
||||
|
||||
**2.2.0**
|
||||
* Sound Support
|
||||
* Split Off `Allow Joining Survival Servers` From Game-Mode Mod
|
||||
* Separate Headless Code From Server Code
|
||||
* Fix Bug Where `RakNetInstance` Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
|
||||
* Clean-Up Code
|
||||
* Remove Support For Debian Buster
|
||||
|
||||
**2.1.8**
|
||||
* Fix Crash On ARM Systems
|
||||
|
||||
**2.1.7**
|
||||
* Fix On 64-Bit ARM Systems
|
||||
|
||||
**2.1.6**
|
||||
* Optimize Media Layer Proxy
|
||||
|
||||
**2.1.5**
|
||||
* Print Error Message If RakNet Fails To Start
|
||||
|
||||
**2.1.4**
|
||||
* Fix `RakNet::RakString` Security Bug
|
||||
|
||||
**2.1.3**
|
||||
* Workaround Broken Library Search Path On Some ARM 32-Bit Systems
|
||||
|
||||
**2.1.2**
|
||||
* Fix Library Loading On ARM 32-Bit Systems
|
||||
|
||||
**2.1.1**
|
||||
* Fix Symlink Code
|
||||
|
||||
**2.1.0**
|
||||
* Allow Binding `Q` Key To Item Dropping
|
||||
* Expose More Feature Flags
|
||||
* Replace `Mob Spawning` Feature Flag With `Force Mob Spawning`
|
||||
* Fix `ESC` Key In Options Menu When `Miscellaneous Input Fixes` Is Enabled
|
||||
|
||||
**2.0.9**
|
||||
* Fix Translucent Preview Items In Furnace UI Being Fully Opaque When The `gui_blocks` Atlas Is Disabled
|
||||
|
||||
**2.0.8**
|
||||
* Use Default Port In `servers.txt` If Not Specified
|
||||
|
||||
**2.0.7**
|
||||
* Fix Sign Text Not Updating In Multiplayer When Exiting Editing UI Using Escape Button
|
||||
* Fix Item Dropping Not Working
|
||||
|
||||
**2.0.6**
|
||||
* Fix Toolbar Size In Normal GUI
|
||||
|
||||
**2.0.5**
|
||||
* Show Reborn Version In Start Screen
|
||||
* External Server Support
|
||||
|
||||
**2.0.4**
|
||||
* Optimize Media Layer Proxy
|
||||
|
||||
**2.0.3**
|
||||
* Make `kill` Admin Command Print Death Message
|
||||
|
||||
**2.0.2**
|
||||
* Fix Mouse Cursor Bugs
|
||||
|
||||
**2.0.1**
|
||||
* Fix Blank Screen On Twister OS
|
||||
|
||||
**2.0.0**
|
||||
* Major Rewrite
|
26
docs/CONTROLS.md
Normal file
@ -0,0 +1,26 @@
|
||||
# In-Game Controls
|
||||
|
||||
## Keyboard & Mouse
|
||||
| Action | Function |
|
||||
| --- | --- |
|
||||
| W | Move Forward |
|
||||
| A | Move Left |
|
||||
| S | Move Backward |
|
||||
| D | Move Right |
|
||||
| Space | Jump |
|
||||
| Shift | Sneak |
|
||||
| E | Open Inventory |
|
||||
| Q | Drop Item |
|
||||
| Ctrl+Q | Drop Item Stack |
|
||||
| 1-9 | Select Item In Toolbar/Hotbar |
|
||||
| Escape | Pause |
|
||||
| Tab | Lock/Unlock Mouse |
|
||||
| F11 | Fullscreen |
|
||||
| F2 | Screenshot |
|
||||
| F1 | Hide GUI |
|
||||
| F5 | Change Perspective |
|
||||
| T | Open Chat |
|
||||
| Mouse Movement | Camera Control |
|
||||
| Scroll Wheel | Cycle Selected Item In Toolbar |
|
||||
| Left-CLick | Attack/Destroy |
|
||||
| Right-Click | Use Item/Place Block |
|
11
docs/CREDITS.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Credits
|
||||
| Project | Reason |
|
||||
| --- | --- |
|
||||
| [mhsjlw/mcpilauncher](https://github.com/mhsjlw/mcpilauncher/blob/master/trampoline/trampoline.c) | Information On Getting Minecraft: Pi Eiditon To Run On Desktop Linux |
|
||||
| [Phirel's Survival Patch](https://www.minecraftforum.net/forums/minecraft-editions/minecraft-pi-edition/1960005-survival-mode-patch) | Information On Survival Mode Support |
|
||||
| [zhuowei/MinecraftPEModWiki](https://github.com/zhuowei/MinecraftPEModWiki/wiki/How-some-unlocks-are-made) | Information On Smooth Lighting Support |
|
||||
| [Ghidra](https://ghidra-sre.org) | Used For Decompiling Minecraft: Pi Edition |
|
||||
| [RetDec](https://retdec.com) | Used For Decompiling Minecraft: Pi Edition |
|
||||
| [minecraft-linux/mcpelauncher-core](https://github.com/minecraft-linux/mcpelauncher-core/blob/6b5e17b5685a612143297ae4595bdd12327284f3/src/patch_utils.cpp#L42) | Original Function Overwrite Code |
|
||||
| [Hooking C Functions at Runtime - Thomas Finch](http://thomasfinch.me/blog/2015/07/24/Hooking-C-Functions-At-Runtime.html) | Original Patching Code |
|
||||
| [ReMinecraftPE](https://github.com/ReMinecraftPE/mcpe) | A Lot Of Decompiled Code |
|
6
docs/CUSTOM_SKINS.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Custom Skins
|
||||
MCPI-Reborn supports downloading custom skins from [a central skin server](https://github.com/MCPI-Revival/Skins). Skins are downloaded based on the current MCPI username.
|
||||
|
||||
This *does not* cache skins and *will not* work without internet access.
|
||||
|
||||
Custom skins can be disabled using the `Load Custom Skins` feature flag.
|
14
docs/DEDICATED_SERVER.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Dedicated Server
|
||||
The dedicated server is a version of Minecraft: Pi Edition modified to run in a headless environment. It loads settings from a `server.properties` file.
|
||||
|
||||
This server is also compatible with MCPE Alpha v0.6.1[^1].
|
||||
|
||||
## Setup
|
||||
To use, run the normal AppImage with the `--server` argument. It will generate the world and `server.properties` in the current directory.
|
||||
|
||||
## Server Limitations
|
||||
* Player data is not saved because of limitations with MCPE LAN worlds
|
||||
* An easy workaround is to place your inventory in a chest before logging off
|
||||
* Survival Mode servers are incompatible with un-modded MCPI
|
||||
|
||||
[^1]: The exception to this is buckets and other modded items, those will crash MCPE players.
|
70
docs/GETTING_STARTED.md
Normal file
@ -0,0 +1,70 @@
|
||||
---
|
||||
gitea: none
|
||||
include_toc: true
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
Welcome to the official guide for setting up Minecraft: Pi Edition: Reborn (also known as MCPI-Reborn)! This document will help you through the installation and setup process.
|
||||
|
||||
## System Requirements
|
||||
MCPI-Reborn requires support for OpenGL ES v2.0 (unlike the original game, which used OpenGL ES v1.1). It also only supports Linux-based systems.
|
||||
|
||||
In addition, while the original game could only be run on the Raspberry Pi, MCPI-Reborn is much more flexible. It supports running on 32-bit ARM (known as `armhf`), 64-bit ARM (known as `arm64`), and 64-bit x86 (known as `amd64`).
|
||||
|
||||
## Installation
|
||||
There are three supported ways to install MCPI-Reborn.
|
||||
|
||||
### AppImage
|
||||
The first supported way to install MCPI-Reborn is with an [AppImage](https://appimage.org). An AppImage is a portable application format that allows users to run software without installation.
|
||||
|
||||
To run MCPI-Reborn, all you need to do is [download the latest AppImage](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases/latest) for your architecture and run it.
|
||||
|
||||
More details can be found [here](https://docs.appimage.org/introduction/quickstart.html#how-to-run-an-appimage).
|
||||
|
||||
<details>
|
||||
<summary><b>Additional System Requirements</b></summary>
|
||||
The AppImage requires Debian Bullseye or higher. This is equivalent to Ubuntu 20.04.
|
||||
|
||||
It also requires some additional packages. To install them, run:
|
||||
```sh
|
||||
sudo apt install -y libopenal1 libglib2.0-0
|
||||
```
|
||||
</details>
|
||||
|
||||
### Flatpak
|
||||
The next method is the official [Flatpak](https://www.flatpak.org/). This method has the additional benefit of built-in sandboxing. Unfortunately, it does not support 32-bit ARM systems.
|
||||
|
||||
It can be installed through [Flathub](https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn).
|
||||
|
||||
### Pi-Apps
|
||||
The final supported method is [Pi-Apps](https://github.com/Botspot/pi-apps). It is a ["well-maintained collection of app installation-scripts"](https://github.com/Botspot/pi-apps#:~:text=well-maintained%20collection%20of%20app%20installation-scripts) that includes support for MCPI-Reborn.
|
||||
|
||||
The list of systems supported by Pi-Apps can be found [here](https://github.com/Botspot/pi-apps?tab=readme-ov-file#supported-systems).
|
||||
|
||||
## Managing Game Data
|
||||
Just as regular Minecraft stores game data at `~/.minecraft`, MCPI-Reborn uses `~/.minecraft-pi`[^1]. This is the profile directory and is where your worlds, screenshots, and game settings are stored.
|
||||
|
||||
The profile directory can easily be accessed by opening MCPI-Reborn and going to `Options -> Reborn -> Profile Directory`.
|
||||
|
||||
## Sound
|
||||
One of MCPI-Reborn's most important modifications is the addition of a sound engine. However, due to copyright limitations, Minecraft's sounds cannot be distributed with MCPI-Reborn and must be installed manually.
|
||||
|
||||
Fortunately, installing the sound data is simple:
|
||||
1. Obtain a valid Minecraft: Pocket Edition v0.6.1[^2] APK file.
|
||||
2. Extract `lib/*/libminecraftpe.so` from the APK.
|
||||
3. Create the directory `<Profile Directory>/overrides` if it does not already exist.
|
||||
4. Copy `libminecraftpe.so` into `<Profile Directory>/overrides`.
|
||||
5. Sound should now be fully functional!
|
||||
|
||||
## Custom Textures
|
||||
MCPI-Reborn allows users to easily use custom textures through the use of an "overrides directory." Any files placed in this directory will automatically replace their equivalent file in MCPI-Reborn.
|
||||
|
||||
For instance, to override `data/images/terrain.png`, you would copy the replacement file to `<Overrides Folder>/images/terrain.png`.
|
||||
|
||||
The overrides directory is located at `<Profile Directory>/overrides`.
|
||||
|
||||
## Discord
|
||||
If you have any questions or just want to talk about Minecraft: Pi Edition, there is an [official Discord server](https://discord.com/invite/aDqejQGMMy)!
|
||||
|
||||
[^1]: When using the Flatpak, the profile directory is located at `~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi`.
|
||||
[^2]: This is not a strict requirement; a Minecraft: Pocket Edition v0.8.1 APK would likely work, but it is not guaranteed.
|
8
docs/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Documentation
|
||||
* [View Getting Started](GETTING_STARTED.md)
|
||||
* [View Dedicated Server](DEDICATED_SERVER.md)
|
||||
* [View Credits](CREDITS.md)
|
||||
* [View Terminology](TERMINOLOGY.md)
|
||||
* [View In-Game Controls](CONTROLS.md)
|
||||
* [View Custom Skins](CUSTOM_SKINS.md)
|
||||
* [View Changelog](CHANGELOG.md)
|
11
docs/TERMINOLOGY.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Terminology
|
||||
| Name | Description |
|
||||
| --- | --- |
|
||||
| MCPI | Shorthand for Minecraft: Pi Edition |
|
||||
| MCPE | Shorthand for Minecraft: Pocket Edition |
|
||||
| Host Architecture | The native architecture of the CPU that MCPi-Reborn will be running on |
|
||||
| Native Component | A component that *can* be compiled for the host architecture |
|
||||
| ARM Component | A component that *must* be compiled for ARM |
|
||||
| Server Mode | A mode where MCPI is patched into behaving like a dedicated server |
|
||||
| Client Mode | The normal behavior of MCPI |
|
||||
| Stub | An implementation of a library where all functions either do nothing or error |
|
11
example-mods/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Example Mods
|
||||
These are example mods that can be built using the modding SDK.
|
||||
|
||||
* **Expanded Creative Mod**: This specific mod adds even more items and blocks to the Creative Inventory. It was originally by [@Bigjango13](https://github.com/bigjango13).
|
||||
* **Chat Commands Mod**: This specific mod makes a chat message starting with `/` handled by the MCPI API.
|
||||
* **Recipes Mod**: This specific mod demos custom recipes.
|
||||
|
||||
## The SDK
|
||||
The modding SDK is a collection of exported CMake targets that allows anyone to create their own MCPI mod!
|
||||
|
||||
The SDK is copied to `~/.minecraft-pi/sdk` whenever MCPI-Reborn is started.
|
26
example-mods/build.sh
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
# Create Output Directory
|
||||
cd "$(dirname "$0")"
|
||||
ROOT="$(pwd)"
|
||||
OUT="${ROOT}/out"
|
||||
rm -rf "${OUT}"
|
||||
mkdir -p "${OUT}"
|
||||
|
||||
# Build
|
||||
build() {
|
||||
cd "${ROOT}/$1"
|
||||
# Build
|
||||
rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -GNinja ..
|
||||
cmake --build .
|
||||
# Copy Result
|
||||
cp lib*.so "${OUT}"
|
||||
}
|
||||
build chat-commands
|
||||
build expanded-creative
|
||||
build recipes
|
15
example-mods/chat-commands/.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/out
|
||||
/debian/tmp
|
||||
/.vscode
|
||||
/build*
|
||||
/CMakeLists.txt.user
|
||||
*.autosave
|
||||
/AppImageBuilder.yml
|
||||
/appimage-builder-cache
|
||||
/appimage-build
|
||||
/AppDir
|
||||
/*.zsync
|
||||
/*.AppImage
|
||||
/core*
|
||||
/qemu_*
|
||||
/cmake/.prebuilt-armhf-toolchain
|
17
example-mods/chat-commands/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
|
||||
# Build For ARM
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
||||
set(CMAKE_SYSTEM_NAME "Linux")
|
||||
set(CMAKE_SYSTEM_PROCESSOR "arm")
|
||||
|
||||
# Start Project
|
||||
project(chat-commands)
|
||||
|
||||
# Include SDK
|
||||
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn/sdk/sdk.cmake")
|
||||
|
||||
# Build
|
||||
add_library(chat-commands SHARED chat-commands.cpp)
|
||||
target_link_libraries(chat-commands mods reborn-patch symbols)
|
45
example-mods/chat-commands/chat-commands.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include <libreborn/patch.h>
|
||||
#include <libreborn/util/util.h>
|
||||
#include <libreborn/util/string.h>
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/chat/chat.h>
|
||||
#include <mods/misc/misc.h>
|
||||
#include <mods/server/server.h>
|
||||
|
||||
// The Actual Mod
|
||||
HOOK(chat_handle_packet_send, void, (const Minecraft *minecraft, ChatPacket *packet)) {
|
||||
// Get Message
|
||||
const char *message = packet->message.c_str();
|
||||
if (message[0] == '/') {
|
||||
// API Command
|
||||
Minecraft *mc = (Minecraft *) minecraft;
|
||||
Gui *gui = &mc->gui;
|
||||
std::string out = chat_send_api_command(mc, (char *) &message[1]);
|
||||
if (out.length() > 0 && out[out.length() - 1] == '\n') {
|
||||
out[out.length() - 1] = '\0';
|
||||
}
|
||||
std::string cp437_out = to_cp437(out);
|
||||
gui->addMessage(cp437_out);
|
||||
} else {
|
||||
// Call Original Method
|
||||
real_chat_handle_packet_send()(minecraft, packet);
|
||||
}
|
||||
}
|
||||
|
||||
// Add Server Command
|
||||
HOOK(server_get_commands, std::vector<ServerCommand> *, (Minecraft *minecraft, ServerSideNetworkHandler *server_side_network_handler)) {
|
||||
// Call Original Method
|
||||
std::vector<ServerCommand> *commands = real_server_get_commands()(minecraft, server_side_network_handler);
|
||||
// Add Command
|
||||
commands->push_back({
|
||||
.name = "greet",
|
||||
.comment = "Example Custom Command",
|
||||
.callback = [](__attribute__((unused)) const std::string &cmd) {
|
||||
INFO("Hello World!");
|
||||
}
|
||||
});
|
||||
// Return
|
||||
return commands;
|
||||
}
|
15
example-mods/expanded-creative/.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/out
|
||||
/debian/tmp
|
||||
/.vscode
|
||||
/build*
|
||||
/CMakeLists.txt.user
|
||||
*.autosave
|
||||
/AppImageBuilder.yml
|
||||
/appimage-builder-cache
|
||||
/appimage-build
|
||||
/AppDir
|
||||
/*.zsync
|
||||
/*.AppImage
|
||||
/core*
|
||||
/qemu_*
|
||||
/cmake/.prebuilt-armhf-toolchain
|
17
example-mods/expanded-creative/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
|
||||
# Build For ARM
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
||||
set(CMAKE_SYSTEM_NAME "Linux")
|
||||
set(CMAKE_SYSTEM_PROCESSOR "arm")
|
||||
|
||||
# Start Project
|
||||
project(expanded-creative)
|
||||
|
||||
# Include SDK
|
||||
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn/sdk/sdk.cmake")
|
||||
|
||||
# Build
|
||||
add_library(expanded-creative SHARED expanded-creative.cpp)
|
||||
target_link_libraries(expanded-creative mods reborn-patch symbols)
|
548
example-mods/expanded-creative/expanded-creative.cpp
Normal file
@ -0,0 +1,548 @@
|
||||
#include <libreborn/patch.h>
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
// The Actual Mod
|
||||
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(FillingContainer *filling_container) {
|
||||
ItemInstance *fire_instance = new ItemInstance;
|
||||
fire_instance->count = 255;
|
||||
fire_instance->auxiliary = 0;
|
||||
fire_instance->id = 51;
|
||||
filling_container->addItem(fire_instance);
|
||||
|
||||
ItemInstance *mushroomStew_instance = new ItemInstance;
|
||||
mushroomStew_instance->count = 255;
|
||||
mushroomStew_instance->auxiliary = 0;
|
||||
mushroomStew_instance->id = 282;
|
||||
filling_container->addItem(mushroomStew_instance);
|
||||
|
||||
ItemInstance *steak_instance = new ItemInstance;
|
||||
steak_instance->count = 255;
|
||||
steak_instance->auxiliary = 0;
|
||||
steak_instance->id = 364;
|
||||
filling_container->addItem(steak_instance);
|
||||
|
||||
ItemInstance *cookedChicken_instance = new ItemInstance;
|
||||
cookedChicken_instance->count = 255;
|
||||
cookedChicken_instance->auxiliary = 0;
|
||||
cookedChicken_instance->id = 366;
|
||||
filling_container->addItem(cookedChicken_instance);
|
||||
|
||||
ItemInstance *porkCooked_instance = new ItemInstance;
|
||||
porkCooked_instance->count = 255;
|
||||
porkCooked_instance->auxiliary = 0;
|
||||
porkCooked_instance->id = 320;
|
||||
filling_container->addItem(porkCooked_instance);
|
||||
|
||||
ItemInstance *apple_instance = new ItemInstance;
|
||||
apple_instance->count = 255;
|
||||
apple_instance->auxiliary = 0;
|
||||
apple_instance->id = 260;
|
||||
filling_container->addItem(apple_instance);
|
||||
|
||||
ItemInstance *tallGrass_instance = new ItemInstance;
|
||||
tallGrass_instance->count = 255;
|
||||
tallGrass_instance->auxiliary = 0;
|
||||
tallGrass_instance->id = 31;
|
||||
filling_container->addItem(tallGrass_instance);
|
||||
|
||||
ItemInstance *crops_instance = new ItemInstance;
|
||||
crops_instance->count = 255;
|
||||
crops_instance->auxiliary = 0;
|
||||
crops_instance->id = 59;
|
||||
filling_container->addItem(crops_instance);
|
||||
|
||||
ItemInstance *farmland_instance = new ItemInstance;
|
||||
farmland_instance->count = 255;
|
||||
farmland_instance->auxiliary = 0;
|
||||
farmland_instance->id = 60;
|
||||
filling_container->addItem(farmland_instance);
|
||||
|
||||
ItemInstance *activeFurnace_instance = new ItemInstance;
|
||||
activeFurnace_instance->count = 255;
|
||||
activeFurnace_instance->auxiliary = 0;
|
||||
activeFurnace_instance->id = 62;
|
||||
filling_container->addItem(activeFurnace_instance);
|
||||
|
||||
ItemInstance *ironDoor_instance = new ItemInstance;
|
||||
ironDoor_instance->count = 255;
|
||||
ironDoor_instance->auxiliary = 0;
|
||||
ironDoor_instance->id = 330;
|
||||
filling_container->addItem(ironDoor_instance);
|
||||
|
||||
ItemInstance *activeRedstoneOre_instance = new ItemInstance;
|
||||
activeRedstoneOre_instance->count = 255;
|
||||
activeRedstoneOre_instance->auxiliary = 0;
|
||||
activeRedstoneOre_instance->id = 74;
|
||||
filling_container->addItem(activeRedstoneOre_instance);
|
||||
|
||||
ItemInstance *pumkinStem_instance = new ItemInstance;
|
||||
pumkinStem_instance->count = 255;
|
||||
pumkinStem_instance->auxiliary = 0;
|
||||
pumkinStem_instance->id = 105;
|
||||
filling_container->addItem(pumkinStem_instance);
|
||||
|
||||
ItemInstance *newGrass_instance = new ItemInstance;
|
||||
newGrass_instance->count = 255;
|
||||
newGrass_instance->auxiliary = 0;
|
||||
newGrass_instance->id = 253;
|
||||
filling_container->addItem(newGrass_instance);
|
||||
|
||||
ItemInstance *reserved6_instance = new ItemInstance;
|
||||
reserved6_instance->count = 255;
|
||||
reserved6_instance->auxiliary = 0;
|
||||
reserved6_instance->id = 1;
|
||||
filling_container->addItem(reserved6_instance);
|
||||
|
||||
ItemInstance *doubleStoneSlab_instance = new ItemInstance;
|
||||
doubleStoneSlab_instance->count = 255;
|
||||
doubleStoneSlab_instance->auxiliary = 0;
|
||||
doubleStoneSlab_instance->id = 43;
|
||||
filling_container->addItem(doubleStoneSlab_instance);
|
||||
|
||||
ItemInstance *arrow_instance = new ItemInstance;
|
||||
arrow_instance->count = 255;
|
||||
arrow_instance->auxiliary = 0;
|
||||
arrow_instance->id = 262;
|
||||
filling_container->addItem(arrow_instance);
|
||||
|
||||
ItemInstance *coal_instance = new ItemInstance;
|
||||
coal_instance->count = 255;
|
||||
coal_instance->auxiliary = 0;
|
||||
coal_instance->id = 263;
|
||||
filling_container->addItem(coal_instance);
|
||||
|
||||
ItemInstance *diamond_instance = new ItemInstance;
|
||||
diamond_instance->count = 255;
|
||||
diamond_instance->auxiliary = 0;
|
||||
diamond_instance->id = 264;
|
||||
filling_container->addItem(diamond_instance);
|
||||
|
||||
ItemInstance *ironIngot_instance = new ItemInstance;
|
||||
ironIngot_instance->count = 255;
|
||||
ironIngot_instance->auxiliary = 0;
|
||||
ironIngot_instance->id = 265;
|
||||
filling_container->addItem(ironIngot_instance);
|
||||
|
||||
ItemInstance *goldIngot_instance = new ItemInstance;
|
||||
goldIngot_instance->count = 255;
|
||||
goldIngot_instance->auxiliary = 0;
|
||||
goldIngot_instance->id = 266;
|
||||
filling_container->addItem(goldIngot_instance);
|
||||
|
||||
ItemInstance *woodSword_instance = new ItemInstance;
|
||||
woodSword_instance->count = 255;
|
||||
woodSword_instance->auxiliary = 0;
|
||||
woodSword_instance->id = 268;
|
||||
filling_container->addItem(woodSword_instance);
|
||||
|
||||
ItemInstance *woodShovel_instance = new ItemInstance;
|
||||
woodShovel_instance->count = 255;
|
||||
woodShovel_instance->auxiliary = 0;
|
||||
woodShovel_instance->id = 269;
|
||||
filling_container->addItem(woodShovel_instance);
|
||||
|
||||
ItemInstance *woodPickaxe_instance = new ItemInstance;
|
||||
woodPickaxe_instance->count = 255;
|
||||
woodPickaxe_instance->auxiliary = 0;
|
||||
woodPickaxe_instance->id = 270;
|
||||
filling_container->addItem(woodPickaxe_instance);
|
||||
|
||||
ItemInstance *woodAxe_instance = new ItemInstance;
|
||||
woodAxe_instance->count = 255;
|
||||
woodAxe_instance->auxiliary = 0;
|
||||
woodAxe_instance->id = 271;
|
||||
filling_container->addItem(woodAxe_instance);
|
||||
|
||||
ItemInstance *stoneSword_instance = new ItemInstance;
|
||||
stoneSword_instance->count = 255;
|
||||
stoneSword_instance->auxiliary = 0;
|
||||
stoneSword_instance->id = 272;
|
||||
filling_container->addItem(stoneSword_instance);
|
||||
|
||||
ItemInstance *stoneShovel_instance = new ItemInstance;
|
||||
stoneShovel_instance->count = 255;
|
||||
stoneShovel_instance->auxiliary = 0;
|
||||
stoneShovel_instance->id = 273;
|
||||
filling_container->addItem(stoneShovel_instance);
|
||||
|
||||
ItemInstance *stonePickaxe_instance = new ItemInstance;
|
||||
stonePickaxe_instance->count = 255;
|
||||
stonePickaxe_instance->auxiliary = 0;
|
||||
stonePickaxe_instance->id = 274;
|
||||
filling_container->addItem(stonePickaxe_instance);
|
||||
|
||||
ItemInstance *stoneAxe_instance = new ItemInstance;
|
||||
stoneAxe_instance->count = 255;
|
||||
stoneAxe_instance->auxiliary = 0;
|
||||
stoneAxe_instance->id = 275;
|
||||
filling_container->addItem(stoneAxe_instance);
|
||||
|
||||
ItemInstance *shovelIron_instance = new ItemInstance;
|
||||
shovelIron_instance->count = 255;
|
||||
shovelIron_instance->auxiliary = 0;
|
||||
shovelIron_instance->id = 256;
|
||||
filling_container->addItem(shovelIron_instance);
|
||||
|
||||
ItemInstance *ironPick_instance = new ItemInstance;
|
||||
ironPick_instance->count = 255;
|
||||
ironPick_instance->auxiliary = 0;
|
||||
ironPick_instance->id = 257;
|
||||
filling_container->addItem(ironPick_instance);
|
||||
|
||||
ItemInstance *ironAxe_instance = new ItemInstance;
|
||||
ironAxe_instance->count = 255;
|
||||
ironAxe_instance->auxiliary = 0;
|
||||
ironAxe_instance->id = 258;
|
||||
filling_container->addItem(ironAxe_instance);
|
||||
|
||||
ItemInstance *diamondSword_instance = new ItemInstance;
|
||||
diamondSword_instance->count = 255;
|
||||
diamondSword_instance->auxiliary = 0;
|
||||
diamondSword_instance->id = 276;
|
||||
filling_container->addItem(diamondSword_instance);
|
||||
|
||||
ItemInstance *diamondShovel_instance = new ItemInstance;
|
||||
diamondShovel_instance->count = 255;
|
||||
diamondShovel_instance->auxiliary = 0;
|
||||
diamondShovel_instance->id = 277;
|
||||
filling_container->addItem(diamondShovel_instance);
|
||||
|
||||
ItemInstance *diamondPickaxe_instance = new ItemInstance;
|
||||
diamondPickaxe_instance->count = 255;
|
||||
diamondPickaxe_instance->auxiliary = 0;
|
||||
diamondPickaxe_instance->id = 278;
|
||||
filling_container->addItem(diamondPickaxe_instance);
|
||||
|
||||
ItemInstance *diamondAxe_instance = new ItemInstance;
|
||||
diamondAxe_instance->count = 255;
|
||||
diamondAxe_instance->auxiliary = 0;
|
||||
diamondAxe_instance->id = 279;
|
||||
filling_container->addItem(diamondAxe_instance);
|
||||
|
||||
ItemInstance *magicWand_instance = new ItemInstance;
|
||||
magicWand_instance->count = 255;
|
||||
magicWand_instance->auxiliary = 0;
|
||||
magicWand_instance->id = 280;
|
||||
filling_container->addItem(magicWand_instance);
|
||||
|
||||
ItemInstance *bowl_instance = new ItemInstance;
|
||||
bowl_instance->count = 255;
|
||||
bowl_instance->auxiliary = 0;
|
||||
bowl_instance->id = 281;
|
||||
filling_container->addItem(bowl_instance);
|
||||
|
||||
ItemInstance *goldSword_instance = new ItemInstance;
|
||||
goldSword_instance->count = 255;
|
||||
goldSword_instance->auxiliary = 0;
|
||||
goldSword_instance->id = 283;
|
||||
filling_container->addItem(goldSword_instance);
|
||||
|
||||
ItemInstance *goldShovel_instance = new ItemInstance;
|
||||
goldShovel_instance->count = 255;
|
||||
goldShovel_instance->auxiliary = 0;
|
||||
goldShovel_instance->id = 284;
|
||||
filling_container->addItem(goldShovel_instance);
|
||||
|
||||
ItemInstance *goldPickaxe_instance = new ItemInstance;
|
||||
goldPickaxe_instance->count = 255;
|
||||
goldPickaxe_instance->auxiliary = 0;
|
||||
goldPickaxe_instance->id = 285;
|
||||
filling_container->addItem(goldPickaxe_instance);
|
||||
|
||||
ItemInstance *goldAxe_instance = new ItemInstance;
|
||||
goldAxe_instance->count = 255;
|
||||
goldAxe_instance->auxiliary = 0;
|
||||
goldAxe_instance->id = 286;
|
||||
filling_container->addItem(goldAxe_instance);
|
||||
|
||||
ItemInstance *string_instance = new ItemInstance;
|
||||
string_instance->count = 255;
|
||||
string_instance->auxiliary = 0;
|
||||
string_instance->id = 287;
|
||||
filling_container->addItem(string_instance);
|
||||
|
||||
ItemInstance *feather_instance = new ItemInstance;
|
||||
feather_instance->count = 255;
|
||||
feather_instance->auxiliary = 0;
|
||||
feather_instance->id = 288;
|
||||
filling_container->addItem(feather_instance);
|
||||
|
||||
ItemInstance *gunpowder_instance = new ItemInstance;
|
||||
gunpowder_instance->count = 255;
|
||||
gunpowder_instance->auxiliary = 0;
|
||||
gunpowder_instance->id = 289;
|
||||
filling_container->addItem(gunpowder_instance);
|
||||
|
||||
ItemInstance *woodHoe_instance = new ItemInstance;
|
||||
woodHoe_instance->count = 255;
|
||||
woodHoe_instance->auxiliary = 0;
|
||||
woodHoe_instance->id = 290;
|
||||
filling_container->addItem(woodHoe_instance);
|
||||
|
||||
ItemInstance *stoneHoe_instance = new ItemInstance;
|
||||
stoneHoe_instance->count = 255;
|
||||
stoneHoe_instance->auxiliary = 0;
|
||||
stoneHoe_instance->id = 291;
|
||||
filling_container->addItem(stoneHoe_instance);
|
||||
|
||||
ItemInstance *flint1_instance = new ItemInstance;
|
||||
flint1_instance->count = 255;
|
||||
flint1_instance->auxiliary = 0;
|
||||
flint1_instance->id = 292;
|
||||
filling_container->addItem(flint1_instance);
|
||||
|
||||
ItemInstance *diamondHoe_instance = new ItemInstance;
|
||||
diamondHoe_instance->count = 255;
|
||||
diamondHoe_instance->auxiliary = 0;
|
||||
diamondHoe_instance->id = 293;
|
||||
filling_container->addItem(diamondHoe_instance);
|
||||
|
||||
ItemInstance *goldHoe_instance = new ItemInstance;
|
||||
goldHoe_instance->count = 255;
|
||||
goldHoe_instance->auxiliary = 0;
|
||||
goldHoe_instance->id = 294;
|
||||
filling_container->addItem(goldHoe_instance);
|
||||
|
||||
ItemInstance *seeds_instance = new ItemInstance;
|
||||
seeds_instance->count = 255;
|
||||
seeds_instance->auxiliary = 0;
|
||||
seeds_instance->id = 295;
|
||||
filling_container->addItem(seeds_instance);
|
||||
|
||||
ItemInstance *wheat_instance = new ItemInstance;
|
||||
wheat_instance->count = 255;
|
||||
wheat_instance->auxiliary = 0;
|
||||
wheat_instance->id = 296;
|
||||
filling_container->addItem(wheat_instance);
|
||||
|
||||
ItemInstance *bread_instance = new ItemInstance;
|
||||
bread_instance->count = 255;
|
||||
bread_instance->auxiliary = 0;
|
||||
bread_instance->id = 297;
|
||||
filling_container->addItem(bread_instance);
|
||||
|
||||
ItemInstance *diamondHelm_instance = new ItemInstance;
|
||||
diamondHelm_instance->count = 255;
|
||||
diamondHelm_instance->auxiliary = 0;
|
||||
diamondHelm_instance->id = 310;
|
||||
filling_container->addItem(diamondHelm_instance);
|
||||
|
||||
ItemInstance *diamondChest_instance = new ItemInstance;
|
||||
diamondChest_instance->count = 255;
|
||||
diamondChest_instance->auxiliary = 0;
|
||||
diamondChest_instance->id = 311;
|
||||
filling_container->addItem(diamondChest_instance);
|
||||
|
||||
ItemInstance *diamondLeg_instance = new ItemInstance;
|
||||
diamondLeg_instance->count = 255;
|
||||
diamondLeg_instance->auxiliary = 0;
|
||||
diamondLeg_instance->id = 312;
|
||||
filling_container->addItem(diamondLeg_instance);
|
||||
|
||||
ItemInstance *diamondBoot_instance = new ItemInstance;
|
||||
diamondBoot_instance->count = 255;
|
||||
diamondBoot_instance->auxiliary = 0;
|
||||
diamondBoot_instance->id = 313;
|
||||
filling_container->addItem(diamondBoot_instance);
|
||||
|
||||
ItemInstance *leatherCap_instance = new ItemInstance;
|
||||
leatherCap_instance->count = 255;
|
||||
leatherCap_instance->auxiliary = 0;
|
||||
leatherCap_instance->id = 298;
|
||||
filling_container->addItem(leatherCap_instance);
|
||||
|
||||
ItemInstance *leatherShirt_instance = new ItemInstance;
|
||||
leatherShirt_instance->count = 255;
|
||||
leatherShirt_instance->auxiliary = 0;
|
||||
leatherShirt_instance->id = 299;
|
||||
filling_container->addItem(leatherShirt_instance);
|
||||
|
||||
ItemInstance *leatherPants_instance = new ItemInstance;
|
||||
leatherPants_instance->count = 255;
|
||||
leatherPants_instance->auxiliary = 0;
|
||||
leatherPants_instance->id = 300;
|
||||
filling_container->addItem(leatherPants_instance);
|
||||
|
||||
ItemInstance *leatherBoots_instance = new ItemInstance;
|
||||
leatherBoots_instance->count = 255;
|
||||
leatherBoots_instance->auxiliary = 0;
|
||||
leatherBoots_instance->id = 301;
|
||||
filling_container->addItem(leatherBoots_instance);
|
||||
|
||||
ItemInstance *chainHelm_instance = new ItemInstance;
|
||||
chainHelm_instance->count = 255;
|
||||
chainHelm_instance->auxiliary = 0;
|
||||
chainHelm_instance->id = 302;
|
||||
filling_container->addItem(chainHelm_instance);
|
||||
|
||||
ItemInstance *chainShirt_instance = new ItemInstance;
|
||||
chainShirt_instance->count = 255;
|
||||
chainShirt_instance->auxiliary = 0;
|
||||
chainShirt_instance->id = 303;
|
||||
filling_container->addItem(chainShirt_instance);
|
||||
|
||||
ItemInstance *chainLegs_instance = new ItemInstance;
|
||||
chainLegs_instance->count = 255;
|
||||
chainLegs_instance->auxiliary = 0;
|
||||
chainLegs_instance->id = 304;
|
||||
filling_container->addItem(chainLegs_instance);
|
||||
|
||||
ItemInstance *chainBoots_instance = new ItemInstance;
|
||||
chainBoots_instance->count = 255;
|
||||
chainBoots_instance->auxiliary = 0;
|
||||
chainBoots_instance->id = 305;
|
||||
filling_container->addItem(chainBoots_instance);
|
||||
|
||||
ItemInstance *goldHelm_instance = new ItemInstance;
|
||||
goldHelm_instance->count = 255;
|
||||
goldHelm_instance->auxiliary = 0;
|
||||
goldHelm_instance->id = 314;
|
||||
filling_container->addItem(goldHelm_instance);
|
||||
|
||||
ItemInstance *goldChest_instance = new ItemInstance;
|
||||
goldChest_instance->count = 255;
|
||||
goldChest_instance->auxiliary = 0;
|
||||
goldChest_instance->id = 315;
|
||||
filling_container->addItem(goldChest_instance);
|
||||
|
||||
ItemInstance *goldLegs_instance = new ItemInstance;
|
||||
goldLegs_instance->count = 255;
|
||||
goldLegs_instance->auxiliary = 0;
|
||||
goldLegs_instance->id = 316;
|
||||
filling_container->addItem(goldLegs_instance);
|
||||
|
||||
ItemInstance *goldBoots_instance = new ItemInstance;
|
||||
goldBoots_instance->count = 255;
|
||||
goldBoots_instance->auxiliary = 0;
|
||||
goldBoots_instance->id = 317;
|
||||
filling_container->addItem(goldBoots_instance);
|
||||
|
||||
ItemInstance *ironHelm_instance = new ItemInstance;
|
||||
ironHelm_instance->count = 255;
|
||||
ironHelm_instance->auxiliary = 0;
|
||||
ironHelm_instance->id = 306;
|
||||
filling_container->addItem(ironHelm_instance);
|
||||
|
||||
ItemInstance *ironChest_instance = new ItemInstance;
|
||||
ironChest_instance->count = 255;
|
||||
ironChest_instance->auxiliary = 0;
|
||||
ironChest_instance->id = 307;
|
||||
filling_container->addItem(ironChest_instance);
|
||||
|
||||
ItemInstance *ironLegs_instance = new ItemInstance;
|
||||
ironLegs_instance->count = 255;
|
||||
ironLegs_instance->auxiliary = 0;
|
||||
ironLegs_instance->id = 308;
|
||||
filling_container->addItem(ironLegs_instance);
|
||||
|
||||
ItemInstance *ironBoots_instance = new ItemInstance;
|
||||
ironBoots_instance->count = 255;
|
||||
ironBoots_instance->auxiliary = 0;
|
||||
ironBoots_instance->id = 309;
|
||||
filling_container->addItem(ironBoots_instance);
|
||||
|
||||
ItemInstance *flint2_instance = new ItemInstance;
|
||||
flint2_instance->count = 255;
|
||||
flint2_instance->auxiliary = 0;
|
||||
flint2_instance->id = 318;
|
||||
filling_container->addItem(flint2_instance);
|
||||
|
||||
ItemInstance *porkRaw_instance = new ItemInstance;
|
||||
porkRaw_instance->count = 255;
|
||||
porkRaw_instance->auxiliary = 0;
|
||||
porkRaw_instance->id = 319;
|
||||
filling_container->addItem(porkRaw_instance);
|
||||
|
||||
ItemInstance *leather_instance = new ItemInstance;
|
||||
leather_instance->count = 255;
|
||||
leather_instance->auxiliary = 0;
|
||||
leather_instance->id = 334;
|
||||
filling_container->addItem(leather_instance);
|
||||
|
||||
ItemInstance *clayBrick_instance = new ItemInstance;
|
||||
clayBrick_instance->count = 255;
|
||||
clayBrick_instance->auxiliary = 0;
|
||||
clayBrick_instance->id = 336;
|
||||
filling_container->addItem(clayBrick_instance);
|
||||
|
||||
ItemInstance *clay_instance = new ItemInstance;
|
||||
clay_instance->count = 255;
|
||||
clay_instance->auxiliary = 0;
|
||||
clay_instance->id = 337;
|
||||
filling_container->addItem(clay_instance);
|
||||
|
||||
ItemInstance *notepad_instance = new ItemInstance;
|
||||
notepad_instance->count = 255;
|
||||
notepad_instance->auxiliary = 0;
|
||||
notepad_instance->id = 339;
|
||||
filling_container->addItem(notepad_instance);
|
||||
|
||||
ItemInstance *book_instance = new ItemInstance;
|
||||
book_instance->count = 255;
|
||||
book_instance->auxiliary = 0;
|
||||
book_instance->id = 340;
|
||||
filling_container->addItem(book_instance);
|
||||
|
||||
ItemInstance *slimeball_instance = new ItemInstance;
|
||||
slimeball_instance->count = 255;
|
||||
slimeball_instance->auxiliary = 0;
|
||||
slimeball_instance->id = 341;
|
||||
filling_container->addItem(slimeball_instance);
|
||||
|
||||
ItemInstance *compass_instance = new ItemInstance;
|
||||
compass_instance->count = 255;
|
||||
compass_instance->auxiliary = 0;
|
||||
compass_instance->id = 345;
|
||||
filling_container->addItem(compass_instance);
|
||||
|
||||
ItemInstance *clock_instance = new ItemInstance;
|
||||
clock_instance->count = 255;
|
||||
clock_instance->auxiliary = 0;
|
||||
clock_instance->id = 347;
|
||||
filling_container->addItem(clock_instance);
|
||||
|
||||
ItemInstance *glowDust_instance = new ItemInstance;
|
||||
glowDust_instance->count = 255;
|
||||
glowDust_instance->auxiliary = 0;
|
||||
glowDust_instance->id = 348;
|
||||
filling_container->addItem(glowDust_instance);
|
||||
|
||||
ItemInstance *bone_instance = new ItemInstance;
|
||||
bone_instance->count = 255;
|
||||
bone_instance->auxiliary = 0;
|
||||
bone_instance->id = 352;
|
||||
filling_container->addItem(bone_instance);
|
||||
|
||||
ItemInstance *sugar_instance = new ItemInstance;
|
||||
sugar_instance->count = 255;
|
||||
sugar_instance->auxiliary = 0;
|
||||
sugar_instance->id = 353;
|
||||
filling_container->addItem(sugar_instance);
|
||||
|
||||
ItemInstance *melon_instance = new ItemInstance;
|
||||
melon_instance->count = 255;
|
||||
melon_instance->auxiliary = 0;
|
||||
melon_instance->id = 360;
|
||||
filling_container->addItem(melon_instance);
|
||||
|
||||
ItemInstance *beefRaw_instance = new ItemInstance;
|
||||
beefRaw_instance->count = 255;
|
||||
beefRaw_instance->auxiliary = 0;
|
||||
beefRaw_instance->id = 363;
|
||||
filling_container->addItem(beefRaw_instance);
|
||||
|
||||
ItemInstance *chickenRaw_instance = new ItemInstance;
|
||||
chickenRaw_instance->count = 255;
|
||||
chickenRaw_instance->auxiliary = 0;
|
||||
chickenRaw_instance->id = 365;
|
||||
filling_container->addItem(chickenRaw_instance);
|
||||
}
|
||||
|
||||
// Init
|
||||
__attribute__((constructor)) static void init_expanded_creative() {
|
||||
INFO("Loading Expanded Creative Mod");
|
||||
misc_run_on_creative_inventory_setup(Inventory_setupDefault_FillingContainer_addItem_call_injection);
|
||||
}
|
15
example-mods/recipes/.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/out
|
||||
/debian/tmp
|
||||
/.vscode
|
||||
/build*
|
||||
/CMakeLists.txt.user
|
||||
*.autosave
|
||||
/AppImageBuilder.yml
|
||||
/appimage-builder-cache
|
||||
/appimage-build
|
||||
/AppDir
|
||||
/*.zsync
|
||||
/*.AppImage
|
||||
/core*
|
||||
/qemu_*
|
||||
/cmake/.prebuilt-armhf-toolchain
|
17
example-mods/recipes/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
|
||||
# Build For ARM
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
||||
set(CMAKE_SYSTEM_NAME "Linux")
|
||||
set(CMAKE_SYSTEM_PROCESSOR "arm")
|
||||
|
||||
# Start Project
|
||||
project(recipes)
|
||||
|
||||
# Include SDK
|
||||
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn/sdk/sdk.cmake")
|
||||
|
||||
# Build
|
||||
add_library(recipes SHARED recipes.cpp)
|
||||
target_link_libraries(recipes mods reborn-util symbols)
|
65
example-mods/recipes/recipes.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
#include <libreborn/patch.h>
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
// Custom Crafting Recipes
|
||||
#define SAND 12
|
||||
static void Recipes_injection(Recipes *recipes) {
|
||||
// Add
|
||||
Recipes_Type type1 = {
|
||||
.item = 0,
|
||||
.tile = 0,
|
||||
.instance = {
|
||||
.count = 1,
|
||||
.id = SAND,
|
||||
.auxiliary = 0
|
||||
},
|
||||
.letter = 'a'
|
||||
};
|
||||
Recipes_Type type2 = {
|
||||
.item = 0,
|
||||
.tile = 0,
|
||||
.instance = {
|
||||
.count = 1,
|
||||
.id = 13,
|
||||
.auxiliary = 0
|
||||
},
|
||||
.letter = 'b'
|
||||
};
|
||||
ItemInstance result = {
|
||||
.count = 1,
|
||||
.id = 344,
|
||||
.auxiliary = 0
|
||||
};
|
||||
std::vector<Recipes_Type> types = {type1, type2};
|
||||
recipes->addShapelessRecipe(result, types);
|
||||
}
|
||||
|
||||
// Custom Furnace Recipes
|
||||
static void FurnaceRecipes_injection(FurnaceRecipes *recipes) {
|
||||
// Add
|
||||
ItemInstance result = {
|
||||
.count = 1,
|
||||
.id = 246,
|
||||
.auxiliary = 0
|
||||
};
|
||||
recipes->addFurnaceRecipe(49, result);
|
||||
}
|
||||
|
||||
// Init
|
||||
__attribute__((constructor)) static void init_recipes() {
|
||||
// Log
|
||||
INFO("Loading Custom Recipes");
|
||||
|
||||
// Setup
|
||||
misc_run_on_recipes_setup(Recipes_injection);
|
||||
misc_run_on_furnace_recipes_setup(FurnaceRecipes_injection);
|
||||
|
||||
// Recipe Remainder
|
||||
overwrite_calls(Minecraft_init, [](Minecraft_init_t original, Minecraft *self) {
|
||||
original(self);
|
||||
Item::items[SAND]->craftingRemainingItem = Item::snowball;
|
||||
});
|
||||
}
|
38
images/CMakeLists.txt
Normal file
@ -0,0 +1,38 @@
|
||||
project(images)
|
||||
|
||||
# Logo
|
||||
install(
|
||||
FILES "modern_logo.png"
|
||||
DESTINATION "${MCPI_INSTALL_DIR}/data/images/gui"
|
||||
)
|
||||
|
||||
# Title Background
|
||||
install(
|
||||
FILES "background.png"
|
||||
DESTINATION "${MCPI_INSTALL_DIR}/data/images/gui"
|
||||
RENAME "titleBG.png"
|
||||
)
|
||||
|
||||
# Mojang Textures
|
||||
install(
|
||||
FILES "mojang/chest.png"
|
||||
DESTINATION "${MCPI_INSTALL_DIR}/data/images/item"
|
||||
)
|
||||
install(
|
||||
FILES "mojang/shadow.png" "mojang/vignette.png" "mojang/grasscolor.png"
|
||||
DESTINATION "${MCPI_INSTALL_DIR}/data/images/misc"
|
||||
)
|
||||
|
||||
# Icon
|
||||
set(ICON_DIR "${MCPI_SHARE_DIR}/icons/hicolor/512x512/apps")
|
||||
install(
|
||||
FILES "icon.png"
|
||||
DESTINATION "${ICON_DIR}"
|
||||
RENAME "${MCPI_APP_ID}.png"
|
||||
)
|
||||
|
||||
# AppImage
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
install_symlink("${ICON_DIR}/${MCPI_APP_ID}.png" "${MCPI_APP_ID}.png")
|
||||
install_symlink("${MCPI_APP_ID}.png" ".DirIcon")
|
||||
endif()
|
BIN
images/background.png
Normal file
After Width: | Height: | Size: 139 KiB |
BIN
images/icon.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
images/modern_logo.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
images/mojang/chest.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
images/mojang/grasscolor.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
images/mojang/shadow.png
Normal file
After Width: | Height: | Size: 868 B |
BIN
images/mojang/vignette.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
images/start.png
Normal file
After Width: | Height: | Size: 133 KiB |
123
launcher/CMakeLists.txt
Normal file
@ -0,0 +1,123 @@
|
||||
project(launcher)
|
||||
|
||||
# Launcher
|
||||
add_executable(launcher
|
||||
src/bootstrap/bootstrap.cpp
|
||||
src/bootstrap/mods.cpp
|
||||
src/bootstrap/assets.cpp
|
||||
src/bootstrap/patchelf.cpp
|
||||
src/bootstrap/debug.cpp
|
||||
src/util/util.cpp
|
||||
src/util/sdk.cpp
|
||||
src/util/env.cpp
|
||||
src/logger/logger.cpp
|
||||
src/logger/crash-report.cpp
|
||||
src/options/parser.cpp
|
||||
src/main.cpp
|
||||
src/ui/frame.cpp
|
||||
src/ui/color.cpp
|
||||
src/client/configuration.cpp
|
||||
src/client/cache.cpp
|
||||
src/client/ui.cpp
|
||||
src/updater/updater.cpp
|
||||
)
|
||||
target_link_libraries(launcher
|
||||
reborn-util
|
||||
LIB_LIEF
|
||||
imgui
|
||||
trampoline-headers
|
||||
pthread
|
||||
)
|
||||
# RPath
|
||||
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
|
||||
target_link_options(launcher PRIVATE "LINKER:--disable-new-dtags")
|
||||
# Files
|
||||
target_compile_definitions(launcher PRIVATE _FILE_OFFSET_BITS=64)
|
||||
|
||||
# Install
|
||||
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")
|
||||
install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_APP_NAME}")
|
||||
|
||||
# Install Desktop Entry
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
|
||||
"[Desktop Entry]\n"
|
||||
"Name=${MCPI_APP_TITLE}\n"
|
||||
"Comment=Fun with Blocks\n"
|
||||
"Icon=${MCPI_APP_ID}\n"
|
||||
"Exec=${MCPI_APP_NAME}\n"
|
||||
"Type=Application\n"
|
||||
"Categories=Game;\n"
|
||||
"Terminal=false\n"
|
||||
"StartupNotify=false\n"
|
||||
"StartupWMClass=${MCPI_APP_ID}\n"
|
||||
)
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
|
||||
DESTINATION "${MCPI_SHARE_DIR}/applications"
|
||||
RENAME "${MCPI_APP_ID}.desktop"
|
||||
)
|
||||
|
||||
# Install AppStream Metadata
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<component type=\"desktop\">\n"
|
||||
" <id>${MCPI_APP_ID}</id>\n"
|
||||
" <name>${MCPI_APP_TITLE}</name>\n"
|
||||
" <metadata_license>CC0-1.0</metadata_license>\n"
|
||||
" <summary>Fun with Blocks</summary>\n"
|
||||
" <description>\n"
|
||||
" <p>Minecraft: Pi Edition Modding Project.</p>\n"
|
||||
" <p>NOTE: This is not verified by, affiliated with, or supported by Mojang or Microsoft.</p>\n"
|
||||
" </description>\n"
|
||||
" <url type=\"homepage\">${MCPI_REPO}</url>\n"
|
||||
" <launchable type=\"desktop-id\">${MCPI_APP_ID}.desktop</launchable>\n"
|
||||
" <provides>\n"
|
||||
" <id>${MCPI_APP_ID}.desktop</id>\n"
|
||||
" </provides>\n"
|
||||
" <project_license>LicenseRef-proprietary</project_license>\n"
|
||||
" <developer_name>${MCPI_AUTHOR} & Mojang AB</developer_name>\n"
|
||||
" <content_rating type=\"oars-1.0\">\n"
|
||||
" <content_attribute id=\"violence-cartoon\">moderate</content_attribute>\n"
|
||||
" <content_attribute id=\"violence-fantasy\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"violence-realistic\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"violence-bloodshed\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"violence-sexual\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"drugs-alcohol\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"drugs-narcotics\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"drugs-tobacco\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"sex-nudity\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"sex-themes\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"language-profanity\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"language-humor\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"language-discrimination\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"social-chat\">intense</content_attribute>\n"
|
||||
" <content_attribute id=\"social-info\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"social-audio\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"social-location\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"social-contacts\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"money-purchasing\">none</content_attribute>\n"
|
||||
" <content_attribute id=\"money-gambling\">none</content_attribute>\n"
|
||||
" </content_rating>\n"
|
||||
" <releases>\n"
|
||||
" <release version=\"${MCPI_VERSION}\" date=\"${MCPI_VERSION_DATE}\"></release>\n"
|
||||
" </releases>\n"
|
||||
" <screenshots>\n"
|
||||
" <screenshot type=\"default\">\n"
|
||||
" <image>${MCPI_REPO}/raw/branch/master/images/start.png</image>\n"
|
||||
" </screenshot>\n"
|
||||
" </screenshots>\n"
|
||||
"</component>\n"
|
||||
)
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
|
||||
DESTINATION "${MCPI_SHARE_DIR}/metainfo"
|
||||
RENAME "${MCPI_APP_ID}.appdata.xml"
|
||||
)
|
||||
|
||||
# AppImage
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
install_symlink("bin/${MCPI_APP_NAME}" "AppRun")
|
||||
install_symlink("${MCPI_SHARE_DIR}/applications/${MCPI_APP_ID}.desktop" "${MCPI_APP_ID}.desktop")
|
||||
# Updater
|
||||
target_sources(launcher PRIVATE src/updater/appimage.cpp)
|
||||
endif()
|
15
launcher/src/bootstrap/assets.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include <libreborn/env/env.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
#include "../util/util.h"
|
||||
|
||||
// Setup Asset Paths
|
||||
static void setup_path(const char *env_name, std::string assets_path) {
|
||||
chop_last_component(assets_path);
|
||||
assets_path += "/data";
|
||||
set_and_print_env(env_name, assets_path.c_str());
|
||||
}
|
||||
void bootstrap_assets(const std::string &original_game_binary) {
|
||||
setup_path(_MCPI_REBORN_ASSETS_PATH_ENV, safe_realpath("/proc/self/exe"));
|
||||
setup_path(_MCPI_VANILLA_ASSETS_PATH_ENV, original_game_binary);
|
||||
}
|
78
launcher/src/bootstrap/bootstrap.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/env/env.h>
|
||||
#include <libreborn/config.h>
|
||||
#include <libreborn/util/exec.h>
|
||||
|
||||
#include "../util/util.h"
|
||||
#include "bootstrap.h"
|
||||
|
||||
#define MCPI_BINARY "minecraft-pi"
|
||||
|
||||
#define REQUIRED_PAGE_SIZE 4096
|
||||
|
||||
// Bootstrap
|
||||
void bootstrap(const options_t &options) {
|
||||
// Debug Information
|
||||
print_debug_information();
|
||||
|
||||
// Check Page Size
|
||||
const long page_size = sysconf(_SC_PAGESIZE);
|
||||
if (page_size != REQUIRED_PAGE_SIZE) {
|
||||
CONDITIONAL_ERR(!options.skip_pagesize_check, "Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
|
||||
}
|
||||
|
||||
// Get Binary Directory
|
||||
const std::string binary_directory = get_binary_directory();
|
||||
DEBUG("Binary Directory: %s", binary_directory.c_str());
|
||||
|
||||
// Copy SDK
|
||||
if (!reborn_is_server()) {
|
||||
copy_sdk(binary_directory, false);
|
||||
}
|
||||
|
||||
// Resolve Binary Path
|
||||
DEBUG("Resolving File Paths...");
|
||||
std::string original_game_binary = binary_directory + ("/" MCPI_BINARY);
|
||||
original_game_binary = safe_realpath(original_game_binary);
|
||||
const char *custom_binary = getenv(MCPI_BINARY_ENV);
|
||||
const std::string game_binary = custom_binary ? safe_realpath(custom_binary) : original_game_binary;
|
||||
|
||||
// Configure Preloaded Objects
|
||||
DEBUG("Locating Mods...");
|
||||
const std::vector<std::string> mcpi_ld_preload = bootstrap_mods(binary_directory);
|
||||
|
||||
// Configure Library Search Path
|
||||
DEBUG("Setting Linker Search Paths...");
|
||||
const std::vector<std::string> mcpi_ld_path = get_ld_path(binary_directory);
|
||||
|
||||
// Assets
|
||||
DEBUG("Finding Assets...");
|
||||
bootstrap_assets(original_game_binary);
|
||||
|
||||
// Patch Binary
|
||||
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
|
||||
DEBUG("Patching ELF...");
|
||||
patch_mcpi_elf_dependencies(game_binary, new_mcpi_exe_path, get_new_linker(binary_directory), mcpi_ld_path, mcpi_ld_preload);
|
||||
|
||||
// Start Game
|
||||
INFO("Starting Game...");
|
||||
|
||||
// Arguments
|
||||
const std::vector<std::string> args {
|
||||
#ifdef MCPI_BUILD_RUNTIME
|
||||
"runtime",
|
||||
#endif
|
||||
new_mcpi_exe_path
|
||||
};
|
||||
|
||||
// Run
|
||||
const char *new_argv[args.size() + 1];
|
||||
for (std::vector<std::string>::size_type i = 0; i < args.size(); i++) {
|
||||
new_argv[i] = args[i].c_str();
|
||||
}
|
||||
new_argv[args.size()] = nullptr;
|
||||
safe_execvpe(new_argv, environ);
|
||||
}
|
20
launcher/src/bootstrap/bootstrap.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../options/parser.h"
|
||||
|
||||
#define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched"
|
||||
|
||||
void bootstrap(const options_t &options);
|
||||
// Debugging
|
||||
void print_debug_information();
|
||||
// Mods
|
||||
std::vector<std::string> bootstrap_mods(const std::string &binary_directory);
|
||||
// Assets
|
||||
void bootstrap_assets(const std::string &original_game_binary);
|
||||
// ELF
|
||||
std::string get_new_linker(const std::string &binary_directory);
|
||||
std::vector<std::string> get_ld_path(const std::string &binary_directory);
|
||||
void patch_mcpi_elf_dependencies(const std::string &original_path, char *new_path, const std::string &interpreter, const std::vector<std::string> &rpath, const std::vector<std::string> &mods);
|
38
launcher/src/bootstrap/debug.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/util/exec.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
|
||||
// Debug Information
|
||||
static void run_debug_command(const char *const command[], const char *prefix) {
|
||||
int status = 0;
|
||||
const std::vector<unsigned char> *output = run_command(command, &status);
|
||||
if (!is_exit_status_success(status)) {
|
||||
ERR("Unable To Gather Debug Information");
|
||||
}
|
||||
std::string output_str = (const char *) output->data();
|
||||
delete output;
|
||||
// Trim
|
||||
const std::string::size_type length = output_str.length();
|
||||
if (length > 0 && output_str[length - 1] == '\n') {
|
||||
output_str.pop_back();
|
||||
}
|
||||
// Print
|
||||
DEBUG("%s: %s", prefix, output_str.c_str());
|
||||
}
|
||||
void print_debug_information() {
|
||||
// System Information
|
||||
constexpr const char *const command[] = {"uname", "-a", nullptr};
|
||||
run_debug_command(command, "System Information");
|
||||
|
||||
// Version
|
||||
DEBUG("Reborn Version: v%s", MCPI_VERSION);
|
||||
|
||||
// Architecture
|
||||
std::string arch = MCPI_ARCH;
|
||||
for (char &c : arch) {
|
||||
c = char(std::toupper(c));
|
||||
}
|
||||
DEBUG("Reborn Target Architecture: %s", arch.c_str());
|
||||
}
|
74
launcher/src/bootstrap/mods.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include <dirent.h>
|
||||
#include <cerrno>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/util/util.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
#include "../util/util.h"
|
||||
|
||||
// Get All Mods In Folder
|
||||
static void load(std::vector<std::string> &ld_preload, const std::string &folder, int recursion_limit = 128);
|
||||
static void handle_file(std::vector<std::string> &ld_preload, const std::string &file, const int recursion_limit) {
|
||||
// Check Type
|
||||
struct stat file_stat = {};
|
||||
lstat(file.c_str(), &file_stat);
|
||||
if (S_ISDIR(file_stat.st_mode)) {
|
||||
// Recurse Into Directory
|
||||
load(ld_preload, std::string(file) + '/', recursion_limit - 1);
|
||||
} else if (S_ISLNK(file_stat.st_mode)) {
|
||||
// Resolve Symlink
|
||||
const std::string resolved_file = safe_realpath(file);
|
||||
handle_file(ld_preload, resolved_file, recursion_limit);
|
||||
} else if (S_ISREG(file_stat.st_mode)) {
|
||||
// Check If File Is Accessible
|
||||
const int result = access(file.c_str(), R_OK);
|
||||
if (result == 0) {
|
||||
// Add To LD_PRELOAD
|
||||
DEBUG("Found Mod: %s", file.c_str());
|
||||
ld_preload.push_back(file);
|
||||
} else if (result == -1 && errno != 0) {
|
||||
// Fail
|
||||
WARN("Unable To Access: %s: %s", file.c_str(), strerror(errno));
|
||||
errno = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void load(std::vector<std::string> &ld_preload, const std::string &folder, const int recursion_limit) {
|
||||
// Check Recursion
|
||||
if (recursion_limit <= 0) {
|
||||
ERR("Reached Recursion Limit While Loading Mods");
|
||||
}
|
||||
// Make Directory
|
||||
ensure_directory(folder.c_str());
|
||||
// Read
|
||||
read_directory(folder, [&folder, &ld_preload, &recursion_limit](const dirent *entry) {
|
||||
// Get Full Name
|
||||
const std::string name = folder + entry->d_name;
|
||||
// Handle
|
||||
handle_file(ld_preload, name, recursion_limit);
|
||||
});
|
||||
}
|
||||
|
||||
// Bootstrap Mods
|
||||
#define SUBDIRECTORY_FOR_MODS "/mods/"
|
||||
std::vector<std::string> bootstrap_mods(const std::string &binary_directory) {
|
||||
// Prepare
|
||||
std::vector<std::string> preload;
|
||||
|
||||
// Load
|
||||
const std::vector folders = {
|
||||
home_get(),
|
||||
binary_directory
|
||||
};
|
||||
for (std::string mods_folder : folders) {
|
||||
mods_folder += SUBDIRECTORY_FOR_MODS;
|
||||
load(preload, mods_folder);
|
||||
}
|
||||
|
||||
// Return
|
||||
return preload;
|
||||
}
|
125
launcher/src/bootstrap/patchelf.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
#include <cstdlib>
|
||||
#include <sys/stat.h>
|
||||
#include <ranges>
|
||||
|
||||
#include <LIEF/ELF.hpp>
|
||||
|
||||
#include <libreborn/util/util.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
|
||||
// Duplicate MCPI Executable Into /tmp
|
||||
static void duplicate_mcpi_executable(char *new_path) {
|
||||
// Ensure Temporary Directory
|
||||
ensure_directory(MCPI_PATCHED_DIR);
|
||||
|
||||
// Generate New File
|
||||
const int new_file_fd = mkstemp(new_path);
|
||||
if (new_file_fd == -1) {
|
||||
ERR("Unable To Create Temporary File: %s", strerror(errno));
|
||||
}
|
||||
close(new_file_fd);
|
||||
}
|
||||
|
||||
// Fix MCPI Dependencies
|
||||
static std::vector<std::string> needed_libraries = {
|
||||
"libmedia-layer-core.so",
|
||||
"libpng12.so.0",
|
||||
"libstdc++.so.6",
|
||||
"libm.so.6",
|
||||
"libgcc_s.so.1",
|
||||
"libc.so.6",
|
||||
"libpthread.so.0"
|
||||
};
|
||||
static std::vector<std::string> function_prefixes_to_patch = {
|
||||
"SDL_",
|
||||
"gl"
|
||||
};
|
||||
void patch_mcpi_elf_dependencies(const std::string &original_path, char *new_path, const std::string &interpreter, const std::vector<std::string> &rpath, const std::vector<std::string> &mods) {
|
||||
// Duplicate MCPI executable into /tmp so it can be modified.
|
||||
duplicate_mcpi_executable(new_path);
|
||||
|
||||
// Load Binary
|
||||
const std::unique_ptr<LIEF::ELF::Binary> binary = LIEF::ELF::Parser::parse(original_path);
|
||||
|
||||
// Set Interpreter
|
||||
binary->interpreter(interpreter);
|
||||
|
||||
// Remove Existing Needed Libraries
|
||||
std::vector<std::string> to_remove;
|
||||
for (const LIEF::ELF::DynamicEntry &entry : binary->dynamic_entries()) {
|
||||
const LIEF::ELF::DynamicEntryLibrary *library = dynamic_cast<const LIEF::ELF::DynamicEntryLibrary *>(&entry);
|
||||
if (library) {
|
||||
to_remove.push_back(library->name());
|
||||
}
|
||||
}
|
||||
for (const std::string &library : to_remove) {
|
||||
binary->remove_library(library);
|
||||
}
|
||||
|
||||
// Setup RPath
|
||||
binary->add(LIEF::ELF::DynamicEntryRpath(rpath));
|
||||
|
||||
// Add Libraries
|
||||
std::vector<std::string> all_libraries;
|
||||
for (const std::vector<std::string> &list : {mods, needed_libraries}) {
|
||||
all_libraries.insert(all_libraries.end(), list.begin(), list.end());
|
||||
}
|
||||
for (const std::string &library : all_libraries | std::views::reverse) {
|
||||
binary->add_library(library);
|
||||
}
|
||||
|
||||
// Fix Symbol Names
|
||||
for (LIEF::ELF::Symbol &symbol : binary->dynamic_symbols()) {
|
||||
if (symbol.is_function()) {
|
||||
for (const std::string &prefix : function_prefixes_to_patch) {
|
||||
if (symbol.name().rfind(prefix, 0) == 0) {
|
||||
symbol.name("media_" + symbol.name());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write Binary
|
||||
LIEF::ELF::Builder builder{*binary};
|
||||
builder.build();
|
||||
builder.write(new_path);
|
||||
|
||||
// Fix Permissions
|
||||
if (chmod(new_path, S_IRUSR | S_IXUSR) != 0) {
|
||||
ERR("Unable To Set File Permissions: %s: %s", new_path, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
// Linker
|
||||
std::string get_new_linker(const std::string &binary_directory) {
|
||||
std::string linker = "/lib/ld-linux-armhf.so.3";
|
||||
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
||||
linker = binary_directory + "/sysroot" + linker;
|
||||
#else
|
||||
(void) binary_directory;
|
||||
#endif
|
||||
return linker;
|
||||
}
|
||||
std::vector<std::string> get_ld_path(const std::string &binary_directory) {
|
||||
std::vector<std::string> mcpi_ld_path = {
|
||||
// ARM Sysroot
|
||||
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
||||
"sysroot/lib",
|
||||
"sysroot/lib/arm-linux-gnueabihf",
|
||||
"sysroot/usr/lib",
|
||||
"sysroot/usr/lib/arm-linux-gnueabihf",
|
||||
#endif
|
||||
// Libraries
|
||||
"lib/arm"
|
||||
};
|
||||
// Fix Paths
|
||||
for (std::string &path : mcpi_ld_path) {
|
||||
path.insert(0, 1, '/');
|
||||
path.insert(0, binary_directory);
|
||||
}
|
||||
// Return
|
||||
return mcpi_ld_path;
|
||||
}
|
178
launcher/src/client/cache.cpp
Normal file
@ -0,0 +1,178 @@
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
#include <sstream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/util/util.h>
|
||||
#include <libreborn/util/io.h>
|
||||
|
||||
#include "cache.h"
|
||||
#include "configuration.h"
|
||||
|
||||
// Get Cache Path
|
||||
static std::string get_cache_path() {
|
||||
return home_get() + "/.launcher-cache";
|
||||
}
|
||||
|
||||
// Load
|
||||
template <typename T>
|
||||
static T simple_read(std::ifstream &stream) {
|
||||
T out;
|
||||
stream.read((char *) &out, sizeof(T));
|
||||
return out;
|
||||
}
|
||||
template <>
|
||||
std::string simple_read<std::string>(std::ifstream &stream) {
|
||||
std::string out;
|
||||
if (!std::getline(stream, out, '\0')) {
|
||||
out = "";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
static void read_cache(std::ifstream &stream, State &ret) {
|
||||
// Cache Version
|
||||
const unsigned char cache_version = simple_read<unsigned char>(stream);
|
||||
if (stream.eof()) {
|
||||
// Unable To Read Version
|
||||
WARN("Unable To Read Launcher Cache Version");
|
||||
return;
|
||||
}
|
||||
|
||||
// Support Older Versions
|
||||
bool load_new_fields = true;
|
||||
if (cache_version == 0) {
|
||||
// Pre-v3.0.0 Cache
|
||||
load_new_fields = false;
|
||||
} else if (cache_version != (unsigned char) CACHE_VERSION) {
|
||||
// Invalid Version
|
||||
WARN("Invalid Launcher Cache Version (Expected: %i, Actual: %i)", CACHE_VERSION, (int) cache_version);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load Username And Render Distance
|
||||
State state;
|
||||
state.username = simple_read<std::string>(stream);
|
||||
state.render_distance = simple_read<std::string>(stream);
|
||||
if (load_new_fields) {
|
||||
state.gui_scale = simple_read<float>(stream);
|
||||
state.servers.load(simple_read<std::string>(stream));
|
||||
}
|
||||
|
||||
// Load Feature Flags
|
||||
std::unordered_map<std::string, bool> flags;
|
||||
while (!stream.eof()) {
|
||||
std::string flag = simple_read<std::string>(stream);
|
||||
flags[flag] = simple_read<bool>(stream);
|
||||
stream.peek();
|
||||
}
|
||||
state.flags.from_cache(flags);
|
||||
|
||||
// Check For Error
|
||||
if (!stream) {
|
||||
WARN("Failure While Loading Launcher Cache");
|
||||
return;
|
||||
}
|
||||
|
||||
// Success
|
||||
ret = state;
|
||||
}
|
||||
State load_cache() {
|
||||
// Log
|
||||
DEBUG("Loading Launcher Cache...");
|
||||
|
||||
// Return Value
|
||||
State ret;
|
||||
|
||||
// Open File
|
||||
std::ifstream stream(get_cache_path(), std::ios::in | std::ios::binary);
|
||||
if (!stream) {
|
||||
// No Warning If File Doesn't Exist
|
||||
if (errno != ENOENT) {
|
||||
WARN("Unable To Open Launcher Cache For Loading");
|
||||
}
|
||||
} else {
|
||||
// Lock File
|
||||
int lock_fd = lock_file(get_cache_path().c_str());
|
||||
|
||||
// Load
|
||||
read_cache(stream, ret);
|
||||
|
||||
// Close
|
||||
stream.close();
|
||||
|
||||
// Unlock File
|
||||
unlock_file(get_cache_path().c_str(), lock_fd);
|
||||
}
|
||||
|
||||
// Return
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Save
|
||||
template <typename T>
|
||||
static void simple_write(std::ostream &stream, const T &val) {
|
||||
stream.write((const char *) &val, sizeof(T));
|
||||
}
|
||||
template <>
|
||||
void simple_write<std::string>(std::ostream &stream, const std::string &val) {
|
||||
stream.write(val.c_str(), int(val.size()) + 1);
|
||||
}
|
||||
void write_cache(std::ostream &stream, const State &state) {
|
||||
// Save Cache Version
|
||||
constexpr unsigned char cache_version = CACHE_VERSION;
|
||||
simple_write(stream, cache_version);
|
||||
|
||||
// Save Username And Render Distance
|
||||
simple_write(stream, state.username);
|
||||
simple_write(stream, state.render_distance);
|
||||
simple_write(stream, state.gui_scale);
|
||||
simple_write(stream, state.servers.to_string());
|
||||
|
||||
// Save Feature Flags
|
||||
const std::unordered_map<std::string, bool> flags_cache = state.flags.to_cache();
|
||||
for (const std::pair<const std::string, bool> &it : flags_cache) {
|
||||
simple_write(stream, it.first);
|
||||
simple_write(stream, it.second);
|
||||
}
|
||||
}
|
||||
void save_cache(const State &state) {
|
||||
// Log
|
||||
DEBUG("Saving Launcher Cache...");
|
||||
|
||||
// Open File
|
||||
std::ofstream stream(get_cache_path(), std::ios::out | std::ios::binary);
|
||||
if (!stream) {
|
||||
// Fail
|
||||
WARN("Unable To Open Launcher Cache For Saving");
|
||||
} else {
|
||||
// Lock File
|
||||
const int lock_fd = lock_file(get_cache_path().c_str());
|
||||
|
||||
// Write
|
||||
write_cache(stream, state);
|
||||
|
||||
// Finish
|
||||
stream.close();
|
||||
if (!stream) {
|
||||
WARN("Failure While Saving Launcher Cache");
|
||||
}
|
||||
|
||||
// Unlock File
|
||||
unlock_file(get_cache_path().c_str(), lock_fd);
|
||||
}
|
||||
}
|
||||
|
||||
// Wipe Cache
|
||||
void wipe_cache() {
|
||||
// Log
|
||||
INFO("Wiping Launcher Cache...");
|
||||
|
||||
// Unlink File
|
||||
const int ret = unlink(get_cache_path().c_str());
|
||||
if (ret != 0 && errno != ENOENT) {
|
||||
WARN("Failure While Wiping Cache: %s", strerror(errno));
|
||||
}
|
||||
}
|
17
launcher/src/client/cache.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
|
||||
// Cache Version
|
||||
#define CACHE_VERSION 1
|
||||
|
||||
// Load Cache
|
||||
struct State;
|
||||
State load_cache();
|
||||
|
||||
// Save Cache
|
||||
void write_cache(std::ostream &stream, const State &state);
|
||||
void save_cache(const State &state);
|
||||
|
||||
// Wipe Cache
|
||||
void wipe_cache();
|
86
launcher/src/client/configuration.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include <sstream>
|
||||
|
||||
#include <libreborn/env/env.h>
|
||||
|
||||
#include "configuration.h"
|
||||
#include "cache.h"
|
||||
|
||||
// State
|
||||
State::State(): flags("") {
|
||||
username = DEFAULT_USERNAME;
|
||||
render_distance = DEFAULT_RENDER_DISTANCE;
|
||||
gui_scale = AUTO_GUI_SCALE;
|
||||
flags = Flags::get();
|
||||
}
|
||||
template <typename T>
|
||||
static void update_from_env(const char *env, T &value, const bool save) {
|
||||
if (save) {
|
||||
set_and_print_env(env, obj_to_env_value(value).c_str());
|
||||
} else {
|
||||
const char *env_value = getenv(env);
|
||||
if (env_value != nullptr) {
|
||||
env_value_to_obj(value, env_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
void State::update(const bool save) {
|
||||
update_from_env(MCPI_FEATURE_FLAGS_ENV, flags, save);
|
||||
update_from_env(MCPI_USERNAME_ENV, username, save);
|
||||
update_from_env(MCPI_RENDER_DISTANCE_ENV, render_distance, save);
|
||||
update_from_env(MCPI_GUI_SCALE_ENV, gui_scale, save);
|
||||
update_from_env(MCPI_SERVER_LIST_ENV, servers, save);
|
||||
}
|
||||
bool State::operator==(const State &other) const {
|
||||
std::ostringstream one;
|
||||
write_cache(one, *this);
|
||||
std::ostringstream two;
|
||||
write_cache(two, other);
|
||||
return one.str() == two.str();
|
||||
}
|
||||
|
||||
// Handle Non-Launch Commands
|
||||
void handle_non_launch_client_only_commands(const options_t &options) {
|
||||
// Print Available Feature Flags
|
||||
if (options.print_available_feature_flags) {
|
||||
const Flags flags = Flags::get();
|
||||
flags.print();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
// Wipe Cache If Needed
|
||||
if (options.wipe_cache) {
|
||||
wipe_cache();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
// Configure Client Options
|
||||
void configure_client(const options_t &options) {
|
||||
// Load Cache
|
||||
State state;
|
||||
bool save_settings = !options.no_cache;
|
||||
if (save_settings) {
|
||||
state = load_cache();
|
||||
}
|
||||
|
||||
// Read From Environment
|
||||
state.update(false);
|
||||
|
||||
// Show UI
|
||||
if (!options.use_default) {
|
||||
ConfigurationUI *ui = new ConfigurationUI(state, save_settings);
|
||||
const int ret = ui->run();
|
||||
delete ui;
|
||||
if (ret <= 0) {
|
||||
// Cancel Launch
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
// Save Cache
|
||||
if (save_settings) {
|
||||
save_cache(state);
|
||||
}
|
||||
|
||||
// Update Environment
|
||||
state.update(true);
|
||||
}
|
60
launcher/src/client/configuration.h
Normal file
@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../options/parser.h"
|
||||
#include "../ui/frame.h"
|
||||
|
||||
#include <libreborn/env/flags.h>
|
||||
#include <libreborn/env/servers.h>
|
||||
|
||||
// Default Configuration
|
||||
#define DEFAULT_USERNAME "StevePi"
|
||||
#define DEFAULT_RENDER_DISTANCE "Short"
|
||||
#define AUTO_GUI_SCALE 0
|
||||
|
||||
// State
|
||||
struct State {
|
||||
State();
|
||||
// Methods
|
||||
void update(bool save);
|
||||
bool operator==(const State &other) const;
|
||||
// Properties
|
||||
std::string username;
|
||||
std::string render_distance;
|
||||
ServerList servers;
|
||||
float gui_scale;
|
||||
Flags flags;
|
||||
};
|
||||
|
||||
// UI
|
||||
struct ConfigurationUI final : Frame {
|
||||
explicit ConfigurationUI(State &state_, bool &save_settings_);
|
||||
int render() override;
|
||||
private:
|
||||
// Bottom Row
|
||||
[[nodiscard]] int get_render_distance_index() const;
|
||||
[[nodiscard]] int draw_bottom() const;
|
||||
// General
|
||||
void draw_main() const;
|
||||
// Advanced
|
||||
void draw_advanced() const;
|
||||
static void draw_category(FlagNode &category);
|
||||
// Server List
|
||||
void draw_servers() const;
|
||||
void draw_server_list() const;
|
||||
// About
|
||||
static void draw_centered_text(const std::string &str);
|
||||
static void draw_links(const std::vector<std::pair<std::string, std::string>> &links);
|
||||
static void draw_about();
|
||||
// State
|
||||
const State original_state;
|
||||
State &state;
|
||||
bool &save_settings;
|
||||
};
|
||||
|
||||
// Handle Non-Launch Commands
|
||||
void handle_non_launch_client_only_commands(const options_t &options);
|
||||
|
||||
// Configure Client Options
|
||||
void configure_client(const options_t &options);
|