Compare commits

..

231 Commits

Author SHA1 Message Date
MrHua269
4347dee5fa Fix java CP 2024-10-06 11:51:31 +08:00
MrHua269
5734e51889 Try fixing folia spector teleportation fix 2024-10-06 11:23:53 +08:00
M2ke4U
f17ba0d315 [ci skip] Updated maven repo 2024-10-01 22:11:17 +08:00
M2ke4U
e6cd6d964a Update maven repo 2024-10-01 22:08:11 +08:00
M2ke4U
758414b5db Updated maven repo link 2024-10-01 21:43:52 +08:00
MrHua269
037b270a71 Add experiment config for command block command execution 2024-08-31 11:05:57 +08:00
MrHua269
a65a515b73 Updated Upstream(Folia) 2024-08-29 20:42:57 +08:00
M2ke4U
b1d297d09d [ci skip]Update README_EN.md 2024-08-12 21:57:30 +08:00
M2ke4U
a93e01d86d [ci skip]Update README.md 2024-08-12 21:56:32 +08:00
MrHua269
e8a4308dfb Synced updates from dev/1.21.1 2024-08-12 21:32:37 +08:00
M2ke4U
60c416d3a9 Use snapshost repo 2024-08-12 19:27:37 +08:00
M2ke4U
78cc493220 Remove gpr registrations 2024-08-12 19:21:37 +08:00
M2ke4U
360ab76f27 Update build_1.20.6.yml 2024-08-12 19:13:56 +08:00
M2ke4U
4e56383c3f Fix environment varible init 2024-08-12 19:05:46 +08:00
M2ke4U
0486f22863 [ci skip]Remove incorrect env init 2024-08-12 19:03:08 +08:00
M2ke4U
4d0250da91 Move publish to script 2024-08-12 18:55:00 +08:00
M2ke4U
cee875b0fd [ci skip]Move publish to script 2024-08-12 18:54:22 +08:00
M2ke4U
564c218c3a Removed github packages 2024-08-12 18:46:33 +08:00
M2ke4U
4616a6706f Removed github packages 2024-08-12 18:46:07 +08:00
M2ke4U
b4330e6a62 Added maven publish back 2024-08-12 18:36:07 +08:00
M2ke4U
d228424df6 Added molia maven repo 2024-08-12 18:30:41 +08:00
MrHua269
9b3a981018 Fix membar can not be stored 2024-07-31 16:20:25 +08:00
ShintoKosei
6614f67647 Update CI 2024-07-30 18:41:34 +08:00
MrHua269
85f3a4a123 FoliaPR Add TPS From Region 2024-07-30 18:01:03 +08:00
ShintoKosei
99e29a0596 Fix Afdian Link 2024-07-30 15:09:00 +08:00
MrHua269
0a0cdb8d54 Added some optimizations 2024-07-29 20:16:25 +08:00
MrHua269
aa49ca63a4 Check null 2024-07-29 17:14:08 +08:00
MrHua269
fefc53dd71 Only run discard checks of projectile chunk-loading optimization on tick regions 2024-07-29 12:09:51 +08:00
MrHua269
0e049306c9 [ci skip]Tidy patches 2024-07-28 18:47:45 +08:00
MrHua269
e991f0b80f Fix incorrect scheduling in POI fixes 2024-07-23 11:39:44 +08:00
MrHua269
4752f00d09 Updated POI fixes 2024-07-17 20:45:13 +08:00
Dreeam
e6027bdfbf Fix sending keepalive packet
7708a4c06f
2024-07-10 06:05:27 +08:00
MrHua269
1f881dd409 Corrected watchdog hook position 2024-07-01 12:25:00 +08:00
MrHua269
be0d1b1bb2 Added YieldJobState fixes to POI fixes 2024-07-01 11:20:13 +08:00
Stabrinai
3fd73145d6 Verify signature only in online-mode 2024-06-30 20:49:45 +08:00
MrHua269
b8963f9862 Try fixing NPE and append missing functions in Watchdog 2024-06-29 22:04:25 +08:00
MrHua269
83a868e3d2 Fix problematic inversions in 0012 2024-06-29 21:46:41 +08:00
MrHua269
9153d07d43 Fix wrong file extension checks 2024-06-28 21:43:19 +08:00
MrHua269
fcf4731fa2 Re-added and rewrote linear region format 2024-06-27 19:45:01 +08:00
MrHua269
0795ae027d Updated Upstream(Folia) 2024-06-20 04:52:40 +00:00
MrHua269
f2a13748e8 Do not teleport Nan entities in large velocity fix 2024-06-16 14:48:54 +00:00
MrHua269
acc31af9f6 Added config for: Pufferfish Reduce entity fluid lookups if no fluids 2024-06-16 11:02:32 +00:00
MrHua269
9121c2ba4e Added a simple membar 2024-06-15 13:01:48 +00:00
MrHua269
0cc6f1cdb3 Added comments for some config 2024-06-15 07:46:05 +00:00
MrHua269
ac1cc484c2 Added comments for some config 2024-06-15 04:17:37 +00:00
MrHua269
b208bcc81f Finish remain renaming and works on membar 2024-06-11 12:44:19 +00:00
M2ke4U
43eda55b88 Move rambar patch to unapplied because it is still in testing stage 2024-06-10 21:13:54 +08:00
MrHua269
e6ee20986b Try fixing folia off region POI accessing issue 2024-06-10 10:51:53 +00:00
MrHua269
46aec00348 Clean patches 2024-06-02 07:14:13 +00:00
MrHua269
3deaf5f7fb [ci skip]Corrected CI name 2024-05-31 11:50:49 +00:00
MrHua269
81dd04e018 Updated to non experimental version 2024-05-31 11:50:15 +00:00
MrHua269
bd26f9aeab Updated Upstream(Folia) 2024-05-31 11:47:13 +00:00
ShintoKosei
6b2a9d25c8 [ci skip]Update CI 2024-05-26 19:41:51 +08:00
ShintoKosei
15bb0f42d0 Update README 2024-05-24 22:58:03 +08:00
ShintoKosei
841c0b9cd3 [release skip]Update README 2024-05-24 22:19:15 +08:00
ShintoKosei
63ef3ce0b9 Update CI (use warning color) 2024-05-24 15:06:49 +08:00
ShintoKosei
92b9d91fdf Update CI (the mojmap) 2024-05-24 15:04:28 +08:00
ShintoKosei
a02d29c6a7 [NOT TO USE EMOJI] 2024-05-24 14:44:35 +08:00
ShintoKosei
7b971faccc To Build dev 2024-05-24 14:43:31 +08:00
Dreeam
b952734d6b [ci skip] Correct rebrand 2024-05-21 21:39:07 +08:00
MrHua269
5e86abed12 Use private executor for watchdog timer 2024-05-19 13:22:44 +00:00
Dreeam
266ea43135 Updated Upstream (Folia) 2024-05-19 04:52:07 -04:00
M2ke4U
a33f5c92bb Switched to mojmap for 1.20.6 2024-05-12 21:28:14 +08:00
M2ke4U
1238ec3bf9 Updated Upstream(Folia) 2024-05-12 20:56:34 +08:00
M2ke4U
dec6cf5fd3 Linear is not supported anymore 2024-05-11 22:10:27 +08:00
MrHua269
bb679c51fc Merge remote-tracking branch 'origin/dev/1.20.6' into dev/1.20.6 2024-05-11 12:22:16 +00:00
MrHua269
0f1fee37ef Updated Upstream(Folia) 2024-05-11 12:22:05 +00:00
M2ke4U
5a852d792e MojangMap → Reobf 2024-05-10 23:56:52 +08:00
Dreeam
4333f80871 All patches done 2024-05-09 20:22:31 -04:00
Dreeam
45e119a5ad Some 1.20.6 work 2024-05-09 18:36:58 -04:00
Dreeam
b027e4cd03 Updated Upstream (Folia)
Latest 1.20.4 Paper/Folia
2024-05-09 16:58:15 -04:00
M2ke4U
1e5e540795 Corrected incorrect discord link
WTF??
2024-05-03 21:25:12 +08:00
M2ke4U
a020b181cc Corrected incorrect discord link
WTF?
2024-05-03 21:24:38 +08:00
M2ke4U
7ea76f4f74 Delete patches/server/0061-Added-chunkhot-to-tpsbar.patch 2024-05-03 21:21:19 +08:00
Luminol CI
787c3793c6 Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4
# Conflicts:
#	patches/server/0052-Leaves-Replay-Mod-API.patch
2024-05-03 12:53:59 +00:00
Luminol CI
39c74a5409 Fix Java compile 2024-05-03 12:52:37 +00:00
M2ke4U
fca5e33fa4 Fix java compile in ReplayMod API 2024-05-03 18:26:07 +08:00
MrHua269
2d14daaa87 Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-05-02 04:24:42 +00:00
MrHua269
0a63aeaca2 Removed useless patches 2024-05-02 04:24:28 +00:00
haha44444
729312415f fix goto chinese page bug 2024-04-30 23:19:13 +08:00
haha44444
96499c26ff fix goto english page bug 2024-04-30 23:19:13 +08:00
MrHua269
7645ef08e8 Added chunkhot to tpsbar 2024-04-30 23:19:13 +08:00
MrHua269
e7dde4f240 Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-04-30 14:03:20 +00:00
MrHua269
dbb30dc4f3 Added chunkhot to tpsbar 2024-04-30 14:02:57 +00:00
M2ke4U
65de2ae23e Merge pull request #13 from haha44444/ver/1.20.4
fix a littleeeee issue
2024-04-30 20:24:36 +08:00
haha44444
ec74075cc5 fix goto chinese page bug 2024-04-30 02:26:59 +08:00
haha44444
e5379a2042 fix goto english page bug 2024-04-30 02:25:50 +08:00
MrHua269
67ba24ec92 Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-04-27 13:24:15 +00:00
MrHua269
943c084de6 Fully APIs for ChunkHotAPI 2024-04-27 13:24:03 +00:00
ShintoKosei
8d3c7e7807 Change to Mojmap 2024-04-27 21:07:36 +08:00
MrHua269
fbd9d9f48f Fix some stuff about ChunkHot API 2024-04-27 13:03:44 +00:00
MrHua269
512da58f92 KioCG ChunkHot API test 2024-04-27 12:43:42 +00:00
MrHua269
b239c97db1 Removed linear format support 2024-04-27 10:39:01 +00:00
MrHua269
650ce2770d Added flush threshold for linear region file 2024-04-20 13:34:16 +00:00
MrHua269
ce500bf638 Added flush threshold for linear region file 2024-04-20 13:33:34 +00:00
MrHua269
48f34a6146 Refactor linear flushing again 2024-04-20 13:15:22 +00:00
ShintoKosei
40cae40b09 Fix CI 2024-04-14 13:56:38 +08:00
ShintoKosei
38a8161c1a Update CI 2024-04-14 13:50:09 +08:00
MrHua269
dced86a404 Fix java compile 2024-04-13 12:18:11 +00:00
MrHua269
a983ac00e5 Update(Leaves): Photographer GameMode locked 2024-04-13 12:16:03 +00:00
MrHua269
e2b21e0f69 Clean and optimize patches 2024-04-13 12:05:00 +00:00
MrHua269
07ef8e01c5 Remove io_uring support 2024-04-13 11:58:11 +00:00
MrHua269
77cb94ae5f Updated Upstream(Folia) 2024-04-13 11:55:55 +00:00
MrHua269
14e7cbe186 Clean patches 2024-04-13 11:41:31 +00:00
ShintoKosei
49be774d83 rebase 2024-04-13 19:03:09 +08:00
ShintoKosei
06dcc037df Update CI 2024-04-06 15:17:19 +08:00
MrHua269
9247a01058 Added some optimizations from Gale 2024-04-06 05:19:02 +00:00
MrHua269
856ddfe7cc Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-04-06 02:38:37 +00:00
MrHua269
4013d9dc3b Add warn to region format config 2024-04-06 02:38:27 +00:00
ShintoKosei
ce8a2afb0f Create FUNDING.yml 2024-04-05 23:03:10 +08:00
ShintoKosei
ea3efdb597 [ci skip]Update README.md 2024-04-05 19:59:05 +08:00
ShintoKosei
678c3faeea [ci skpi]Update README.md 2024-04-05 19:47:26 +08:00
ShintoKosei
815adcc00e [ci skip]Update README 2024-04-05 16:48:49 +08:00
MrHua269
c0d766fd07 Fix my stupid rebrand 2024-04-05 04:33:53 +00:00
MrHua269
a9cd09f900 Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-04-05 01:19:11 +00:00
MrHua269
1452008bbe Fix non-working tripwire incorrect updating fix 2024-04-05 01:19:00 +00:00
Klop233
e71abbd761 fix CI 2024-04-04 19:37:52 +08:00
Klop233
6db86f10e7 Revert "update CI"
This reverts commit e1afa32f90.
2024-04-04 11:29:15 +08:00
Klop233
f134186657 Revert "Update build_1_20_4.yml"
This reverts commit 9551755b0d.
2024-04-04 11:29:13 +08:00
Klop233
ef1b7ce6f7 Revert "update CI"
This reverts commit 3c1be89214.
2024-04-04 11:29:11 +08:00
Klop233
f16e5c1064 Revert "update CI"
This reverts commit 6317a5399b.
2024-04-04 11:29:08 +08:00
Klop233
0b9a436044 Revert incorrect CI changes
This reverts commit 76f2aa58e1.
2024-04-04 11:28:58 +08:00
Klop233
76f2aa58e1 update CI 2024-04-03 21:35:54 +08:00
Klop233
6317a5399b update CI 2024-04-03 21:35:54 +08:00
Klop233
3c1be89214 update CI 2024-04-03 21:35:53 +08:00
Klop233
9551755b0d Update build_1_20_4.yml 2024-04-03 21:35:53 +08:00
Klop233
e1afa32f90 update CI 2024-04-03 21:35:53 +08:00
ShintoKosei
fa109ea506 [ci skip]fix README.md 2024-04-03 18:10:40 +08:00
MrHua269
ebe2b03455 Updated Upstream(Folia) 2024-03-30 10:17:45 +00:00
ShintoKosei
3456a29225 [ci skip]Update README.md 2024-03-28 13:38:22 +08:00
Dreeam
c06f539f46 Fix build 2024-03-25 11:17:56 -04:00
MrHua269
259d5173b8 Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-03-25 13:53:36 +00:00
MrHua269
3aa2070f49 Updated Upstream(Folia) 2024-03-25 13:53:21 +00:00
Klop233
248ac6ae2b [ci skip] change default to CN 2024-03-23 23:21:00 +08:00
MrHua269
54da5452d2 Leaves Replay Mod API 2024-03-17 02:15:26 +00:00
M2ke4U
b1a3d6f0d1 Merge pull request #7 from HaHaWTH/ver/1.20.4
Fix MC-172047 and MC-2025
2024-03-15 19:53:50 +08:00
HaHaWTH
9b761ef0c0 patch 2024-03-15 12:16:08 +08:00
HaHaWTH
e965f7285a Fix MC-2025 2024-03-15 03:33:09 +08:00
HaHaWTH
0f1f8b3f78 Fix MC-172047 2024-03-15 03:23:10 +08:00
M2ke4U
cce9600afb Fix jar renaming issue 2024-03-10 14:07:10 +08:00
M2ke4U
5ced673fd8 Set CI to Ubuntu 2024-03-10 13:54:55 +08:00
MrHua269
5a8c6b91d0 Publish tweaks(x2) 2024-03-10 05:44:56 +00:00
MrHua269
64f826fd98 Publish tweaks 2024-03-10 05:44:37 +00:00
MrHua269
5b0465efeb Added a simple watchdog for tick regions 2024-03-10 05:09:51 +00:00
MrHua269
2f30488144 Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-03-09 13:31:46 +00:00
MrHua269
1aca9f74c4 Tweaks in LeavesProtocolManager and fix config hot reloading issue in tpsbar 2024-03-09 13:31:12 +00:00
MrHua269
932c9f9194 Tweaks in LeavesProtocolManager and fix config hot reloading issue in tpsbar 2024-03-09 13:30:23 +00:00
MrHua269
eafe7cd5e3 [ci skip]Make project name to lowercase 2024-03-09 10:00:18 +00:00
Klop233
a319241fc2 ci test 2024-03-09 09:35:42 +08:00
Klop233
540bbd4f6a Create ci test 2024-03-09 09:34:58 +08:00
Klop233
8b8328c5b6 Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-03-09 08:40:26 +08:00
Klop233
c508de9f2a [ci skip] remove unuseful file 2024-03-09 08:39:38 +08:00
M2ke4U
483e958c58 Fix incorrect init logic in tpsbar 2024-03-08 22:17:09 +08:00
MrHua269
01abc6c424 Added config command 2024-03-03 13:01:24 +00:00
MrHua269
6d26556182 Add basement things of config file hot reloading 2024-03-03 12:13:18 +00:00
MrHua269
78e463d201 Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-03-03 11:52:27 +00:00
MrHua269
f67b792dd6 Only publish API module 2024-03-03 11:52:17 +00:00
NatJerry
38eb77a049 [ci skip]Update README_CN.md 2024-03-03 13:54:25 +08:00
NatJerry
624825f76b [ci skip]Update README.md 2024-03-03 13:53:30 +08:00
MrHua269
4dcf8fb6ff Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-03-03 00:55:02 +00:00
MrHua269
a06ae51240 Adjust gradle config in main module and added option for dev bundle publishing 2024-03-03 00:54:21 +00:00
Klop233
3c80338a24 test 2024-03-02 14:37:19 +08:00
MrHua269
59a428e597 Updated Upstream(Folia) 2024-02-22 00:53:47 +00:00
MrHua269
f65089a3bc Updated Upstream(Folia) 2024-02-21 07:22:46 +00:00
MrHua269
3dc384625a Bumped paperweight to 1.5.11 2024-02-21 00:48:38 +00:00
MrHua269
41d9c2cb89 Updated Upstream(Folia) 2024-02-21 00:45:39 +00:00
MrHua269
48c1fde6b0 Add some optimizations and misc config 2024-02-20 13:23:20 +00:00
MrHua269
9c332ffb4b Clean unused files 2024-02-20 12:53:06 +00:00
MrHua269
4aaa78b7fc Clean LuminolConfig 2024-02-20 09:28:02 +00:00
ShintoKosei
2d1a64177a [ci skip]update reamde.md 2024-02-19 22:56:54 +08:00
ShintoKosei
5363c69ea7 [ci skip]Update README.md 2024-02-19 22:51:08 +08:00
M2ke4U
5e79b7c916 Corrected incorrect config key name in patch 0016 2024-02-18 18:00:25 +08:00
ShintoKosei
c0797d33df [ci skip]Update README.md 2024-02-18 17:33:04 +08:00
NatJerry
fed8624fff Update README.md 2024-02-18 16:47:52 +08:00
ShintoKosei
0715533d18 [ci skip]fix Contributing.md 2024-02-18 14:58:58 +08:00
ShintoKosei
d0d9402571 [ci skip]Update README(en) 2024-02-18 14:53:26 +08:00
ShintoKosei
eb52e43eda [ci skip]Add CONTRIBUTING.md 2024-02-18 14:51:22 +08:00
ShintoKosei
1a7154a26e [ci skip]Add CONTRIBUTING.md 2024-02-18 14:50:20 +08:00
MrHua269
58d264ff28 Updated Upstream(Folia) 2024-02-14 00:38:38 +00:00
MrHua269
80e9064854 Added some optimizations from Gale 2024-02-09 23:45:34 +00:00
MrHua269
8628f803c2 Remove problematic API patches 2024-02-09 14:55:29 +00:00
MrHua269
dc4a73f92b Some events for threaded regions 2024-02-09 03:34:58 +00:00
MrHua269
785325c5e2 Leaves carpet protocol support 2024-02-08 11:57:39 +00:00
MrHua269
f1f23b48a9 Added notice 2024-02-08 03:59:56 +00:00
MrHua269
1e7ec58c46 Removed debug method in LuminolConfig 2024-02-08 01:14:44 +00:00
MrHua269
a5b1d1c1c4 Correct confusable config key names and clean patches 2024-02-08 00:49:25 +00:00
Klop233
825c337518 Update README.md 2024-02-08 07:38:42 +08:00
Klop233
3075603528 Rebrand icon 2024-02-07 14:44:00 +00:00
Klop233
b7f290b6b9 [ci skip] Update readme 2024-02-07 11:39:01 +00:00
MrHua269
a9c13dcd70 Rewrite config file system and remove useless patches 2024-02-07 09:16:42 +00:00
MrHua269
541507e23b LinearPaper Remove all locks on region files 2024-02-06 11:53:46 +00:00
ShintoKosei
861b6c2425 [ci skip] Upload SVG 2024-02-06 17:25:14 +08:00
ShintoKosei
c0771ba8d9 [ci skip] Update README 2024-02-06 14:32:11 +08:00
ShintoKosei
594aaf149f [ci skip] Update main branch of 1.20.4 2024-02-06 14:30:20 +08:00
MrHua269
891f42ac78 Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-02-06 04:51:30 +00:00
MrHua269
ca9decc263 Updated Upstream(Folia) 2024-02-06 04:51:04 +00:00
M2ke4U
6709316516 [ci skip]Added logo in README 2024-02-05 21:43:37 +08:00
M2ke4U
c86388a91f [ci skip]Added logo file 2024-02-05 21:40:23 +08:00
M2ke4U
8ec40d0dcb [ci skip]Added bstats 2024-02-05 09:21:52 +08:00
MrHua269
00fb6f9ab7 Do not check tickThread while removing bots 2024-02-02 01:19:16 +00:00
MrHua269
a780b90545 Rebase patches 2024-02-01 10:26:13 +00:00
MrHua269
c90b205633 Fixes in folia and fakeplayer 2024-02-01 09:43:05 +00:00
MrHua269
089c2d85fe Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-01-31 09:35:28 +00:00
MrHua269
f197e9dcb9 Fixes in fakeplayer and io_uring channel type 2024-01-31 09:35:09 +00:00
M2ke4U
db303d60b1 Correct wrong thread name
How careless I could be()
2024-01-30 21:15:35 +08:00
MrHua269
a66f857401 Io_uring channel type support 2024-01-30 13:03:40 +00:00
MrHua269
9e33137e10 Set CI auto release from release to prerelease 2024-01-30 13:03:33 +00:00
MrHua269
8130bc9226 Fix wrongly CraftScheduler call in ServerBot 2024-01-30 08:46:40 +00:00
MrHua269
aa17d5c905 Correct incorrect commits between 0055 and 0056 2024-01-29 13:30:12 +00:00
MrHua269
6ee523d185 Leaves fakeplayer support 2024-01-29 12:36:11 +00:00
MrHua269
3446b9d45f Merge remote-tracking branch 'origin/ver/1.20.4' into ver/1.20.4 2024-01-28 13:07:28 +00:00
MrHua269
e2c1b3f536 Disable DAB by default 2024-01-28 13:06:33 +00:00
M2ke4U
004b0a731a Dropped problematic patches 2024-01-28 18:23:34 +08:00
MrHua269
7322788353 Add some desc for async mob spawning and added some new optimizations 2024-01-28 09:35:53 +00:00
MrHua269
b9aaad9559 Fix some issue in async mob spawning 2024-01-28 02:07:58 +00:00
MrHua269
c5a7fbccbf Updated Upstream(Folia) 2024-01-27 14:38:04 +00:00
M2ke4U
2616bd9df6 Teleport async if the entity was moving to another region 2024-01-26 19:10:34 +08:00
M2ke4U
7280aa9a6b Piston fixes from molean server 2024-01-21 19:51:13 +08:00
MrHua269
53206ca75f Fix build 2024-01-17 14:14:41 +00:00
MrHua269
a413f1d82c Leaves Fix Bladeren Protocol 2024-01-17 14:11:02 +00:00
MrHua269
25008dc31d Updated Upstream(Folia) 2024-01-14 00:53:39 +00:00
M2ke4U
89871f0b36 Do not process any packet if the leaves protocol supports are disabled 2024-01-08 21:27:34 +08:00
M2ke4U
9d257c6060 [ci skip]Remove useless file 2024-01-07 17:04:30 +08:00
M2ke4U
471a059ab2 [ci skip]Updated LICENSE and migrated license to luminolmc 2024-01-02 23:11:03 +08:00
MrHua269
a0bc01a355 Updated Upstream(Folia) 2024-01-01 08:16:23 +00:00
M2ke4U
30ef290b4f [ci skip]Rename build.yml to build_1_20_4.yml 2023-12-24 21:29:12 +08:00
M2ke4U
759b88fb4b Fix threading issue in PCA Sync 2023-12-24 14:48:28 +08:00
M2ke4U
ad74975559 Updated Upstream(Folia) 2023-12-24 14:40:08 +08:00
M2ke4U
27535b8b94 Fix java compiling issue in 0041 2023-12-24 12:32:26 +08:00
M2ke4U
e400a4f904 Updated dependence version in README.md 2023-12-24 12:16:02 +08:00
M2ke4U
299cc10748 Updated to dev/1.20.4 cd713b8ea2e7a57a37a99755d8d84b7fa0c9f170 2023-12-24 12:14:19 +08:00
147 changed files with 10503 additions and 13474 deletions

14
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
custom: https://afdian.com/a/Luminol

68
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@@ -0,0 +1,68 @@
name: Bug反馈 Bug report
description:
报告Bug插件不兼容情况以及其他相关问题。
Report issues with plugin incompatbility or other behavior related issues.
labels:
- bug
body:
- type: markdown
attributes:
value: |
请详细描述您所遇到的Bug。确保您**真的**遇到了**服务端**Bug而非原版特性或客户端Bug。
Please describe the bug you encountered in detail. Make sure you're **actually** hitting a **server-side** bug, not a vanilla feature or client-side bug.<br>
如果您确定的话,就按照下面的模板填充信息,并提交反馈。
If you are sure, follow the template below to fill in the information and submit your feedback.<br>
如果此bug被尝试修复您可以帮助我们测试并回复。若bug的确被修复您可以关闭issue来让开发者确认。
If this bug is tried to fix, you can help us test and reply. If the bug is fixed, you can close the issue to let the developer confirm.
- type: input
id: leavesMC-version
attributes:
label: 服务端版本 LuminolMC Version
description:
LuminolMC服务端发行版本 LuminolMC server release version (contains the git commit's hash)<br>
通过执行`/version`命令将获取到的内容复制到这里。 Run `/version` on your server and paste the full, unmodified output here.
placeholder: >
e.g. git-Luminol-"0635a89" (MC: 1.20.4)
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: 预期的行为 Expected behavior
description: 你期望看到的情况是什么样。What you expected to see.
placeholder: e.g. 使用 /tpsbar [NAME] 命令可以切换TPSBAR的开关
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: 观测到的实际行为 Observed/Actual behavior
description: 你实际看到的。 What you actually saw.
placeholder: e.g. 使用 /tpsbar [NAME] 命令切换不了TPSBAR
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: 复现步骤 Steps/models to reproduce
description:
这里应该有一个图片、视频或其他信息来展现你的问题。<br>
This may include a build schematic, a video, or detailed instructions to help reconstruct the issue.
placeholder: e.g. 登录其他账号,使用 /tpsbar [NAME] 命令切换不了TPSBAR
validations:
required: true
- type: textarea
id: plugin-list
attributes:
label: 插件与数据包列表。 Plugin and Datapack List.
description:
服务器上的所有插件和数据包列表。
All plugins and datapacks running on your server.<br>
执行命令`/plugins`查看插件列表。执行命令`/datapack list`查看数据包列表。
To list plugins, run `/plugins`. For datapacks, run `/datapack list`.
validations:
required: true
- type: textarea
id: other
attributes:
label: 更多详细信息。 The more information.

View File

@@ -0,0 +1,31 @@
name: 新的需求 Feature Request
description:
为Luminol提供新的想法。
Suggest an idea for Luminol.
labels:
- enhancement
body:
- type: markdown
attributes:
value: |
感谢您为 Luminol 提交新的需求!请尽可能详细地描述,以便我们可以更轻松地考虑和审查请求。
Thank you for filling out a feature request for Luminol! Please be as detailed as possible so that we may consider and review the request easier.<br>
请搜索所有问题以避免重复的功能请求。如果您期望的功能已存在,请回复如果您有什么要补充的。
We ask that you search all the issues to avoid a duplicate feature request. If one exists, please reply if you have anything to add.<br>
在请求新功能之前,请确保您使用的是最新版本并且您请求的功能不在 Luminol 中。
Before requesting a new feature, please make sure you are using the latest version and that the feature you are requesting is not already in Paper.<br>
我们的开发人员可能没有过多时间来测试新功能的可用性如新功能进入Test状态您可以帮助我们进行测试并回复。
Our developers may not have much time to test the usability of new functions. If the new functions enter the Test state, you can help us test and reply.
- type: textarea
id: feature
attributes:
label: 描述你希望添加的功能。 Describe the feature you'd like.
placeholder: e.g. 添加新的PATH
validations:
required: true
- type: textarea
id: othre
attributes:
label: 其他 Other
description: 添加其他的信息。 Add any other context or screenshots about the feature request below.

75
.github/workflows/build_1.20.6.yml vendored Normal file
View File

@@ -0,0 +1,75 @@
name: Luminol CI - vev/1.20.6
on:
push:
branches: [ "ver/1.20.6" ]
pull_request:
branches: [ "ver/1.20.6" ]
permissions: write-all
jobs:
build:
runs-on: ubuntu-latest
environment: default
env:
MAVEN_REPO_USER: ${{ secrets.MAVEN_REPO_USER }}
MAVEN_REPO_PASSWORD: ${{ secrets.MAVEN_REPO_PASSWORD }}
steps:
- name: Checkout Git Repository
uses: actions/checkout@v4
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@v3
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
gradle-version: 8.7
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '21'
- name: Configure Git User Details
run: git config --global user.email "ci@luminolmc.com" && git config --global user.name "LuminolMC CI"
- name: Apply Patches
run: gradle applyPatches
- name: CreateJar
run: gradle createMojmapBundlerJar createMojmapPaperclipJar
- name: Publish to repo
run: |
export MAVEN_REPO_USER=${{ secrets.MAVEN_REPO_USER }}
export MAVEN_REPO_PASSWORD=${{ secrets.MAVEN_REPO_PASSWORD }}
./gradlew publish -PpublishDevBundle=true
- name: SetENV
run: sh scripts/SetENV.sh
- name: Upload Artifact
uses: "actions/upload-artifact@v4"
with:
name: "${{ env.project_id_b }} CI Artifacts"
path: "build/libs/*.jar"
- name: Create Release
if: "!contains(github.event.commits[0].message, '[release skip]')"
uses: ncipollo/release-action@v1.14.0
with:
tag: ${{ env.tag }}
name: ${{ env.project_id_b }} ${{ env.mcversion }} - ${{ env.commit_id }}
body: |
📦Version: `${{ env.mcversion }}` | Commit ${{ env.commit_id }} [![download](https://img.shields.io/github/downloads/LuminolMC/${{ env.project_id }}/${{ env.tag }}/total?color=red&style=flat-square)](https://github.com/LuminolMC/${{ env.project_id }}/download/${{ env.tag }}/${{ env.jar }})
This release is automatically compiled by GitHub Actions
### Commit Message
${{ env.commit_msg }}
artifacts: |
${{ env.jar_dir }}
${{ env.jar_dir_bundler }}
generateReleaseNotes: true
prerelease: ${{ env.pre }}
makeLatest: ${{ env.make_latest }}
token: "${{ secrets.GITHUB_TOKEN }}"
- name: Push to API
if: "!contains(github.event.commits[0].message, '[release skip]')"
continue-on-error: true
env:
secret_v2: ${{ secrets.API_KEY }}
tag: ${{ env.tag }}
project_id: ${{ env.project_id }}
run: sh scripts/PushToAPI.sh

View File

@@ -1,63 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
name: LuminolCI - Ver/1.20.2
on:
push:
branches: [ "ver/1.20.2" ]
pull_request:
branches: [ "ver/1.20.2" ]
permissions: write-all
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Set up git
run: git config --global user.email "noreply@github.com" && git config --global user.name "ci"
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Make gradlew executable
run: chmod 777 ./gradlew
- name: Setup project
uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0
with:
arguments: applyPatches
- name: Build project to paperclip jar
uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0
with:
arguments: createReobfPaperclipJar
- name: Capture build artifacts
uses: actions/upload-artifact@v3
with:
name: Artifacts
path: build/libs/
- name: Publish API
run: |
echo "GITHUB_USERNAME=LuminolCI" >> $GITHUB_ENV
export GITHUB_USERNAME=LuminolCI
echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
./gradlew publish
- name: Rename jar file
run: mv build/libs/Luminol-paperclip-1.20.2-R0.1-SNAPSHOT-reobf.jar build/libs/luminol-1.20.2-paperclip.jar
- name: Release Artifacts
uses: svenstaro/upload-release-action@v2
with:
release_name: "Luminol MC1.20.2 - ${{ github.event.repository.updated_at}}"
tag: "1.20.2-${{ github.run_id }}"
repo_token: "${{ secrets.GITHUB_TOKEN }}"
file: "build/libs/luminol-1.20.2-paperclip.jar"
file_glob: true
prerelease: true

9
.gitignore vendored
View File

@@ -33,7 +33,6 @@ target/
dependency-reduced-pom.xml
# various other potential build files
build/
bin/
dist/
manifest.mf
@@ -51,8 +50,10 @@ manifest.mf
# other stuff
run/
# Luminol
build-data/
Hearse-API
Hearse-Server
Luminol-API
Luminol-Server
paper-api-generator
*.jar
/patches/todo/
/patches2/todo/

View File

@@ -1,39 +1,88 @@
<img src="./public/image/Luminol_5.png" alt="Logo" align="right" width="250">
# Luminol
<h4>Luminol 是一个基于Folia的分支具有许多有用的优化、可配置的原版特性和更多的API支持它专为生存和无政府服务器设计</h4>
[![MIT License](https://img.shields.io/github/license/LuminolMC/Luminol?style=flat-square)](LICENSE)
[![Issues](https://img.shields.io/github/issues/LuminolMC/Luminol?style=flat-square)](https://github.com/LuminolMC/Luminol/issues)
![Commit Activity](https://img.shields.io/github/commit-activity/w/LuminolMC/Luminol?style=flat-square)
![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/LuminolMC/Luminol?style=flat-square)
![GitHub all releases](https://img.shields.io/github/downloads/LuminolMC/Luminol/total?style=flat-square)
<h4>Luminol is a folia fork with many useful optimizations, configurable vanilla features, and more API supports, and it was designed for survival and anarchy servers</h4>
[English](./README_EN.md) | **中文**
## Features
- Configurable vanilla features
- Tpsbar support
- Linear region file format(from kaiiju)
- Useful optimizations to improve the performance of single threaded region
- More API support for plugin development (W.I.P)
## 特性
- 可配置的原版特性
- Tpsbar 支持
- 对单线程区域性能的优化
- 更多的插件开发API支持进行中
## Download
Any versions are available in the [release](https://github.com/LuminolMC/Luminol/releases), also you can build it by yourself through the following steps.
## 下载
任何版本都可以在 [Release](https://github.com/LuminolMC/Luminol/releases) 中找到,你也可以通过[以下步骤](./README.md#构建)自己构建。
## 构建
要构建一个paperclip jar你需要运行以下命令。你可以在build/libs中找到jar注意需要`JDK21`
## Build
To build a paperclip jar, you need to run the following command. You can find the jar in build/libs(Note: JDK17 is needed)
```shell
./gradlew applyPatches && ./gradlew createReobfPaperclipJar
./gradlew applyPatches && ./gradlew createMojmapPaperclipJar
```
## Using API
For gradle:
## 使用API
使用 Gradle:
```kotlin
repositories {
maven {
url = "http://maven.nostal.ink/repository/maven-snapshots/"
}
}
dependencies {
compileOnly("me.earthme.luminol:luminol-api:1.20.2-R0.1-SNAPSHOT")
compileOnly("me.earthme.luminol:luminol-api:1.20.6-R0.1-20241001.135131-1")
}
```
For maven
使用 Maven
```xml
<dependency>
<groupId>me.earthme.luminol</groupId>
<artifactId>luminol-api</artifactId>
<version>1.20.2-R0.1-SNAPSHOT</version>
</dependency>
<repositories>
<repository>
<id>nostal</id>
<url>http://maven.nostal.ink/repository/maven-snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>me.earthme.luminol</groupId>
<artifactId>luminol-api</artifactId>
<version>1.20.6-R0.1-20241001.135131-1</version>
</dependency>
</dependencies>
```
## 联系方式
> 如果您对这个项目感兴趣或有任何问题,请随时向我们提问。
**QQ群: [368632360](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=MfosKhcDd8Fdxn1MREuZ8Krbf9T6jiBC&authKey=3cm6qdHohON3gHnuD63FK4k07fIbrWnY4hdyq8OmELsfjMVP1kbFTJY9mRyM2Rkj&noverify=0&group_code=368632360)** | QQ频道: [点击加入](https://pd.qq.com/s/eq9krf9j) | Telegram: [点击加入](https://t.me/LuminolMC) | Discord: [点击加入](https://discord.gg/Qd7m3V6eDx)
## 关于 Issue
当您遇到任何问题时,请向我们提问,我们将尽力解决,但请记得清楚地描述您的问题并提供足够的日志等信息。
## 贡献代码
可[查看 Contributing](./docs/CONTRIBUTING.md)
## BStats
![bStats](https://bstats.org/signatures/server-implementation/Luminol.svg "bStats")
## 请给我们一个 ⭐Star
> 你的每一个免费的 ⭐Star 就是我们每一个前进的动力。
<a href="https://star-history.com/#LuminolMC/Luminol&LuminolMC/LightingLuminol&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol&type=Date" />
<img alt="Star历史表" src="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol&type=Date" />
</picture>
</a>

86
README_EN.md Normal file
View File

@@ -0,0 +1,86 @@
<img src="./public/image/Luminol_5.png" alt="Logo" align="right" width="250">
# Luminol
<h4>Luminol is a Folia fork with many useful optimizations, configurable vanilla features, and more API supports, and it was designed for survival and anarchy servers</h4>
[![MIT License](https://img.shields.io/github/license/LuminolMC/Luminol?style=flat-square)](LICENSE)
[![Issues](https://img.shields.io/github/issues/LuminolMC/Luminol?style=flat-square)](https://github.com/LuminolMC/Luminol/issues)
![Commit Activity](https://img.shields.io/github/commit-activity/w/LuminolMC/Luminol?style=flat-square)
![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/LuminolMC/Luminol?style=flat-square)
![GitHub all releases](https://img.shields.io/github/downloads/LuminolMC/Luminol/total?style=flat-square)
**English** | [中文](./README.md)
## Features
- Configurable vanilla features
- Tpsbar support
- Linear region file format(from kaiiju)
- Useful optimizations to improve the performance of single threaded region
- More API support for plugin development (W.I.P)
## Download
Any versions are available in the [release](https://github.com/LuminolMC/Luminol/releases), also you can build it by yourself through [the following steps](./README_EN.md#build).
## Build
To build a paperclip jar, you need to run the following command. You can find the jar in build/libs(Note: JDK21 is needed)
```shell
./gradlew applyPatches && ./gradlew createMojmapPaperclipJar
```
## Using API
For gradle:
```kotlin
repositories {
maven {
url = "https://maven.nostal.ink/repository/maven-snapshots/"
}
}
dependencies {
compileOnly("me.earthme.luminol:luminol-api:1.20.6-R0.1-20241001.135131-1")
}
```
For maven
```xml
<repositories>
<repository>
<id>nostal</id>
<url>http://maven.nostal.ink/repository/maven-snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>me.earthme.luminol</groupId>
<artifactId>luminol-api</artifactId>
<version>1.20.6-R0.1-20241001.135131-1</version>
</dependency>
</dependencies>
```
## Contact
> If you are interested in this project or have any issue, feel free to ask us.
**QQ Group: [368632360](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=MfosKhcDd8Fdxn1MREuZ8Krbf9T6jiBC&authKey=3cm6qdHohON3gHnuD63FK4k07fIbrWnY4hdyq8OmELsfjMVP1kbFTJY9mRyM2Rkj&noverify=0&group_code=368632360)** | QQ Channel: [Click To Join](https://pd.qq.com/s/eq9krf9j) | Telegram: [Click To Join](https://t.me/LuminolMC) | Discord: [Click To Join](https://discord.gg/Qd7m3V6eDx)
## About Issue
When you meet any problems, just ask us, we will do our best to solve it, but remember to state your problem clear and provide enough logs etc.</br>
## Pull Requests
See [Contributing](./docs/CONTRIBUTING_EN.md)
## BStats
![bStats](https://bstats.org/signatures/server-implementation/Luminol.svg "bStats")
## Please ⭐star us!
<a href="https://star-history.com/#LuminolMC/Luminol&LuminolMC/LightingLuminol&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol&type=Date" />
</picture>
</a>

View File

@@ -1,10 +1,7 @@
import io.papermc.paperweight.util.constants.*
plugins {
java
`maven-publish`
id("com.github.johnrengelman.shadow") version "8.1.1" apply false
id("io.papermc.paperweight.patcher") version "1.5.9"
id("io.papermc.paperweight.patcher") version "1.7.1"
}
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
@@ -17,9 +14,9 @@ repositories {
}
dependencies {
remapper("net.fabricmc:tiny-remapper:0.8.6:fat")
decompiler("org.quiltmc:quiltflower:1.9.0")
paperclip("io.papermc:paperclip:3.0.3-SNAPSHOT")
remapper("net.fabricmc:tiny-remapper:0.10.1:fat")
decompiler("org.vineflower:vineflower:1.10.1")
paperclip("io.papermc:paperclip:3.0.3")
}
subprojects {
@@ -28,13 +25,13 @@ subprojects {
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
languageVersion.set(JavaLanguageVersion.of(21))
}
}
tasks.withType<JavaCompile> {
options.encoding = Charsets.UTF_8.name()
options.release.set(17)
options.release.set(21)
}
tasks.withType<Javadoc> {
@@ -59,17 +56,6 @@ subprojects {
}
tasks.generateDevelopmentBundle {
apiCoordinates.set("me.earthme.luminol:luminol-api")
mojangApiCoordinates.set("io.papermc.paper:paper-mojangapi")
libraryRepositories.set(
listOf(
"https://repo.maven.apache.org/maven2/",
paperMavenPublicUrl,
)
)
}
paperweight {
serverProject.set(project(":luminol-server"))
@@ -91,5 +77,46 @@ paperweight {
serverPatchDir.set(layout.projectDirectory.dir("patches/server"))
serverOutputDir.set(layout.projectDirectory.dir("Luminol-Server"))
}
patchTasks.register("generatedApi") {
isBareDirectory = true
upstreamDirPath = "paper-api-generator/generated"
patchDir = layout.projectDirectory.dir("patches/generatedApi")
outputDir = layout.projectDirectory.dir("paper-api-generator/generated")
}
}
}
tasks.generateDevelopmentBundle {
apiCoordinates.set("me.earthme.luminol:luminol-api")
libraryRepositories.addAll(
"https://repo.maven.apache.org/maven2/",
"https://maven.pkg.github.com/LuminolMC/Luminol",
paperMavenPublicUrl,
)
}
allprojects {
publishing {
repositories {
maven {
name = "moliaMavenRepo"
url = uri("https://maven.nostal.ink/repository/maven-snapshots/")
credentials.username = System.getenv("MAVEN_REPO_USER")
credentials.password = System.getenv("MAVEN_REPO_PASSWORD")
}
}
}
}
publishing {
if (project.hasProperty("publishDevBundle")) {
publications.create<MavenPublication>("devBundle") {
artifact(tasks.generateDevelopmentBundle) {
artifactId = "dev-bundle"
}
}
}
}

67
docs/CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,67 @@
为Luminol贡献代码
===========
[English](./CONTRIBUTING_EN.md) | **中文**
我们很开心您想为我们的项目做出贡献一般来说我们对PR的审核是十分宽松的
但是如果您可以遵守下列的规则,我们可以更快地完成审核。
## 使用个人账户进行 Fork
我们会定期尝试合并已有的 PR如果有一些小问题会尝试帮您解决这些问题。
但是如果您使用了组织账号进行 PR我们就不能对您的 PR 进行修改了。因此我们只能关闭你的PR然后进行手动合并。
所以,请不要使用组织账号进行 Fork
您可以看看 [这个 Issue](https://github.com/isaacs/github/issues/1681) 来了解一下我们为什么无法修改组织账号的 PR。
## 开发环境
在开始开发之前,您首先需要拥有以下软件作为开发环境:
- `git`
- `JDK 17 或更高版本`
## 了解补丁Patches
Luminol 使用和 Folia 一样的补丁系统,并为了针对不同部分的修改分成了两个目录:
- `luminol-api` - 对 `Folia-API` / `Paper-API` / `Spigot-API` / `Bukkit` 进行的修改。
补丁系统是基于 git 的,你可以在这里了解 git 的基本内容: <https://git-scm.com/docs/gittutorial>
如果你已经 Fork 了主储存库,那么下面你应该这么做:
1. 将你的仓库 clone 到本地;
2. 在你的 IDE 或 终端 内执行 Gradle 的 `applyPatches` 任务,如果是在终端内,你可以执行 `./gradlew applyPatches`
3. 进入 `luminol-api` 文件夹进行修改。
顺便一提,`luminol-api` 并不是正常的 git 仓库:
- 在应用补丁前,基点将会指向未被更改的源码
- 在基点后的每一个提交都是一个补丁
- 只有在 Folia 最后一个提交后的提交才会被视为 luminol 补丁
## 增加补丁
按照以下步骤增加一个补丁是非常简单的:
1.`luminol-api` 进行修改;
2. 使用 git 添加你的修改,比如 `git add .`
3. 使用 `git commit -m <提交信息>` 进行提交;
4. 运行 Gradle 任务 `rebuildPatches` 将你的提交转化为一个补丁;
5. 将你生成的补丁文件进行推送。
这样做以后,你就可以将你的补丁文件进行 PR 提交。
## 修改补丁
你可以使用以下方法来修改一个补丁的内容:
1. 在 HEAD 上直接进行修改;
2. 使用 `git commit -a --fixup <hash>` 来进行一个更正提交;
- 如果你想要更改提交信息,你也可以用 `--squash` 来代替 `--fixup`
3. 使用 `git rebase -i --autosquash base` 来进行自动变基,你只需要输入 `:q` 来关闭确认页面即可;
4. 运行 Gradle 任务 `rebuildPatches` 来修改已被修改的补丁;
5. 将修改后的补丁 PR 发回储存库。

70
docs/CONTRIBUTING_EN.md Normal file
View File

@@ -0,0 +1,70 @@
Contributing to Luminol
===========
**English** | [中文](./CONTRIBUTING.md)
We're glad that you want to contribute to our project!
In general, our review of pull requests is very lenient.
And if you can follow the rules below, we can complete the review faster.
## Please fork using your personal account
We regularly merge existing PRs.
If there're some small problems, we'll help you solve them by editing your PR.
But, if your PR is from a organization, we can NOT edit your PR, so we must merge your PR manually.
So, don't use orgnization accounts for fork!
See also [This issue](https://github.com/isaacs/github/issues/1681), and then you'll know why we can't edit PRs from organizations.
## Development Environment
Before coding, you need these softwares / tools as Dev Environment.
- `git`
- `JDK 17 or higher`
## Understanding "Patches"
Luminol uses as the same patching system as Paper,
and has been divided into two directories for the purpose of modifying different parts of it:
- `luminol-api` - Modifications to `Folia-API` / `Paper-API` / `Spigot-API` / `Bukkit`.
The patching system is based on git, and you can learn about it at here: <https://git-scm.com/docs/gittutorial>
If you have forked the main repository, then you should follow the steps below:
1. Clone your repository to local
2. Run Gradle's `applyPatches` task in your IDE or terminal (You can run `./gradlew applyPatches` directly in terminal.)
3. Enter `luminol-api` directory to carry out modifications.
BTW, `luminol-api` and are not normal git repositories.
- Before applying patches, the base will point to unmodified source code.
- Every commit after the base is a patch.
- Only commits after the last commit of Paper will be considered Luminol' patches.
## Adding new patches
It's very easy to to add patches by following the steps below:
1. Modify the code of `luminol-api`
2. Add these changes to the local git repository (For example, `git add .`)
3. Commit these changes using `git commit -m <Commit Message>`
4. Run Gradle's task `rebuildPatches` to convert your commits to a new patch
5. Push your patches to your repository
After pushing, you can open a PR to submit your patches.
## Modifying patches
You can modify a existing patch by following the steps below:
1. Modify code at HEAD
2. Run `git commit -a --fixup <hash>` in your terminal to make a fix-up commit
- If you want to edit the commit message, replace `--fixup` with `--squash`.
3. Run `git rebase -i --autosquash base` to rebase automatically, then just type `:q` to close the confirm page
4. Run Gradle's task `rebuildPatches` to modify existing patches
5. Push and PR again

View File

@@ -1,9 +1,13 @@
group = me.earthme.luminol
version = 1.20.2-R0.1-SNAPSHOT
version = 1.20.6-R0.1-SNAPSHOT
foliaCommit = 1e5e2154c9f88d788cecf0b9fcc77ece7d1f8663
foliaCommit = 9a19e4286c04bc01b9d7bc005cf66f8cc2dd49ff
org.gradle.caching = true
org.gradle.parallel = true
org.gradle.vfs.watch = false
org.gradle.jvmargs = -Xmx3G
mcVersion = 1.20.6
GroupMCV = 1.20
preVersion = false

Binary file not shown.

View File

@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

29
gradlew vendored
View File

@@ -83,10 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -133,10 +131,13 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
@@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \

20
gradlew.bat vendored
View File

@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 18:04:47 +0800
Subject: [PATCH] Added maven publish
diff --git a/build.gradle.kts b/build.gradle.kts
index 639651972fddce4dff63a0f0a7e566a15b9e2dd6..890820cb36e4cadeadb4c2d7cd961a73b065a217 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -168,3 +168,23 @@ tasks.check {
dependsOn(scanJar)
}
// Paper end
+
+// Luminol start
+publishing {
+ repositories {
+ maven {
+ name = "githubPackage"
+ url = uri("https://maven.pkg.github.com/LuminolMC/Luminol")
+
+ credentials.username = System.getenv("GITHUB_USERNAME")
+ credentials.password = System.getenv("GITHUB_TOKEN")
+ }
+
+ publications {
+ register<MavenPublication>("gpr") {
+ from(components["java"])
+ }
+ }
+ }
+}
+// Luminol end
\ No newline at end of file

View File

@@ -0,0 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Tue, 21 May 2024 21:31:53 +0800
Subject: [PATCH] Rebrand to Luminol
diff --git a/src/main/java/io/papermc/paper/ServerBuildInfo.java b/src/main/java/io/papermc/paper/ServerBuildInfo.java
index 9df9d09aa477d4cd3c496ba0933c816df1ef0964..b8a5e4f02499e3a3c370d43f6bbb84ffba58e1f3 100644
--- a/src/main/java/io/papermc/paper/ServerBuildInfo.java
+++ b/src/main/java/io/papermc/paper/ServerBuildInfo.java
@@ -18,6 +18,13 @@ public interface ServerBuildInfo {
*/
Key BRAND_PAPER_ID = Key.key("papermc", "paper");
+ // Luminol start
+ /**
+ * The brand id for Luminol.
+ */
+ Key BRAND_LUMINOL_ID = Key.key("luminolmc", "luminol");
+ // Luminol end
+
/**
* Gets the {@code ServerBuildInfo}.
*

View File

@@ -1,506 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Tue, 30 Jan 2024 09:03:08 +0000
Subject: [PATCH] Leaves fakeplayer API
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index b7e1c8bd8dd38e1a9e74925740b22dad61a75f49..5ee1ba3847599ac67b5cd8ca26e61b1231c45dcd 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -58,6 +58,7 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import io.papermc.paper.util.JarManifests; // Paper
+import top.leavesmc.leaves.entity.BotManager;
/**
* Represents the Bukkit core, for version and Server singleton handling
@@ -2836,6 +2837,17 @@ public final class Bukkit {
}
// Folia end - region threading API
+ // Leaves start - Bot API
+ /**
+ * Returns a bot manager.
+ *
+ * @return Bot Manager
+ */
+ public static @NotNull BotManager getBotManager() {
+ return server.getBotManager();
+ }
+ // Leaves end - Bot API
+
@NotNull
public static Server.Spigot spigot() {
return server.spigot();
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 85b169c04f44431363d4e14d4857140f160ceace..9e12552aca127892d122a2616d303d3cdfc67416 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -58,6 +58,7 @@ import org.bukkit.util.CachedServerIcon;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import top.leavesmc.leaves.entity.BotManager;
/**
* Represents a server implementation.
@@ -2479,4 +2480,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/
public boolean isGlobalTickThread();
// Folia end - region threading API
+
+
+ // Leaves start - Bot API
+ /**
+ * Returns a bot manager.
+ *
+ * @return Bot Manager
+ */
+ @NotNull BotManager getBotManager();
+ // Leaves end - Bot API
}
diff --git a/src/main/java/top/leavesmc/leaves/entity/Bot.java b/src/main/java/top/leavesmc/leaves/entity/Bot.java
new file mode 100644
index 0000000000000000000000000000000000000000..8816683c795f9be6a4f112203cfac3f59d8faba5
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/entity/Bot.java
@@ -0,0 +1,46 @@
+package top.leavesmc.leaves.entity;
+
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import top.leavesmc.leaves.entity.botaction.LeavesBotAction;
+
+/**
+ * Represents a fakeplayer
+ */
+public interface Bot extends Player {
+
+ /**
+ * Gets the fakeplayer skin
+ *
+ * @return fakeplayer skin name
+ */
+ @Nullable
+ public String getSkinName();
+
+ /**
+ * Gets the fakeplayer name without prefix and suffix
+ *
+ * @return fakeplayer real name
+ */
+ @NotNull
+ public String getRealName();
+
+ /**
+ * Sets the fakeplayer action with args.
+ *
+ * @param action action name
+ * @param player player who create this action
+ * @param args passed action arguments
+ */
+ public boolean setBotAction(@NotNull String action, @NotNull Player player, @NotNull String[] args);
+
+ /**
+ * Sets the fakeplayer action with args.
+ *
+ * @param action leaves bot action
+ * @param player player who create this action
+ * @param args passed action arguments
+ */
+ public boolean setBotAction(@NotNull LeavesBotAction action, @NotNull Player player, @NotNull String[] args);
+}
diff --git a/src/main/java/top/leavesmc/leaves/entity/BotManager.java b/src/main/java/top/leavesmc/leaves/entity/BotManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..f2258027b2ed4bfcf7feda2e9075b1a1a05a85b6
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/entity/BotManager.java
@@ -0,0 +1,107 @@
+package top.leavesmc.leaves.entity;
+
+import org.bukkit.Location;
+import org.bukkit.util.Consumer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import top.leavesmc.leaves.entity.botaction.CustomBotAction;
+
+import java.util.Collection;
+import java.util.UUID;
+
+/**
+ * Simple fakeplayer manager
+ */
+public interface BotManager {
+
+ /**
+ * Gets a fakeplayer object by the given uuid.
+ *
+ * @param uuid the uuid to look up
+ * @return a fakeplayer if one was found, null otherwise
+ */
+ @Nullable
+ public Bot getBot(@NotNull UUID uuid);
+
+ /**
+ * Gets a fakeplayer object by the given name.
+ *
+ * @param name the name to look up
+ * @return a fakeplayer if one was found, null otherwise
+ */
+ @Nullable
+ public Bot getBot(@NotNull String name);
+
+ /**
+ * Creates a fakeplayer with given param.
+ * <p>
+ * prefix and suffix will not be added.
+ *
+ * @param name fakeplayer name
+ * @param realName fakeplayer real name
+ * @param skin fakeplayer skin arr
+ * @param skinName fakeplayer skin name
+ * @param location a location will create fakeplayer
+ * @return a fakeplayer if success, null otherwise
+ */
+ @Nullable
+ public Bot createBot(@NotNull String name, @NotNull String realName, @Nullable String[] skin, @Nullable String skinName, @NotNull Location location);
+
+ /**
+ * Creates a fakeplayer with given param.
+ *
+ * @param name fakeplayer name
+ * @param skinName fakeplayer skin name
+ * @param location a location will create fakeplayer
+ * @param consumer a consumer after create fakeplayer success
+ */
+ public void createBot(@NotNull String name, @Nullable String skinName, @NotNull Location location, @Nullable Consumer<Bot> consumer);
+
+ /**
+ * Removes a fakeplayer object by the given name.
+ *
+ * @param name the name to look up
+ */
+ public void removeBot(@NotNull String name);
+
+ /**
+ * Removes a fakeplayer object by the given uuid.
+ *
+ * @param uuid the uuid to look up
+ */
+ public void removeBot(@NotNull UUID uuid);
+
+ /**
+ * Removes all fakeplayers.
+ */
+ public void removeAllBots();
+
+ /**
+ * Save fakeplayers data if resident-fakeplayer is true, or remove all fakeplayer.
+ */
+ public void saveOrRemoveAllBots();
+
+ /**
+ * Gets a view of all currently logged in fakeplayers. This view is a reused object, making some operations like Collection.size() zero-allocation.
+ *
+ * @return a view of fakeplayers.
+ */
+ public Collection<Bot> getBots();
+
+ /**
+ * Register a custom bot action.
+ *
+ * @param name action name
+ * @param action action executor
+ * @return true if success, or false
+ */
+ public boolean registerCustomBotAction(String name, CustomBotAction action);
+
+ /**
+ * Unregister a custom bot action.
+ *
+ * @param name action name
+ * @return true if success, or false
+ */
+ public boolean unregisterCustomBotAction(String name);
+}
diff --git a/src/main/java/top/leavesmc/leaves/entity/botaction/CustomBotAction.java b/src/main/java/top/leavesmc/leaves/entity/botaction/CustomBotAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..7abf4eef22e40468929e724ebc07a97b0b2a05f3
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/entity/botaction/CustomBotAction.java
@@ -0,0 +1,52 @@
+package top.leavesmc.leaves.entity.botaction;
+
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import top.leavesmc.leaves.entity.Bot;
+
+import java.util.List;
+
+/**
+ * Represents a class which contains methods for a custom bot action
+ */
+public interface CustomBotAction {
+
+ /**
+ * Executes the action, returning its success.
+ *
+ * @param bot bot of the action
+ * @return true if once action finish, otherwise false
+ */
+ public boolean doTick(Bot bot);
+
+ /**
+ * Created a new action instance.
+ *
+ * @param player player who create this action
+ * @param args passed action arguments
+ * @return a new action instance with given args
+ */
+ public @Nullable CustomBotAction getNew(Player player, String[] args);
+
+ /**
+ * Requests a list of possible completions for a action argument.
+ *
+ * @return A List of a List of possible completions for the argument.
+ */
+ public @NotNull List<List<String>> getTabComplete();
+
+ /**
+ * Return a ticks to wait between {@link CustomBotAction#doTick(Bot)}
+ *
+ * @return the ticks to wait between runs
+ */
+ public int getTickDelay();
+
+ /**
+ * Return a number of times {@link CustomBotAction#doTick(Bot)} can return true
+ *
+ * @return the number of times an action can be executed
+ */
+ public int getNumber();
+}
diff --git a/src/main/java/top/leavesmc/leaves/entity/botaction/LeavesBotAction.java b/src/main/java/top/leavesmc/leaves/entity/botaction/LeavesBotAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..e298722319ff0cfd52e531693ea3767e5f9a3d52
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/entity/botaction/LeavesBotAction.java
@@ -0,0 +1,32 @@
+package top.leavesmc.leaves.entity.botaction;
+
+/**
+ * A Leaves bot action enum
+ */
+public enum LeavesBotAction {
+ ATTACK("attack"),
+ ATTACK_SELF("attack_self"),
+ BREAK("break"),
+ DROP("drop"),
+ FISH("fish"),
+ JUMP("jump"),
+ LAY("lay"),
+ LOOK("look"),
+ ROTATE("rotate"),
+ SNEAK("sneak"),
+ STOP("stop"),
+ SWIM("swim"),
+ USE("use"),
+ USE_ON("use_on"),
+ USE_TO("use_to");
+
+ private final String name;
+
+ private LeavesBotAction(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/event/bot/BotCreateEvent.java b/src/main/java/top/leavesmc/leaves/event/bot/BotCreateEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..7cf1eb4eb3d2fe9310f9272ec53208632b87b49b
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/event/bot/BotCreateEvent.java
@@ -0,0 +1,106 @@
+package top.leavesmc.leaves.event.bot;
+
+import org.bukkit.Location;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Call when a fakeplayer creates a server
+ */
+public class BotCreateEvent extends Event implements Cancellable {
+ private static final HandlerList handlers = new HandlerList();
+
+ private final String bot;
+ private final String skin;
+ private String joinMessage;
+ private Location createLocation;
+ private boolean cancel = false;
+
+ public BotCreateEvent(@NotNull final String who, @NotNull final String skin, @NotNull final Location createLocation, @Nullable final String joinMessage) {
+ this.bot = who;
+ this.skin = skin;
+ this.joinMessage = joinMessage;
+ this.createLocation = createLocation;
+ }
+
+ /**
+ * Gets the fakeplayer name
+ *
+ * @return fakeplayer name
+ */
+ public String getBot() {
+ return bot;
+ }
+
+ /**
+ * Gets the join message to send to all online players
+ *
+ * @return string join message. Can be null
+ */
+ @Nullable
+ public String getJoinMessage() {
+ return joinMessage;
+ }
+
+ /**
+ * Sets the join message to send to all online players
+ *
+ * @param joinMessage join message. If null, no message will be sent
+ */
+ public void setJoinMessage(@Nullable String joinMessage) {
+ this.joinMessage = joinMessage;
+ }
+
+ /**
+ * Gets the location to create the fakeplayer
+ *
+ * @return Location to create the fakeplayer
+ */
+ @NotNull
+ public Location getCreateLocation() {
+ return createLocation;
+ }
+
+ /**
+ * Sets the location to create the fakeplayer
+ *
+ * @param createLocation location to create the fakeplayer
+ */
+ public void setCreateLocation(@NotNull Location createLocation) {
+ this.createLocation = createLocation;
+ }
+
+ /**
+ * Gets the fakeplayer skin
+ *
+ * @return fakeplayer skin name
+ */
+ @Nullable
+ public String getSkin() {
+ return skin;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancel;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancel = cancel;
+ }
+
+ @Override
+ @NotNull
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/event/bot/BotEvent.java b/src/main/java/top/leavesmc/leaves/event/bot/BotEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..4a4fe07ce965d4a97e0d8105a91310dac7d1343c
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/event/bot/BotEvent.java
@@ -0,0 +1,31 @@
+package top.leavesmc.leaves.event.bot;
+
+import org.bukkit.event.Event;
+import org.jetbrains.annotations.NotNull;
+import top.leavesmc.leaves.entity.Bot;
+
+/**
+ * Represents a fakeplayer related event
+ */
+public abstract class BotEvent extends Event {
+ protected Bot bot;
+
+ public BotEvent(@NotNull final Bot who) {
+ bot = who;
+ }
+
+ public BotEvent(@NotNull final Bot who, boolean async) { // Paper - public
+ super(async);
+ bot = who;
+ }
+
+ /**
+ * Returns the fakeplayer involved in this event
+ *
+ * @return Fakeplayer who is involved in this event
+ */
+ @NotNull
+ public final Bot getBot() {
+ return bot;
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/event/bot/BotJoinEvent.java b/src/main/java/top/leavesmc/leaves/event/bot/BotJoinEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..10afa5c7fd4ee8a4e72d64f8ca9bf8731ec2ad61
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/event/bot/BotJoinEvent.java
@@ -0,0 +1,27 @@
+package top.leavesmc.leaves.event.bot;
+
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+import top.leavesmc.leaves.entity.Bot;
+
+/**
+ * Called when a fakeplayer joins a server
+ */
+public class BotJoinEvent extends BotEvent {
+ private static final HandlerList handlers = new HandlerList();
+
+ public BotJoinEvent(@NotNull Bot who) {
+ super(who);
+ }
+
+ @Override
+ @NotNull
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}

View File

@@ -0,0 +1,101 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Fri, 9 Feb 2024 03:32:05 +0000
Subject: [PATCH] Threaded region start tick and finished tick event
diff --git a/src/main/java/me/earthme/luminol/api/events/TickRegionFinishedTickEvent.java b/src/main/java/me/earthme/luminol/api/events/TickRegionFinishedTickEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..29b98728d3ca4a439c6b3333cd123c0e0b8a2846
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/api/events/TickRegionFinishedTickEvent.java
@@ -0,0 +1,42 @@
+package me.earthme.luminol.api.events;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Called when a region finished its tick task.
+ */
+public class TickRegionFinishedTickEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+
+ private final long currTime;
+ private final long regionId;
+
+ public TickRegionFinishedTickEvent(long currTime, long regionId) {
+ this.currTime = currTime;
+ this.regionId = regionId;
+ }
+
+ /**
+ * Get the time of tick end
+ * @return The time of tick end in nanoseconds
+ */
+ public long getFinishedTime() {
+ return this.currTime;
+ }
+
+ /**
+ * Get the id of current region
+ * Notice: The id of global region is -1 in this event
+ * @return The id of current region
+ */
+ public long getRegionId() {
+ return this.regionId;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/api/events/TickRegionStartTickEvent.java b/src/main/java/me/earthme/luminol/api/events/TickRegionStartTickEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f3cba43ebd873965c24b96ca116abfb149ab4e6
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/api/events/TickRegionStartTickEvent.java
@@ -0,0 +1,41 @@
+package me.earthme.luminol.api.events;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Called when a tick was started.
+ */
+public class TickRegionStartTickEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private final long currTime;
+ private final long regionId;
+
+ public TickRegionStartTickEvent(long currTime, long regionId) {
+ this.currTime = currTime;
+ this.regionId = regionId;
+ }
+
+ /**
+ * Get the id of current region
+ * Notice: The id of global region is -1 in this event
+ * @return The id of current region
+ */
+ public long getRegionId() {
+ return this.regionId;
+ }
+
+ /**
+ * Get the time of tick start
+ * @return The time of tick start in nanoseconds
+ */
+ public long getStartTime(){
+ return this.currTime;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return handlers;
+ }
+}

View File

@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Sat, 27 Apr 2024 13:22:59 +0000
Subject: [PATCH] KioCG Chunk API
diff --git a/src/main/java/org/bukkit/Chunk.java b/src/main/java/org/bukkit/Chunk.java
index bc8b5bc17706250b8535b1b309134843d2ce2bb1..1cfe84ad1094e3c4fab96487f328be53e035a64c 100644
--- a/src/main/java/org/bukkit/Chunk.java
+++ b/src/main/java/org/bukkit/Chunk.java
@@ -389,4 +389,6 @@ public interface Chunk extends PersistentDataHolder {
*/
UNLOADED;
}
+
+ long getChunkHotAvg(); // KioCG
}
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index eb34f22e973fe46529eb93f435f5bf7f85091404..b2d23eeb24d1132607cf68c2a6eec352db321fa2 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -3854,4 +3854,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
@Override
Spigot spigot();
// Spigot end
+
+ long getNearbyChunkHot(); // KioCG
}

View File

@@ -0,0 +1,68 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Tue, 30 Jul 2024 17:58:25 +0800
Subject: [PATCH] FoliaPR Add TPS From Region
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 15049641b8123abf03edcbb49257fb4f3db0a5ec..0492d5738a7168b68b60dcbb24a09946a640a1a1 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -2397,6 +2397,28 @@ public final class Bukkit {
}
// Paper end
+ // Folia start
+ /**
+ * Gets the current location TPS.
+ *
+ * @param location the location for which to get the TPS
+ * @return current location TPS (5s, 15s, 1m, 5m, 15m in Folia-Server), or null if the region doesn't exist
+ */
+ public double @Nullable [] getTPS(Location location) {
+ return server.getTPS(location);
+ }
+
+ /**
+ * Gets the current chunk TPS.
+ *
+ * @param chunk the chunk for which to get the TPS
+ * @return current chunk TPS (5s, 15s, 1m, 5m, 15m in Folia-Server), or null if the region doesn't exist
+ */
+ public double @Nullable [] getTPS(Chunk chunk){
+ return server.getTPS(chunk);
+ }
+ // Folia end
+
/**
* Get the advancement specified by this key.
*
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 1f51f80e8516cfac7ed4078ed96e535389a31f25..d5c89a7a63239e6403f1fa1429d8f5a9802883b1 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -2050,6 +2050,24 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
double getAverageTickTime();
// Paper end
+ // Folia start
+ /**
+ * Gets the current location TPS.
+ *
+ * @param location the location for which to get the TPS
+ * @return current location TPS (5s, 15s, 1m, 5m, 15m in Folia-Server), or null if the region doesn't exist
+ */
+ public double @Nullable [] getTPS(Location location);
+
+ /**
+ * Gets the current chunk TPS.
+ *
+ * @param chunk the chunk for which to get the TPS
+ * @return current chunk TPS (5s, 15s, 1m, 5m, 15m in Folia-Server), or null if the region doesn't exist
+ */
+ public double @Nullable [] getTPS(Chunk chunk);
+ // Folia end
+
// Paper start
/**
* Gets the active {@link org.bukkit.command.CommandMap}

View File

@@ -1,28 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 08:20:14 +0800
From: MrHua269 <novau233@163.com>
Date: Mon, 1 Jan 2024 07:59:27 +0000
Subject: [PATCH] Fix build
diff --git a/build.gradle.kts b/build.gradle.kts
index 0cd12a854e544e867abfd94c18a9f138ba57e587..d295ee01481b088a376691de7c0927e95d7a68a8 100644
index eb2f9941b24af591f1e56339b97f5284a765cf81..32bfe781e5298e5ad1bd2ed4471fb824c49f0ab4 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -14,7 +14,7 @@ val alsoShade: Configuration by configurations.creating
@@ -13,7 +13,7 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) {
val alsoShade: Configuration by configurations.creating
dependencies {
// Folia start
- implementation(project(":folia-api"))
+ implementation(project(":luminol-api")) //Luminol
implementation("io.papermc.paper:paper-mojangapi:${project.version}") {
exclude("io.papermc.paper", "paper-api")
}
@@ -74,7 +74,7 @@ tasks.jar {
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",
"Implementation-Title" to "CraftBukkit",
- "Implementation-Version" to "git-Folia-$implementationVersion", // Folia
+ "Implementation-Version" to "git-Luminol-$implementationVersion", // Folia //Luminol
"Implementation-Vendor" to date, // Paper
"Specification-Title" to "Bukkit",
"Specification-Version" to project.version,
- implementation(project(":folia-api")) // Folia
+ implementation(project(":luminol-api")) // Folia // Luminol
// Paper start
implementation("org.jline:jline-terminal-jansi:3.21.0")
implementation("net.minecrell:terminalconsoleappender:1.3.0")

File diff suppressed because it is too large Load Diff

View File

@@ -1,179 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 10:40:56 +0800
Subject: [PATCH] Added empty luminol config
diff --git a/build.gradle.kts b/build.gradle.kts
index d295ee01481b088a376691de7c0927e95d7a68a8..54d761d7e4733c12fbb4957acd509d278ae11316 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -19,6 +19,7 @@ dependencies {
exclude("io.papermc.paper", "paper-api")
}
// Folia end
+ implementation("com.electronwill.night-config:toml:3.6.0") //Luminol - Night config
// Paper start
implementation("org.jline:jline-terminal-jansi:3.21.0")
implementation("net.minecrell:terminalconsoleappender:1.3.0")
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f9ff0fc33fa36c90fc4cbbd21b7b790de581632
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -0,0 +1,99 @@
+package me.earthme.luminol;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import net.minecraft.server.level.ServerLevel;
+
+import java.io.File;
+import java.io.IOException;
+
+public class LuminolConfig {
+ private static final File PARENT_FOLDER = new File("luminol_config");
+ private static final File MAIN_CONFIG_FILE = new File(PARENT_FOLDER,"luminol_global.toml");
+ private static CommentedFileConfig MAIN_CONFIG;
+
+ public static String serverModName = "Luminol";
+ public static boolean fakeVanillaModeEnabled = false;
+
+ public static void init() throws IOException {
+ PARENT_FOLDER.mkdir();
+
+ if (!MAIN_CONFIG_FILE.exists()){
+ MAIN_CONFIG_FILE.createNewFile();
+ }
+
+ MAIN_CONFIG = CommentedFileConfig.ofConcurrent(MAIN_CONFIG_FILE);
+
+ MAIN_CONFIG.load();
+ initValues();
+ MAIN_CONFIG.save();
+ }
+
+ public static void initValues(){
+ serverModName = get("misc.server_mod_name",serverModName,"The servermod name will be sent to players,and you can see it in F3 or motd responses");
+ fakeVanillaModeEnabled = get("misc.enable_fake_vanilla_mode",fakeVanillaModeEnabled,"Enable this to make the ping response of your server like a vanilla server");
+ }
+
+ public static <T> T get(String key,T def){
+ if (MAIN_CONFIG.contains(key)){
+ return MAIN_CONFIG.get(key);
+ }
+
+ MAIN_CONFIG.set(key,def);
+ return def;
+ }
+
+ public static <T> T get(String key,T def,String comment){
+ MAIN_CONFIG.setComment(key,comment);
+
+ if (MAIN_CONFIG.contains(key)){
+ return MAIN_CONFIG.get(key);
+ }
+
+ MAIN_CONFIG.set(key,def);
+ return def;
+ }
+
+ public static class LumionalWorldConfig{
+ private final File configFile;
+ private CommentedFileConfig commentedFileConfig;
+
+ public LumionalWorldConfig(ServerLevel level) {
+ this.configFile = new File(PARENT_FOLDER,"luminol_world_"+level.getWorld().getName()+".toml");
+ }
+
+ public void init() throws IOException {
+ if (!this.configFile.exists()){
+ this.configFile.createNewFile();
+ }
+
+ this.commentedFileConfig = CommentedFileConfig.ofConcurrent(this.configFile);
+ this.commentedFileConfig.load();
+ this.initValues();
+ this.commentedFileConfig.save();
+ }
+
+ public void initValues(){
+
+ }
+
+ public <T> T get(String key,T def,String comment){
+ this.commentedFileConfig.setComment(key,comment);
+
+ if (this.commentedFileConfig.contains(key)){
+ return this.commentedFileConfig.get(key);
+ }
+
+ this.commentedFileConfig.set(key,def);
+ return def;
+ }
+
+ public <T> T get(String key,T def){
+ if (this.commentedFileConfig.contains(key)){
+ return this.commentedFileConfig.get(key);
+ }
+
+ this.commentedFileConfig.set(key,def);
+ return def;
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 05d8cabd2294456e3c8df60265f8b035990dd896..f0bf57a7acd77eeffbeeb6743ba58166823022fd 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -19,6 +19,8 @@ import java.util.Locale;
import java.util.Optional;
import java.util.function.BooleanSupplier;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.DefaultUncaughtExceptionHandler;
import net.minecraft.DefaultUncaughtExceptionHandlerWithName;
import net.minecraft.SharedConstants;
@@ -206,6 +208,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
// Spigot end
// Paper start
io.papermc.paper.util.ObfHelper.INSTANCE.getClass(); // Paper - load mappings for stacktrace deobf and etc.
+ LuminolConfig.init(); //Luminol
paperConfigurations.initializeGlobalConfiguration();
paperConfigurations.initializeWorldDefaultsConfiguration();
// Paper start - moved up to right after PlayerList creation but before file load/save
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 724aa1d8147ea2fb5e46d291adacfb7e1f5b5f62..e274c501e2455845f6f9a4614802336205362b69 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -38,6 +38,8 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.CrashReport;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
@@ -766,6 +768,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
// Folia end - region threading
+ public final LuminolConfig.LumionalWorldConfig lumionalWorldConfig; //Luminol
+
// Add env and gen to constructor, IWorldDataServer -> WorldDataServer
public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey<Level> resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List<CustomSpawner> list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
// IRegistryCustom.Dimension iregistrycustom_dimension = minecraftserver.registryAccess(); // CraftBukkit - decompile error
@@ -850,6 +854,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.chunkTaskScheduler = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler(this, io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.workerThreads); // Paper - rewrite chunk system
this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system
this.updateTickData(); // Folia - region threading - make sure it is initialised before ticked
+ this.lumionalWorldConfig = new LuminolConfig.LumionalWorldConfig(this);
+ try {
+ this.lumionalWorldConfig.init();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to create luminol config for level "+ this.getWorld().getName()+"!",e);
+ }
}
// Folia start - region threading

View File

@@ -0,0 +1,429 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 00:45:19 +0000
Subject: [PATCH] Empty config file base
diff --git a/build.gradle.kts b/build.gradle.kts
index f9919b9da90317bd615d7e57607df73ebcc1d077..ab07c307bea0d3b79a6239bdcca9714e1ddf3b28 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -14,6 +14,7 @@ val alsoShade: Configuration by configurations.creating
dependencies {
implementation(project(":luminol-api")) // Folia // Luminol
+ implementation("com.electronwill.night-config:toml:3.6.6") // Luminol - Night config
// Paper start
implementation("org.jline:jline-terminal-jansi:3.21.0")
implementation("net.minecrell:terminalconsoleappender:1.3.0")
diff --git a/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java b/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c8745dffa80cf47e856d04d283937bda86881f8
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java
@@ -0,0 +1,70 @@
+package me.earthme.luminol.commands;
+
+import me.earthme.luminol.config.LuminolConfig;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import org.bukkit.Location;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LuminolConfigCommand extends Command {
+ public LuminolConfigCommand(){
+ super("luminolconfig");
+ this.setPermission("luminol.commands.luminolconfig");
+ this.setDescription("Manage config file");
+ this.setUsage("/luminolconfig");
+ }
+
+ @Override
+ public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args, @Nullable Location location) throws IllegalArgumentException {
+ final List<String> result = new ArrayList<>();
+
+ if (args.length == 1){
+ result.add("reload");
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
+ if (!this.testPermission(sender)){
+ sender.sendMessage(Component
+ .text("No permission to execute this command!")
+ .color(TextColor.color(255,0,0))
+ );
+ }
+
+ if (args.length < 1){
+ sender.sendMessage(
+ Component
+ .text("Wrong use!\n")
+ .color(TextColor.color(255,0,0))
+ );
+ return true;
+ }
+
+ switch (args[0]){
+ case "reload" -> {
+ LuminolConfig.reloadAsync().thenAccept(nullValue -> sender.sendMessage(
+ Component
+ .text("Reloaded config file!")
+ .color(TextColor.color(0,255,0))
+ ));
+ }
+
+ default -> sender.sendMessage(
+ Component
+ .text("Unknown action!\n")
+ .color(TextColor.color(255,0,0))
+ );
+ }
+
+ return true;
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/ConfigInfo.java b/src/main/java/me/earthme/luminol/config/ConfigInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..01b64c2cf6b437114337626c242e1da3fbdb8ead
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/ConfigInfo.java
@@ -0,0 +1,11 @@
+package me.earthme.luminol.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ConfigInfo {
+ String baseName();
+
+ String comments() default "";
+}
diff --git a/src/main/java/me/earthme/luminol/config/DoNotLoad.java b/src/main/java/me/earthme/luminol/config/DoNotLoad.java
new file mode 100644
index 0000000000000000000000000000000000000000..fffc5eb4be4b78a886f3c340bd60f3a2b0108a7d
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/DoNotLoad.java
@@ -0,0 +1,8 @@
+package me.earthme.luminol.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DoNotLoad {
+}
diff --git a/src/main/java/me/earthme/luminol/config/EnumConfigCategory.java b/src/main/java/me/earthme/luminol/config/EnumConfigCategory.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b75405c468d24ed8aea5aa54ae5ac339118bf60
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/EnumConfigCategory.java
@@ -0,0 +1,19 @@
+package me.earthme.luminol.config;
+
+public enum EnumConfigCategory {
+ OPTIMIZATIONS("optimizations"),
+ FIXES("fixes"),
+ MISC("misc"),
+ GAMEPLAY("gameplay"),
+ EXPERIMENT("experiment");
+
+ private final String baseKeyName;
+
+ EnumConfigCategory(String baseKeyName) {
+ this.baseKeyName = baseKeyName;
+ }
+
+ public String getBaseKeyName() {
+ return this.baseKeyName;
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/HotReloadUnsupported.java b/src/main/java/me/earthme/luminol/config/HotReloadUnsupported.java
new file mode 100644
index 0000000000000000000000000000000000000000..559c11cb523c7cade34a0abfad15c988f5ad87fe
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/HotReloadUnsupported.java
@@ -0,0 +1,8 @@
+package me.earthme.luminol.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HotReloadUnsupported {
+}
diff --git a/src/main/java/me/earthme/luminol/config/IConfigModule.java b/src/main/java/me/earthme/luminol/config/IConfigModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f6896711907ac30fe0c00130207b970007e4bb4
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/IConfigModule.java
@@ -0,0 +1,22 @@
+package me.earthme.luminol.config;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import org.jetbrains.annotations.NotNull;
+
+public interface IConfigModule {
+
+ EnumConfigCategory getCategory();
+
+ String getBaseName();
+
+ default void onLoaded(CommentedFileConfig configInstance) {}
+
+ default <T> T get(String keyName, T defaultValue, @NotNull CommentedFileConfig config){
+ if (!config.contains(keyName)){
+ config.set(keyName,defaultValue);
+ return defaultValue;
+ }
+
+ return config.get(keyName);
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/LuminolConfig.java b/src/main/java/me/earthme/luminol/config/LuminolConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b4e64796bf01b0a5fcb306850cd60837ed4d36b
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/LuminolConfig.java
@@ -0,0 +1,218 @@
+package me.earthme.luminol.config;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import io.papermc.paper.threadedregions.RegionizedServer;
+import me.earthme.luminol.commands.LuminolConfigCommand;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class LuminolConfig {
+ public static final Logger logger = LogManager.getLogger();
+ private static final File baseConfigFolder = new File("luminol_config");
+ private static final File baseConfigFile = new File(baseConfigFolder,"luminol_global_config.toml");
+ private static final Set<IConfigModule> allInstanced = new HashSet<>();
+ private static CommentedFileConfig configFileInstance;
+ public static boolean alreadyInited = false;
+ private static MinecraftInternalPlugin NULL_PLUGIN = new MinecraftInternalPlugin();
+
+ public static void setupLatch(){
+ Bukkit.getCommandMap().register("luminolconfig","luminol",new LuminolConfigCommand());
+ alreadyInited = true;
+ }
+
+ public static void reload(){
+ RegionizedServer.ensureGlobalTickThread("Reload luminol config off global region thread!");
+
+ dropAllInstanced();
+ try {
+ loadConfig();
+ }catch (Exception e){
+ logger.error(e);
+ }
+ }
+
+ @Contract(" -> new")
+ public static @NotNull CompletableFuture<Void> reloadAsync(){
+ return CompletableFuture.runAsync(LuminolConfig::reload,task -> Bukkit.getGlobalRegionScheduler().run(NULL_PLUGIN,scheduled -> task.run()));
+ }
+
+ public static void dropAllInstanced(){
+ allInstanced.clear();
+ }
+
+ public static void loadConfig() throws IOException {
+ baseConfigFolder.mkdirs();
+
+ if (!baseConfigFile.exists()){
+ baseConfigFile.createNewFile();
+ }
+
+ configFileInstance = CommentedFileConfig.ofConcurrent(baseConfigFile);
+
+ configFileInstance.load();
+
+ try {
+ instanceAllModule();
+ loadAllModules();
+ }catch (Exception e){
+ logger.error("Failed to load config modules!",e);
+ }
+
+ configFileInstance.save();
+ }
+
+ private static void loadAllModules() throws IllegalAccessException {
+ for (IConfigModule instanced : allInstanced){
+ loadForSingle(instanced);
+ }
+ }
+
+ private static void instanceAllModule() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
+ for (Class<?> clazz : getClasses("me.earthme.luminol.config.modules")){
+ if (IConfigModule.class.isAssignableFrom(clazz)){
+ allInstanced.add((IConfigModule) clazz.getConstructor().newInstance());
+ }
+ }
+ }
+
+ private static void loadForSingle(@NotNull IConfigModule singleConfigModule) throws IllegalAccessException {
+ final EnumConfigCategory category = singleConfigModule.getCategory();
+
+ Field[] fields = singleConfigModule.getClass().getDeclaredFields();
+
+ for (Field field : fields) {
+ int modifiers = field.getModifiers();
+ if (Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
+ boolean skipLoad = field.getAnnotation(DoNotLoad.class) != null || (alreadyInited && field.getAnnotation(HotReloadUnsupported.class) != null);
+ ConfigInfo configInfo = field.getAnnotation(ConfigInfo.class);
+
+ if (skipLoad || configInfo == null){
+ continue;
+ }
+
+ final String fullConfigKeyName = category.getBaseKeyName() + "." + singleConfigModule.getBaseName() + "." + configInfo.baseName();
+
+ field.setAccessible(true);
+ final Object currentValue = field.get(null);
+
+ if (!configFileInstance.contains(fullConfigKeyName)){
+ if (currentValue == null){
+ throw new UnsupportedOperationException("Config " + singleConfigModule.getBaseName() + "tried to add an null default value!");
+ }
+
+ final String comments = configInfo.comments();
+
+ if (!comments.isBlank()){
+ configFileInstance.setComment(fullConfigKeyName,comments);
+ }
+
+ configFileInstance.add(fullConfigKeyName,currentValue);
+ continue;
+ }
+
+ final Object actuallyValue = configFileInstance.get(fullConfigKeyName);
+ field.set(null,actuallyValue);
+ }
+ }
+
+ singleConfigModule.onLoaded(configFileInstance);
+ }
+
+ public static @NotNull Set<Class<?>> getClasses(String pack) {
+ Set<Class<?>> classes = new LinkedHashSet<>();
+ String packageDirName = pack.replace('.', '/');
+ Enumeration<URL> dirs;
+
+ try {
+ dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
+ while (dirs.hasMoreElements()) {
+ URL url = dirs.nextElement();
+ String protocol = url.getProtocol();
+ if ("file".equals(protocol)) {
+ String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8);
+ findClassesInPackageByFile(pack, filePath, classes);
+ } else if ("jar".equals(protocol)) {
+ JarFile jar;
+ try {
+ jar = ((JarURLConnection) url.openConnection()).getJarFile();
+ Enumeration<JarEntry> entries = jar.entries();
+ findClassesInPackageByJar(pack, entries, packageDirName, classes);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ return classes;
+ }
+
+ private static void findClassesInPackageByFile(String packageName, String packagePath, Set<Class<?>> classes) {
+ File dir = new File(packagePath);
+
+ if (!dir.exists() || !dir.isDirectory()) {
+ return;
+ }
+
+ File[] dirfiles = dir.listFiles((file) -> file.isDirectory() || file.getName().endsWith(".class"));
+ if (dirfiles != null) {
+ for (File file : dirfiles) {
+ if (file.isDirectory()) {
+ findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), classes);
+ } else {
+ String className = file.getName().substring(0, file.getName().length() - 6);
+ try {
+ classes.add(Class.forName(packageName + '.' + className));
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ }
+
+ private static void findClassesInPackageByJar(String packageName, Enumeration<JarEntry> entries, String packageDirName, Set<Class<?>> classes) {
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ String name = entry.getName();
+ if (name.charAt(0) == '/') {
+ name = name.substring(1);
+ }
+ if (name.startsWith(packageDirName)) {
+ int idx = name.lastIndexOf('/');
+ if (idx != -1) {
+ packageName = name.substring(0, idx).replace('/', '.');
+ }
+ if (name.endsWith(".class") && !entry.isDirectory()) {
+ String className = name.substring(packageName.length() + 1, name.length() - 6);
+ try {
+ classes.add(Class.forName(packageName + '.' + className));
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index cc40d3e69a3635ca7895876159f2821091c14a9a..e456435e2f0606e840c7f4c0ff522e49da6e40e1 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -222,6 +222,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
// Paper end - initialize global and world-defaults configuration
+ me.earthme.luminol.config.LuminolConfig.loadConfig(); //Luminol - load config file
+ me.earthme.luminol.config.LuminolConfig.setupLatch(); //Luminol - load config file
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
if (this.convertOldUsers()) {
this.getProfileCache().save(false); // Paper

View File

@@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 11:17:37 +0800
Subject: [PATCH] Add config for server brand name
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
index 5d7110a33957a597592cacb864c947eb053e8563..25cda48a6ab9a703d64c391007f5c32c368fdbe2 100644
--- a/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
+++ b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
@@ -1,6 +1,7 @@
package com.destroystokyo.paper.network;
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import org.bukkit.entity.Player;
@@ -14,7 +15,7 @@ class PaperServerListPingEventImpl extends PaperServerListPingEvent {
PaperServerListPingEventImpl(MinecraftServer server, StatusClient client, int protocolVersion, @Nullable CachedServerIcon icon) {
super(client, server.server.motd(), server.getPlayerCount(), server.getMaxPlayers(),
- server.getServerModName() + ' ' + server.getServerVersion(), protocolVersion, icon);
+ LuminolConfig.fakeVanillaModeEnabled ? server.getServerVersion() : server.getServerModName() + ' ' + server.getServerVersion(), protocolVersion, icon);//Luminol - Fake vanilla mode
this.server = server;
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 781612b6fc3d020e832164ebce231961dd68e24e..03165a7791aeac54e44391bbb0f432b613369bfa 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -53,6 +53,8 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.CrashReport;
import net.minecraft.ReportedException;
import net.minecraft.SharedConstants;
@@ -1833,7 +1835,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@DontObfuscate
public String getServerModName() {
- return "Luminol"; //Luminol - Luminol > // Folia - Folia > // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla!
+ return LuminolConfig.fakeVanillaModeEnabled ? "vanilla" : LuminolConfig.serverModName; //Luminol //Luminol - Luminol > // Folia - Folia > // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla!
}
public SystemReport fillSystemReport(SystemReport details) {

View File

@@ -0,0 +1,61 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 00:49:38 +0000
Subject: [PATCH] Add config for server mod name
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
index 6ed2114f577ce12d2d493985e798609c7d83f15e..7a5dcf3b7108794b9a224004730eb396a96cce8f 100644
--- a/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
+++ b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
@@ -14,7 +14,7 @@ class PaperServerListPingEventImpl extends PaperServerListPingEvent {
PaperServerListPingEventImpl(MinecraftServer server, StatusClient client, int protocolVersion, @Nullable CachedServerIcon icon) {
super(client, server.motd(), server.getPlayerCount(), server.getMaxPlayers(),
- server.getServerModName() + ' ' + server.getServerVersion(), protocolVersion, icon);
+ me.earthme.luminol.config.modules.misc.ServerModNameConfig.fakeVanilla ? server.getServerVersion() : server.getServerModName() + ' ' + server.getServerVersion(), protocolVersion, icon);//Luminol - Fake vanilla mode
this.server = server;
}
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..94e7c8910e3623163528a844fd7a08b3ffe5826b
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
@@ -0,0 +1,23 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class ServerModNameConfig implements IConfigModule {
+ @ConfigInfo(baseName = "name")
+ public static String serverModName = "Luminol";
+
+ @ConfigInfo(baseName = "vanilla_spoof")
+ public static boolean fakeVanilla = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "server_mod_name";
+ }
+}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 355c8408da189a4805e206db0932c41f940930f0..3a6d567ee9db93606aec30255400dff4f9f87b05 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -2016,7 +2016,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@DontObfuscate
public String getServerModName() {
- return io.papermc.paper.ServerBuildInfo.buildInfo().brandName(); // Paper
+ return me.earthme.luminol.config.modules.misc.ServerModNameConfig.fakeVanilla ? "vanilla" : me.earthme.luminol.config.modules.misc.ServerModNameConfig.serverModName; // Paper // Luminol - Add config for this
}
public SystemReport fillSystemReport(SystemReport details) {

View File

@@ -1,77 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 11:18:04 +0800
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 00:53:03 +0000
Subject: [PATCH] Add config for unsafe teleportation
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 1f9ff0fc33fa36c90fc4cbbd21b7b790de581632..36ca0b94d29d81e5f1f2aff4a38ead0b363dd1c7 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -14,6 +14,8 @@ public class LuminolConfig {
public static String serverModName = "Luminol";
public static boolean fakeVanillaModeEnabled = false;
+ public static boolean safeTeleportation = true;
diff --git a/src/main/java/me/earthme/luminol/config/modules/fixes/UnsafeTeleportationConfig.java b/src/main/java/me/earthme/luminol/config/modules/fixes/UnsafeTeleportationConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..ea374875f529b30db17e8b8cb07b99a600b722dc
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/fixes/UnsafeTeleportationConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.fixes;
+
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -31,6 +33,8 @@ public class LuminolConfig {
public static void initValues(){
serverModName = get("misc.server_mod_name",serverModName,"The servermod name will be sent to players,and you can see it in F3 or motd responses");
fakeVanillaModeEnabled = get("misc.enable_fake_vanilla_mode",fakeVanillaModeEnabled,"Enable this to make the ping response of your server like a vanilla server");
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+ safeTeleportation = get("fixes.enable_safe_teleportation",safeTeleportation,"If this enabled,the end portals will not teleport removed entities.");
}
public static <T> T get(String key,T def){
+public class UnsafeTeleportationConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments = "Allow non player entities enter end portals if enabled.If you want to use sand duping,please turn on this")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.FIXES;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "allow_unsafe_teleportation";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 385d5bc08928dd990b690b926e174af86f178c64..e357ed9607889536ecd0e6ea8b59c97d3dab631f 100644
index fad6a7185e8e9ea160b47ec9da56d08af9df8396..bda387d022a0725074a2871424cfec97508c420b 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -24,6 +24,8 @@ import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.BlockUtil;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
@@ -4001,6 +4003,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -4117,6 +4117,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
protected boolean tryEndPortal() {
io.papermc.paper.util.TickThread.ensureTickThread(this, "Cannot portal entity async");
+ if (!LuminolConfig.safeTeleportation && !(this instanceof Player)) return false; //Luminol - Unsafe teleportation
+ if (me.earthme.luminol.config.modules.fixes.UnsafeTeleportationConfig.enabled && !(this instanceof Player)) return false; //Luminol - Unsafe teleportation
BlockPos pos = this.portalBlock;
ServerLevel world = this.portalWorld;
this.portalBlock = null;
diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
index 41d7cff39fc37955877668337689b4b26cd8c7cf..ca5799c618bec3d0abc4566d82a29bcc767c6f1f 100644
index aeac09f628bd04070fd302842c304a7dfd39b229..dcdb7199ce731b2899ebd847f7c2d66dcd6d62bd 100644
--- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
@@ -1,5 +1,6 @@
package net.minecraft.world.level.block;
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceKey;
@@ -7,6 +8,7 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
@@ -53,6 +55,13 @@ public class EndPortalBlock extends BaseEntityBlock {
@@ -61,6 +61,13 @@ public class EndPortalBlock extends BaseEntityBlock {
// return; // CraftBukkit - always fire event in case plugins wish to change it
}
+ //Luminol start - Unsafe teleportation
+ if (!LuminolConfig.safeTeleportation && !(entity instanceof Player)){
+ if (me.earthme.luminol.config.modules.fixes.UnsafeTeleportationConfig.enabled && !(entity instanceof net.minecraft.world.entity.player.Player)){
+ entity.endPortalLogicAsync();
+ return;
+ }

View File

@@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sat, 25 Nov 2023 18:17:52 +0800
Subject: [PATCH] Add config for sand duping
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 36ca0b94d29d81e5f1f2aff4a38ead0b363dd1c7..9db3bdd7a7d0b2a110e927ee4781eee489d0da9b 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -15,6 +15,7 @@ public class LuminolConfig {
public static boolean fakeVanillaModeEnabled = false;
public static boolean safeTeleportation = true;
+ public static boolean enableSandDuping = false;
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -35,6 +36,7 @@ public class LuminolConfig {
fakeVanillaModeEnabled = get("misc.enable_fake_vanilla_mode",fakeVanillaModeEnabled,"Enable this to make the ping response of your server like a vanilla server");
safeTeleportation = get("fixes.enable_safe_teleportation",safeTeleportation,"If this enabled,the end portals will not teleport removed entities.");
+ enableSandDuping = get("fixes.enable_sand_duping",enableSandDuping,"If this enabled,The value of safe teleportation will always be false and sand duping will be enabled");
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
index 8e348099d6b3eb4510405d76453d70e7cadeebf6..cf72aa13fce00bf21c036c14a605ea7c6090d5f0 100644
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
@@ -4,6 +4,8 @@ import com.mojang.logging.LogUtils;
import java.util.Iterator;
import java.util.function.Predicate;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.CrashReportCategory;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -133,7 +135,7 @@ public class FallingBlockEntity extends Entity {
@Override
public void tick() {
// Paper start - fix sand duping
- if (this.isRemoved()) {
+ if (!LuminolConfig.enableSandDuping && this.isRemoved()) { //Luminol - Add config for sand duping
return;
}
// Paper end - fix sand duping
@@ -150,7 +152,7 @@ public class FallingBlockEntity extends Entity {
this.move(MoverType.SELF, this.getDeltaMovement());
// Paper start - fix sand duping
- if (this.isRemoved()) {
+ if (!LuminolConfig.enableSandDuping && this.isRemoved()) { //Luminol - Add config for sand duping
return;
}
// Paper end - fix sand duping

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 00:59:18 +0000
Subject: [PATCH] Add config for void trading
diff --git a/src/main/java/me/earthme/luminol/config/modules/fixes/VoidTradingFixConfig.java b/src/main/java/me/earthme/luminol/config/modules/fixes/VoidTradingFixConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..22f3c6c70e4287f1bdd0b18f87f57efeb20140a2
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/fixes/VoidTradingFixConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class VoidTradingFixConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.FIXES;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "allow_void_trading";
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index b194f3448b5199e1204da31e1408f2e80803a77d..6b8cbf681203c20eebb214c5c0b0fe0374aa30dc 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -3011,7 +3011,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Spigot Start
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
// Paper start - Fix merchant inventory not closing on entity removal
- if (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) {
+ if (!me.earthme.luminol.config.modules.fixes.VoidTradingFixConfig.enabled && (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null)) { //Luminol - Add config for void trading
merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED);
}
// Paper end - Fix merchant inventory not closing on entity removal

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 02:33:00 +0000
Subject: [PATCH] Add config for vanilla random
diff --git a/src/main/java/me/earthme/luminol/config/modules/fixes/VanillaRandomSourceConfig.java b/src/main/java/me/earthme/luminol/config/modules/fixes/VanillaRandomSourceConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..0e6bfc03be660415c333024b56ac6565e3b61ab1
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/fixes/VanillaRandomSourceConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class VanillaRandomSourceConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enable_for_player_entity",comments = "Related with RNG cracks")
+ public static boolean useLegacyRandomSourceForPlayers = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.FIXES;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "use_vanilla_random_source";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index bda387d022a0725074a2871424cfec97508c420b..681f1476754f49d01b99a892ef2618cac341cd25 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -568,7 +568,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.bb = Entity.INITIAL_AABB;
this.stuckSpeedMultiplier = Vec3.ZERO;
this.nextStep = 1.0F;
- this.random = SHARED_RANDOM; // Paper - Share random for entities to make them more random
+ this.random = me.earthme.luminol.config.modules.fixes.VanillaRandomSourceConfig.useLegacyRandomSourceForPlayers ? RandomSource.create() : SHARED_RANDOM;//Luminol - Add config for vanilla random SHARED_RANDOM // Paper - Share random for entities to make them more random
this.remainingFireTicks = -this.getFireImmuneTicks();
this.fluidHeight = new Object2DoubleArrayMap(2);
this.fluidOnEyes = new HashSet();

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sat, 25 Nov 2023 18:22:09 +0800
Subject: [PATCH] Add config for void trading
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 9db3bdd7a7d0b2a110e927ee4781eee489d0da9b..dffa9db569fcef2feec75072fe86c9a6ded80aa4 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -16,6 +16,7 @@ public class LuminolConfig {
public static boolean safeTeleportation = true;
public static boolean enableSandDuping = false;
+ public static boolean enableVoidTrading = false;
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -37,6 +38,7 @@ public class LuminolConfig {
safeTeleportation = get("fixes.enable_safe_teleportation",safeTeleportation,"If this enabled,the end portals will not teleport removed entities.");
enableSandDuping = get("fixes.enable_sand_duping",enableSandDuping,"If this enabled,The value of safe teleportation will always be false and sand duping will be enabled");
+ enableVoidTrading = get("fixes.enable_void_trading",enableVoidTrading);
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index e274c501e2455845f6f9a4614802336205362b69..722a5ec7f8e4995ac7025ca0785145d46bd66fcd 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -3026,7 +3026,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Spigot Start
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
// Paper start
- if (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) {
+ if (!LuminolConfig.enableVoidTrading && (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null)) { //Luminol - Add config for void trading
merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED);
}
// Paper end

View File

@@ -0,0 +1,75 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 02:00:50 +0000
Subject: [PATCH] Add config for chat sign
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/ChatSignConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/ChatSignConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e03e51e51f56c38abaad100274e25c9f854f727
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/ChatSignConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class ChatSignConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = true;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "mojang_chat_sign";
+ }
+}
diff --git a/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java b/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java
index 479e6e2aa88a22ef7f8fccb06add6806f5b71d9d..22dae23a0c2fa4c85befd670637b1e592d889b58 100644
--- a/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java
+++ b/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java
@@ -14,9 +14,16 @@ public record ArgumentSignatures(List<ArgumentSignatures.Entry> entries) {
private static final int MAX_ARGUMENT_NAME_LENGTH = 16;
public ArgumentSignatures(FriendlyByteBuf buf) {
- this(buf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 8), ArgumentSignatures.Entry::new));
+ this(readSign(buf)); //Luminol - Fix java compile
}
+ //Luminol start - Add config for chat sign
+ private static List<ArgumentSignatures.Entry> readSign(FriendlyByteBuf buf) {
+ var entries = buf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 8), Entry::new);
+ return me.earthme.luminol.config.modules.misc.ChatSignConfig.enabled ? List.of() : entries;
+ }
+ //Luminol end
+
public void write(FriendlyByteBuf buf) {
buf.writeCollection(this.entries, (buf2, entry) -> entry.write(buf2));
}
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
index aafeb9c61ddba6a8671f0238eda47b227619f1af..dc00ad0cc7f0c5c069a8d15dfdc926f2a1487319 100644
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
@@ -129,6 +129,16 @@ public class FriendlyByteBuf extends ByteBuf {
// Paper end - Adventure; add max length parameter
DataResult<JsonElement> dataresult = codec.encodeStart(JsonOps.INSTANCE, value);
+ //Luminol start - Add config for chat sign
+ if (codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) {
+ JsonElement element = dataresult.getOrThrow(string -> new EncoderException("Failed to encode: " + string + " " + value));
+ element.getAsJsonObject().addProperty("preventsChatReports", !me.earthme.luminol.config.modules.misc.ChatSignConfig.enabled);
+
+ this.writeUtf(GSON.toJson(element));
+ return;
+ }
+ //Luminol end
+
this.writeUtf(FriendlyByteBuf.GSON.toJson((JsonElement) dataresult.getOrThrow((s) -> {
return new EncoderException("Failed to encode: " + s + " " + String.valueOf(value));
})), maxLength); // Paper - Adventure; add max length parameter

View File

@@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sat, 25 Nov 2023 18:25:37 +0800
Subject: [PATCH] Add config for incorrect tripwire updating fixing
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index dffa9db569fcef2feec75072fe86c9a6ded80aa4..a49da370c91211d4e2274f72d62c911a1912296a 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -17,6 +17,7 @@ public class LuminolConfig {
public static boolean safeTeleportation = true;
public static boolean enableSandDuping = false;
public static boolean enableVoidTrading = false;
+ public static boolean allowIncorrectTripwireUpdating = false;
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -39,6 +40,7 @@ public class LuminolConfig {
safeTeleportation = get("fixes.enable_safe_teleportation",safeTeleportation,"If this enabled,the end portals will not teleport removed entities.");
enableSandDuping = get("fixes.enable_sand_duping",enableSandDuping,"If this enabled,The value of safe teleportation will always be false and sand duping will be enabled");
enableVoidTrading = get("fixes.enable_void_trading",enableVoidTrading);
+ allowIncorrectTripwireUpdating = get("fixes.allow_incorrect_trip_wire_updaing",allowIncorrectTripwireUpdating);
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
index 004dce26ff073f1de52a84cd425c4f60fdab5e50..ef150d50ff076c80ee62c3c413745fa312c9d289 100644
--- a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
@@ -2,6 +2,8 @@ package net.minecraft.world.level.block;
import com.google.common.base.MoreObjects;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
@@ -147,7 +149,7 @@ public class TripWireHookBlock extends Block {
boolean flag7 = (Boolean) iblockdata2.getValue(TripWireBlock.POWERED);
flag5 |= flag6 && flag7;
- if (k != i || !tripWireBeingRemoved || !flag6) // Paper - don't update the tripwire again if being removed and not disarmed
+ if (k != i || !tripWireBeingRemoved || !flag6 || LuminolConfig.allowIncorrectTripwireUpdating) // Paper - don't update the tripwire again if being removed and not disarmed //Luminol - Add config for incorrect tripwire updating fixing
aiblockdata[k] = iblockdata2;
if (k == i) {
world.scheduleTick(pos, (Block) this, 10);

View File

@@ -1,76 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 15:19:16 +0800
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 04:39:56 +0000
Subject: [PATCH] Add a simple tpsbar
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 90a6cfd011aaefe66fda79f887380ab2d62a07b1..0657fce8aabb956a400b3cead53c28ef52e67fe9 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -2,11 +2,15 @@ package me.earthme.luminol;
import dev.kaiijumc.kaiiju.region.RegionFileFormat;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.commands.TpsBarCommand;
+import me.earthme.luminol.functions.GlobalServerTpsBar;
import net.minecraft.server.level.ServerLevel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.bukkit.Bukkit;
import java.util.Arrays;
+import java.util.List;
import java.util.logging.Level;
import java.io.File;
import java.io.IOException;
@@ -20,6 +24,10 @@ public class LuminolConfig {
public static String serverModName = "Luminol";
public static boolean fakeVanillaModeEnabled = false;
public static boolean disableChatSign = false;
+ public static boolean tpsbarEnabled = false;
+ public static String tpsBarFormat = "<gray>TPS<yellow>:</yellow> <tps> MSPT<yellow>:</yellow> <mspt> Ping<yellow>:</yellow> <ping>ms";
+ public static String[] tpsColors = new String[]{"GREEN","YELLOW","RED","PURPLE"};
+ public static String[] pingColors = new String[]{"GREEN","YELLOW","RED","PURPLE"};
public static boolean safeTeleportation = true;
public static boolean enableSandDuping = false;
@@ -46,10 +54,25 @@ public class LuminolConfig {
MAIN_CONFIG.save();
}
+ public static void initTpsbar(){
+ if (tpsbarEnabled){
+ GlobalServerTpsBar.init();
+ Bukkit.getCommandMap().register("tpsbar","luminol",new TpsBarCommand("tpsbar"));
+ }
+ }
+
public static void initValues(){
serverModName = get("misc.server_mod_name",serverModName,"The servermod name will be sent to players,and you can see it in F3 or motd responses");
fakeVanillaModeEnabled = get("misc.enable_fake_vanilla_mode",fakeVanillaModeEnabled,"Enable this to make the ping response of your server like a vanilla server");
disableChatSign = get("misc.disable_chat_sign",disableChatSign,"Set this to true to disable mojang's chat sign");
+ tpsbarEnabled = get("misc.enable_tpsbar",tpsbarEnabled,"When this enabled,You or your players can see the tps,mspt and ping through a simple bossbar");
+ tpsBarFormat = get("misc.tpsbar_title_format",tpsBarFormat,"The format of tpsbar.");
+ tpsColors = get("misc.tpsbar_range_colors", List.of(tpsColors),"The bar and text color of each tps ranges.The last is the color of initial bar's color").toArray(String[]::new);
+ pingColors = get("misc.tpsbar_ping_range_colors",List.of(pingColors),"As same as the tpsColors").toArray(String[]::new);
+
+ if (tpsbarEnabled){
+ initTpsbar();
+ }
safeTeleportation = get("fixes.enable_safe_teleportation",safeTeleportation,"If this enabled,the end portals will not teleport removed entities.");
enableSandDuping = get("fixes.enable_sand_duping",enableSandDuping,"If this enabled,The value of safe teleportation will always be false and sand duping will be enabled");
diff --git a/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java b/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac8f0e3bf130ba6dfd7202e2f480352218154cdc
index 0000000000000000000000000000000000000000..01677f210fae53a108bfe194189cb4c233e9fa47
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java
@@ -0,0 +1,40 @@
@@ -0,0 +1,50 @@
+package me.earthme.luminol.commands;
+
+import me.earthme.luminol.config.modules.misc.TpsBarConfig;
+import me.earthme.luminol.functions.GlobalServerTpsBar;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import net.kyori.adventure.util.RGBLike;
+import org.bukkit.ChatColor;
+import org.bukkit.Color;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
@@ -90,43 +38,104 @@ index 0000000000000000000000000000000000000000..ac8f0e3bf130ba6dfd7202e2f4803522
+ return true;
+ }
+
+ if (!TpsBarConfig.tpsbarEnabled){
+ sender.sendMessage(Component.text("Tpsbar was already disabled!").color(TextColor.color(255,0,0)));
+ return true;
+ }
+
+ if (!(sender instanceof Player player)){
+ sender.sendMessage(ChatColor.RED+"Only player can use this command!");
+ sender.sendMessage(Component.text("Only player can use this command!").color(TextColor.color(255,0,0)));
+ return true;
+ }
+
+ if (GlobalServerTpsBar.isPlayerVisible(player)) {
+ player.sendMessage(ChatColor.BLUE + "Disabled tps bar");
+ player.sendMessage(Component.text("Disabled tps bar").color(TextColor.color(0,255,0)));
+ GlobalServerTpsBar.setVisibilityForPlayer(player,false);
+ return true;
+ }
+
+ player.sendMessage(ChatColor.GREEN + "Enabled tps bar");
+ player.sendMessage(Component.text("Enabled tps bar").color(TextColor.color(0,255,0)));
+ GlobalServerTpsBar.setVisibilityForPlayer(player,true);
+
+ return true;
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..aafb2f5052c7c8e5971a47308253badb3027093c
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
@@ -0,0 +1,49 @@
+package me.earthme.luminol.config.modules.misc;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.commands.TpsBarCommand;
+import me.earthme.luminol.config.*;
+import me.earthme.luminol.functions.GlobalServerTpsBar;
+import org.bukkit.Bukkit;
+
+import java.util.List;
+
+public class TpsBarConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean tpsbarEnabled = false;
+ @ConfigInfo(baseName = "format")
+ public static String tpsBarFormat = "<gray>TPS<yellow>:</yellow> <tps> MSPT<yellow>:</yellow> <mspt> Ping<yellow>:</yellow> <ping>ms";
+ @ConfigInfo(baseName = "tps_color_list")
+ public static List<String> tpsColors = List.of("GREEN","YELLOW","RED","PURPLE");
+ @ConfigInfo(baseName = "ping_color_list")
+ public static List<String> pingColors = List.of("GREEN","YELLOW","RED","PURPLE");
+ @ConfigInfo(baseName = "update_interval_ticks")
+ public static int updateInterval = 15;
+
+ @DoNotLoad
+ private static boolean inited = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "tpsbar";
+ }
+
+ @Override
+ public void onLoaded(CommentedFileConfig configInstance){
+ if (tpsbarEnabled){
+ GlobalServerTpsBar.init();
+ }else{
+ GlobalServerTpsBar.cancelBarUpdateTask();
+ }
+
+ if (!inited){
+ Bukkit.getCommandMap().register("tpsbar","luminol",new TpsBarCommand("tpsbar"));
+ inited = true;
+ }
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..baec715e0c20e920ccb99f2f07d84fcb6f2b434e
index 0000000000000000000000000000000000000000..3f1478dde900d671c4bfa43df80f629519cd602e
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
@@ -0,0 +1,204 @@
@@ -0,0 +1,225 @@
+package me.earthme.luminol.functions;
+
+import com.google.common.collect.Lists;
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
+import io.papermc.paper.threadedregions.TickData;
+import io.papermc.paper.threadedregions.TickRegions;
+import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
+import me.earthme.luminol.LuminolConfig;
+import me.earthme.luminol.config.modules.misc.TpsBarConfig;
+import net.kyori.adventure.bossbar.BossBar;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin;
@@ -140,20 +149,40 @@ index 0000000000000000000000000000000000000000..baec715e0c20e920ccb99f2f07d84fcb
+ protected static final MinecraftInternalPlugin NULL_PLUGIN = new MinecraftInternalPlugin();
+ protected static final Map<UUID,BossBar> uuid2Bossbars = new HashMap<>();
+ protected static volatile ScheduledTask tpsbarTask = null;
+ private static final Logger logger = LogManager.getLogger();
+
+ public static void init(){
+ Bukkit.getAsyncScheduler().runAtFixedRate(NULL_PLUGIN,c -> {
+ cancelBarUpdateTask();
+
+ Bukkit.getGlobalRegionScheduler().runAtFixedRate(NULL_PLUGIN,c -> {
+ tpsbarTask = c;
+ try {
+ update();
+ }catch (Exception e){
+ e.printStackTrace();
+ logger.error(e);
+ }
+ },1,1, TimeUnit.SECONDS);
+ },1,TpsBarConfig.updateInterval);
+ }
+
+ public static void removeAllBars(){
+ for (Map.Entry<UUID,BossBar> barEntry : uuid2Bossbars.entrySet()){
+ final UUID playerUUID = barEntry.getKey();
+ final BossBar tpsBar = barEntry.getValue();
+
+ final Player targetPlayer = Bukkit.getPlayer(playerUUID);{
+ if (targetPlayer != null){
+ targetPlayer.hideBossBar(tpsBar);
+ }
+ }
+ }
+
+ uuid2Bossbars.clear();
+ }
+
+ public static void cancelBarUpdateTask(){
+ if (tpsbarTask == null){
+ removeAllBars();
+
+ if (tpsbarTask == null || tpsbarTask.isCancelled()){
+ return;
+ }
+
@@ -215,7 +244,7 @@ index 0000000000000000000000000000000000000000..baec715e0c20e920ccb99f2f07d84fcb
+ BossBar targetBossbar = uuid2Bossbars.get(nmsPlayer.getUUID());
+
+ if (targetBossbar == null && isPlayerVisible(apiPlayer)){
+ targetBossbar = BossBar.bossBar(Component.text(""),0.0F, BossBar.Color.valueOf(LuminolConfig.tpsColors[3]), BossBar.Overlay.NOTCHED_20);
+ targetBossbar = BossBar.bossBar(Component.text(""),0.0F, BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3)), BossBar.Overlay.NOTCHED_20);
+ uuid2Bossbars.put(nmsPlayer.getUUID(),targetBossbar);
+ apiPlayer.showBossBar(targetBossbar);
+ }
@@ -230,7 +259,7 @@ index 0000000000000000000000000000000000000000..baec715e0c20e920ccb99f2f07d84fcb
+
+ private static void updateTpsBar(double tps, double mspt, @NotNull BossBar bar, @NotNull Player player){
+ bar.name(MiniMessage.miniMessage().deserialize(
+ LuminolConfig.tpsBarFormat,
+ TpsBarConfig.tpsBarFormat,
+ Placeholder.component("tps",getTpsComponent(tps)),
+ Placeholder.component("mspt",getMsptComponent(mspt)),
+ Placeholder.component("ping",getPingComponent(player.getPing()))
@@ -251,18 +280,18 @@ index 0000000000000000000000000000000000000000..baec715e0c20e920ccb99f2f07d84fcb
+
+ private static BossBar.Color barColorFromPing(int ping){
+ if (ping == -1){
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[3]);
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(3));
+ }
+
+ if (ping <= 80){
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[0]);
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(0));
+ }
+
+ if (ping <= 160){
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[1]);
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(1));
+ }
+
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[2]);
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(2));
+ }
+
+ private static @NotNull Component getMsptComponent(double mspt){
@@ -277,18 +306,18 @@ index 0000000000000000000000000000000000000000..baec715e0c20e920ccb99f2f07d84fcb
+
+ private static BossBar.Color barColorFromMspt(double mspt){
+ if (mspt == -1){
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[3]);
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3));
+ }
+
+ if (mspt <= 25){
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[0]);
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(0));
+ }
+
+ if (mspt <= 50){
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[1]);
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(1));
+ }
+
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[2]);
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(2));
+ }
+
+ private static @NotNull Component getTpsComponent(double tps){
@@ -303,90 +332,65 @@ index 0000000000000000000000000000000000000000..baec715e0c20e920ccb99f2f07d84fcb
+
+ private static BossBar.Color barColorFromTps(double tps){
+ if (tps == -1){
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[3]);
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3));
+ }
+
+ if (tps >= 18){
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[0]);
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(0));
+ }
+
+ if (tps >= 15){
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[1]);
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(1));
+ }
+
+ return BossBar.Color.valueOf(LuminolConfig.tpsColors[2]);
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(2));
+ }
+}
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index f0bf57a7acd77eeffbeeb6743ba58166823022fd..4a1e068c27853a38db0641806626e7ac740bd8de 100644
index e456435e2f0606e840c7f4c0ff522e49da6e40e1..0c9b1289f445b7951a8c92c6d9effb0a7fb8ba01 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -1,20 +1,16 @@
package net.minecraft.server.dedicated;
-import com.google.common.collect.Lists;
+import me.earthme.luminol.functions.GlobalServerTpsBar;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.DataFixer;
import com.mojang.logging.LogUtils;
-import java.io.BufferedReader;
+
import java.io.BufferedWriter;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Proxy;
-import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.Collections;
-import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.function.BooleanSupplier;
@@ -829,6 +825,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -850,6 +850,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override
public void stopServer() {
+ GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
+ me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
super.stopServer();
//Util.shutdownExecutors(); // Paper - moved into super
SkullBlockEntity.clear();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 97bfb92e52c3c5ef1cd22afe2b97c204eb45025a..d7a280427442bac8cc8ccb542d24d4e0901df70a 100644
index 8ee61c2415455f8d4ff1ae687753117a40eb687b..a8f2eddba3ac3b7c551d39e260e096067e8bdc0f 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -278,6 +278,7 @@ public class ServerPlayer extends Player {
@@ -302,6 +302,7 @@ public class ServerPlayer extends Player {
// Paper start - replace player chunk loader
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
+ public volatile boolean isTpsBarVisible = false;
+ public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances getViewDistances() {
return this.viewDistances.get();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 6c8f6e26687b557fcdcd65c657d8b35d3fde805e..06c92a2d3ecb3b747c2303819f72c1c41967af8c 100644
index 639b8678ad7711582f2e912772a98233c5313f63..28583ad8117167400faf3ca0dc4bc9f3f44dbedb 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2216,6 +2216,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -2370,6 +2370,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
handle.expToDrop = data.getInt("expToDrop");
handle.keepLevel = data.getBoolean("keepLevel");
}
+
+ //Luminol start - Tpsbar
+ getHandle().isTpsBarVisible = data.getBoolean("tpsbarVisible");
+ //Luminol end
}
}
@@ -2237,6 +2241,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -2391,6 +2394,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
data.putLong("lastPlayed", System.currentTimeMillis());
data.putString("lastKnownName", handle.getScoreboardName());
+ //Luminol start - Tpsbar
+ data.putBoolean("tpsbarVisible",handle.isTpsBarVisible);
+ //Luminol end
+
// Paper start - persist for use in offline save data
if (!nbttagcompound.contains("Paper")) {
nbttagcompound.put("Paper", new CompoundTag());

View File

@@ -1,118 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sat, 25 Nov 2023 18:31:24 +0800
Subject: [PATCH] Add config for chat sign
diff --git a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
index 772e3a864e0e70288a1c010d8bbb809d34d16a41..68bd66aad880c81d1f8eaf88525597c878350961 100644
--- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
+++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
@@ -15,6 +15,8 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
+
+import me.earthme.luminol.LuminolConfig;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.audience.ForwardingAudience;
import net.kyori.adventure.key.Key;
@@ -355,7 +357,7 @@ public final class ChatProcessor {
private void sendToServer(final ChatType.Bound chatType, final @Nullable Function<Audience, net.minecraft.network.chat.Component> msgFunction) {
final PlayerChatMessage toConsoleMessage = msgFunction == null ? ChatProcessor.this.message : ChatProcessor.this.message.withUnsignedContent(msgFunction.apply(ChatProcessor.this.server.console));
- ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) ? null : "Not Secure");
+ ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) || LuminolConfig.disableChatSign ? null : "Not Secure"); //Luminol - Add config for chat sign
}
}
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index a49da370c91211d4e2274f72d62c911a1912296a..8d1ce8eae252fcf05b6a62d2dc467d6d503d3df4 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -13,6 +13,7 @@ public class LuminolConfig {
public static String serverModName = "Luminol";
public static boolean fakeVanillaModeEnabled = false;
+ public static boolean disableChatSign = false;
public static boolean safeTeleportation = true;
public static boolean enableSandDuping = false;
@@ -36,6 +37,7 @@ public class LuminolConfig {
public static void initValues(){
serverModName = get("misc.server_mod_name",serverModName,"The servermod name will be sent to players,and you can see it in F3 or motd responses");
fakeVanillaModeEnabled = get("misc.enable_fake_vanilla_mode",fakeVanillaModeEnabled,"Enable this to make the ping response of your server like a vanilla server");
+ disableChatSign = get("misc.disable_chat_sign",disableChatSign,"Set this to true to disable mojang's chat sign");
safeTeleportation = get("fixes.enable_safe_teleportation",safeTeleportation,"If this enabled,the end portals will not teleport removed entities.");
enableSandDuping = get("fixes.enable_sand_duping",enableSandDuping,"If this enabled,The value of safe teleportation will always be false and sand duping will be enabled");
diff --git a/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java b/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java
index 72a8aa676836fcb3b4578689d16af65e18f55bbe..04653d58f2493d796e61bc97f0481cb628539c37 100644
--- a/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java
+++ b/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java
@@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.MessageSignature;
import net.minecraft.network.chat.SignableCommand;
@@ -14,8 +16,16 @@ public record ArgumentSignatures(List<ArgumentSignatures.Entry> entries) {
private static final int MAX_ARGUMENT_NAME_LENGTH = 16;
public ArgumentSignatures(FriendlyByteBuf buf) {
- this(buf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 8), ArgumentSignatures.Entry::new));
+ this(readSign(buf));
+ }
+
+ //Luminol start - Add config for chat sign
+ private static List<ArgumentSignatures.Entry> readSign(FriendlyByteBuf buf) {
+ var entries = buf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 8), Entry::new);
+ return LuminolConfig.disableChatSign ? List.of() : entries;
}
+ //Luminol end
+
@Nullable
public MessageSignature get(String argumentName) {
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
index 2e395962b555bef0ce1a98e1d768e7738f011535..11a9bc78c34b9f6bfff1ebf979be55b9bbbbed55 100644
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
@@ -48,6 +48,8 @@ import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.ToIntFunction;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -65,6 +67,7 @@ import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
+import net.minecraft.network.protocol.status.ServerStatus;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Crypt;
@@ -137,6 +140,17 @@ public class FriendlyByteBuf extends ByteBuf {
public <T> void writeJsonWithCodec(Codec<T> codec, T value) {
DataResult<JsonElement> dataresult = codec.encodeStart(JsonOps.INSTANCE, value);
+
+ //Luminol start - Add config for chat sign
+ if (codec == ServerStatus.CODEC) {
+ JsonElement element = Util.getOrThrow(dataresult, string -> new EncoderException("Failed to encode: " + string + " " + value));
+ element.getAsJsonObject().addProperty("preventsChatReports", LuminolConfig.disableChatSign);
+
+ this.writeUtf(GSON.toJson(element));
+ return;
+ }
+ //Luminol end
+
this.writeUtf(FriendlyByteBuf.GSON.toJson((JsonElement) Util.getOrThrow(dataresult, (s) -> {
return new EncoderException("Failed to encode: " + s + " " + value);
})));

View File

@@ -0,0 +1,355 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Sun, 2 Jun 2024 12:18:05 +0000
Subject: [PATCH] Add a simple membar
diff --git a/src/main/java/me/earthme/luminol/commands/MembarCommand.java b/src/main/java/me/earthme/luminol/commands/MembarCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5cbad6b947b1c3e1499bc6d311e17a5eb570c2f
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/MembarCommand.java
@@ -0,0 +1,47 @@
+package me.earthme.luminol.commands;
+
+import me.earthme.luminol.config.modules.misc.MembarConfig;
+import me.earthme.luminol.functions.GlobalServerMemoryBar;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+public class MembarCommand extends Command {
+ public MembarCommand(@NotNull String name) {
+ super(name);
+ this.setPermission("luminol.commands.membar");
+ this.setDescription("Show the memory usage through a bossbar");
+ this.setUsage("/membar");
+ }
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
+ if (!testPermission(sender)){
+ return true;
+ }
+
+ if (!MembarConfig.memoryBarEnabled){
+ sender.sendMessage(Component.text("Membar was already disabled!").color(TextColor.color(255,0,0)));
+ return true;
+ }
+
+ if (!(sender instanceof Player player)){
+ sender.sendMessage(Component.text("Only player can use this command!").color(TextColor.color(255,0,0)));
+ return true;
+ }
+
+ if (GlobalServerMemoryBar.isPlayerVisible(player)) {
+ player.sendMessage(Component.text("Disabled mem bar").color(TextColor.color(0,255,0)));
+ GlobalServerMemoryBar.setVisibilityForPlayer(player,false);
+ return true;
+ }
+
+ player.sendMessage(Component.text("Enabled mem bar").color(TextColor.color(0,255,0)));
+ GlobalServerMemoryBar.setVisibilityForPlayer(player,true);
+
+ return true;
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/MembarConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/MembarConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..b632c4a636974535bf001f010de1dcb6b25868c0
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/MembarConfig.java
@@ -0,0 +1,50 @@
+package me.earthme.luminol.config.modules.misc;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.commands.MembarCommand;
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.DoNotLoad;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.functions.GlobalServerMemoryBar;
+import org.bukkit.Bukkit;
+
+import java.util.List;
+
+public class MembarConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean memoryBarEnabled = false;
+ @ConfigInfo(baseName = "format")
+ public static String memBarFormat = "<gray>Memory usage <yellow>:</yellow> <used>MB<yellow>/</yellow><available>MB";
+ @ConfigInfo(baseName = "memory_color_list")
+ public static List<String> memColors = List.of("GREEN","YELLOW","RED","PURPLE");
+ @ConfigInfo(baseName = "update_interval_ticks")
+ public static int updateInterval = 15;
+
+ @DoNotLoad
+ private static boolean inited = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "membar";
+ }
+
+ @Override
+ public void onLoaded(CommentedFileConfig configInstance){
+ if (memoryBarEnabled){
+ GlobalServerMemoryBar.init();
+ }else{
+ GlobalServerMemoryBar.cancelBarUpdateTask();
+ }
+
+ if (!inited){
+ Bukkit.getCommandMap().register("membar","luminol",new MembarCommand("membar"));
+ inited = true;
+ }
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/functions/GlobalServerMemoryBar.java b/src/main/java/me/earthme/luminol/functions/GlobalServerMemoryBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..a33a45194273cc1b4e4157a5449c7994968a3480
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/functions/GlobalServerMemoryBar.java
@@ -0,0 +1,186 @@
+package me.earthme.luminol.functions;
+
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
+import io.papermc.paper.threadedregions.TickRegions;
+import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
+import me.earthme.luminol.config.modules.misc.MembarConfig;
+import net.kyori.adventure.bossbar.BossBar;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryUsage;
+import java.util.*;
+
+public class GlobalServerMemoryBar {
+ protected static final MinecraftInternalPlugin NULL_PLUGIN = new MinecraftInternalPlugin();
+ protected static final Map<UUID, BossBar> uuid2Bossbars = new HashMap<>();
+ protected static volatile ScheduledTask membarTask = null;
+ private static final Logger logger = LogManager.getLogger();
+
+ public static void init(){
+ cancelBarUpdateTask();
+
+ Bukkit.getGlobalRegionScheduler().runAtFixedRate(NULL_PLUGIN, c -> {
+ membarTask = c;
+ try {
+ update();
+ }catch (Exception e){
+ logger.error(e);
+ }
+ },1, MembarConfig.updateInterval);
+ }
+
+ public static void removeAllBars(){
+ for (Map.Entry<UUID,BossBar> barEntry : uuid2Bossbars.entrySet()){
+ final UUID playerUUID = barEntry.getKey();
+ final BossBar memBar = barEntry.getValue();
+
+ final Player targetPlayer = Bukkit.getPlayer(playerUUID);{
+ if (targetPlayer != null){
+ targetPlayer.hideBossBar(memBar);
+ }
+ }
+ }
+
+ uuid2Bossbars.clear();
+ }
+
+ public static void cancelBarUpdateTask(){
+ removeAllBars();
+
+ if (membarTask == null || membarTask.isCancelled()){
+ return;
+ }
+
+ membarTask.cancel();
+ }
+
+ public static boolean isPlayerVisible(Player player){
+ return ((CraftPlayer) player).getHandle().isMemBarVisible;
+ }
+
+ public static void setVisibilityForPlayer(Player target,boolean canSee){
+ ((CraftPlayer) target).getHandle().isMemBarVisible = canSee;
+ }
+
+ private static void update(){
+ updateBarValues();
+ cleanUpPlayers();
+ }
+
+ private static void cleanUpPlayers(){
+ final List<UUID> toRemove = new ArrayList<>();
+
+ for (Map.Entry<UUID,BossBar> bossBarEntry : uuid2Bossbars.entrySet()){
+ final UUID uuid = bossBarEntry.getKey();
+ boolean shouldRemove = true;
+
+ final Player target = Bukkit.getPlayer(uuid);
+ if (target != null){
+ shouldRemove = !isPlayerVisible(target);
+ }
+
+ if (shouldRemove){
+ toRemove.add(uuid);
+ }
+ }
+
+ for (UUID uuid : toRemove){
+ final BossBar removed = uuid2Bossbars.remove(uuid);
+ if (removed != null){
+ final Player targetPlayer = Bukkit.getPlayer(uuid);
+ if (targetPlayer != null){
+ targetPlayer.hideBossBar(removed);
+ }
+ }
+ }
+ }
+
+ private static void updateBarValues(){
+ MemoryUsage heap = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
+
+ long used = heap.getUsed();
+ long xmx = heap.getMax();
+
+
+
+ for (Player apiPlayer : Bukkit.getOnlinePlayers()){
+ final ServerPlayer nmsPlayer = ((CraftPlayer) apiPlayer).getHandle();
+ final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> region = ((ServerLevel) nmsPlayer.level()).regioniser.getRegionAtUnsynchronised(nmsPlayer.sectionX,nmsPlayer.sectionZ);
+
+ if (region == null){
+ continue;
+ }
+
+ BossBar targetBossbar = uuid2Bossbars.get(nmsPlayer.getUUID());
+
+ if (targetBossbar == null && isPlayerVisible(apiPlayer)){
+ targetBossbar = BossBar.bossBar(Component.text(""),0.0F, BossBar.Color.valueOf(MembarConfig.memColors.get(3)), BossBar.Overlay.NOTCHED_20);
+ uuid2Bossbars.put(nmsPlayer.getUUID(),targetBossbar);
+ apiPlayer.showBossBar(targetBossbar);
+ }
+
+ if (targetBossbar != null){
+ updateMembar(targetBossbar,used,xmx);
+ }
+ }
+ }
+
+ private static void updateMembar(@NotNull BossBar bar, long used, long xmx){
+ double percent = Math.max(Math.min((float) used / xmx, 1.0F), 0.0F);
+ bar.name(MiniMessage.miniMessage().deserialize(
+ MembarConfig.memBarFormat,
+ Placeholder.component("used", getMemoryComponent(used,xmx)),
+ Placeholder.component("available",getMaxMemComponent(xmx))
+ ));
+ bar.color(barColorFromMemory(percent));
+ bar.progress((float) percent);
+ }
+
+ private static @NotNull Component getMaxMemComponent(double max){
+ final BossBar.Color colorBukkit = BossBar.Color.GREEN;
+ final String colorString = colorBukkit.name();
+
+ final String content = "<%s><text></%s>";
+ final String replaced = String.format(content,colorString,colorString);
+
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.format("%.2f", (double)max / (1024 * 1024))));
+ }
+
+ private static @NotNull Component getMemoryComponent(long used,long max){
+ final BossBar.Color colorBukkit = barColorFromMemory(Math.max(Math.min((float) used / max, 1.0F), 0.0F));
+ final String colorString = colorBukkit.name();
+
+ final String content = "<%s><text></%s>";
+ final String replaced = String.format(content,colorString,colorString);
+
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.format("%.2f", (double)used / (1024 * 1024))));
+ }
+
+ private static BossBar.Color barColorFromMemory(double memPercent){
+ if (memPercent == -1){
+ return BossBar.Color.valueOf(MembarConfig.memColors.get(3));
+ }
+
+ if (memPercent <= 50){
+ return BossBar.Color.valueOf(MembarConfig.memColors.getFirst());
+ }
+
+ if (memPercent <= 70){
+ return BossBar.Color.valueOf(MembarConfig.memColors.get(1));
+ }
+
+ return BossBar.Color.valueOf(MembarConfig.memColors.get(2));
+ }
+}
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 0c9b1289f445b7951a8c92c6d9effb0a7fb8ba01..b82ed9280f96bacbb87ae77a6afd5d82d8863b58 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -851,6 +851,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override
public void stopServer() {
me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
+ me.earthme.luminol.functions.GlobalServerMemoryBar.cancelBarUpdateTask(); //Luminol - Memory bar
super.stopServer();
//Util.shutdownExecutors(); // Paper - moved into super
SkullBlockEntity.clear();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index a8f2eddba3ac3b7c551d39e260e096067e8bdc0f..92e9860b146b6e3e1dc593bfd5bfddab3318761d 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -303,6 +303,7 @@ public class ServerPlayer extends Player {
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
+ public volatile boolean isMemBarVisible = false; //Luminol - Memory bar
public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances getViewDistances() {
return this.viewDistances.get();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 28583ad8117167400faf3ca0dc4bc9f3f44dbedb..730887465bf9ca380ef692b4c2d4a28bc6caaaa9 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2373,6 +2373,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
//Luminol start - Tpsbar
getHandle().isTpsBarVisible = data.getBoolean("tpsbarVisible");
//Luminol end
+ //Luminol start - Membar
+ getHandle().isMemBarVisible = data.getBoolean("membarVisible");
+ //Luminol end
}
}
@@ -2397,6 +2400,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
//Luminol start - Tpsbar
data.putBoolean("tpsbarVisible",handle.isTpsBarVisible);
//Luminol end
+ //Luminol start - Membar
+ data.putBoolean("membarVisible",handle.isMemBarVisible);
+ //Luminol end
// Paper start - persist for use in offline save data
if (!nbttagcompound.contains("Paper")) {
nbttagcompound.put("Paper", new CompoundTag());

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sat, 25 Nov 2023 19:03:34 +0800
Subject: [PATCH] Add config for vanilla random
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 8d1ce8eae252fcf05b6a62d2dc467d6d503d3df4..89d8ffc947d265e0e81943ad851e868b622de168 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -19,6 +19,7 @@ public class LuminolConfig {
public static boolean enableSandDuping = false;
public static boolean enableVoidTrading = false;
public static boolean allowIncorrectTripwireUpdating = false;
+ public static boolean useVanillaRandomSource = false;
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -43,6 +44,7 @@ public class LuminolConfig {
enableSandDuping = get("fixes.enable_sand_duping",enableSandDuping,"If this enabled,The value of safe teleportation will always be false and sand duping will be enabled");
enableVoidTrading = get("fixes.enable_void_trading",enableVoidTrading);
allowIncorrectTripwireUpdating = get("fixes.allow_incorrect_trip_wire_updaing",allowIncorrectTripwireUpdating);
+ useVanillaRandomSource = get("fixes.use_vanilla_random_source",useVanillaRandomSource,"RNG feature related");
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index e357ed9607889536ecd0e6ea8b59c97d3dab631f..cb32a3851a315f1f1b4fb6d26fdffbcb471bfc06 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -569,7 +569,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
this.bb = Entity.INITIAL_AABB;
this.stuckSpeedMultiplier = Vec3.ZERO;
this.nextStep = 1.0F;
- this.random = SHARED_RANDOM; // Paper
+ this.random = LuminolConfig.useVanillaRandomSource ? RandomSource.create() : SHARED_RANDOM;//Luminol - Add config for vanilla random SHARED_RANDOM; // Paper
this.remainingFireTicks = -this.getFireImmuneTicks();
this.fluidHeight = new Object2DoubleArrayMap(2);
this.fluidOnEyes = new HashSet();

View File

@@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 04:50:10 +0000
Subject: [PATCH] Add config for username check
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/UsernameCheckConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/UsernameCheckConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7e4724cc4ab8d911bcaf0106c098b266c843bb1
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/UsernameCheckConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class UsernameCheckConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = true;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "username_checks";
+ }
+}
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index 83b09feec13a00c35e6f8d4f0ccdae1c8da9c0e5..d946a08f7a7532079eab83a7d4affc89e6e6ac1e 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -171,7 +171,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
public void handleHello(ServerboundHelloPacket packet) {
Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", new Object[0]);
// Paper start - Validate usernames
- if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
+ if (me.earthme.luminol.config.modules.misc.UsernameCheckConfig.enabled //Luminol - Add config for username check
+ && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
&& io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation
&& !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) {
Validate.validState(StringUtil.isReasonablePlayerName(packet.name()), "Invalid characters in username", new Object[0]);

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 06:40:44 +0000
Subject: [PATCH] Add config for offline mode warning
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/OfflineModeWarningConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/OfflineModeWarningConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..502b93c7bda9e8577a1901a8777b7cf9b9bdc36b
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/OfflineModeWarningConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class OfflineModeWarningConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = true;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "warn_on_offline_mode";
+ }
+}
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index b82ed9280f96bacbb87ae77a6afd5d82d8863b58..7991026d6ab467b1e889d56815bded3700ae5765 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -294,7 +294,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord";
String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/";
// Paper end - Add Velocity IP Forwarding Support
- if (!this.usesAuthentication()) {
+ if (!this.usesAuthentication() && me.earthme.luminol.config.modules.misc.OfflineModeWarningConfig.enabled) { //Luminol - Add config for offline mod warning
DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware.");
// Spigot start

View File

@@ -1,25 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sat, 25 Nov 2023 19:26:01 +0800
Subject: [PATCH] Add logger field to LuminolConfig
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 89d8ffc947d265e0e81943ad851e868b622de168..74573c50c903cfbe5f9617be5b75c21647f05a91 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -2,11 +2,14 @@ package me.earthme.luminol;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import net.minecraft.server.level.ServerLevel;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
public class LuminolConfig {
+ private static final Logger logger = LogManager.getLogger();
private static final File PARENT_FOLDER = new File("luminol_config");
private static final File MAIN_CONFIG_FILE = new File(PARENT_FOLDER,"luminol_global.toml");
private static CommentedFileConfig MAIN_CONFIG;

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Tue, 20 Feb 2024 13:10:07 +0000
Subject: [PATCH] Add config for out-of-order chat checks
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/InorderChatConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/InorderChatConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..83176a8a7e993b51a0663b0f76161884abbf4951
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/InorderChatConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class InorderChatConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = true;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "mojang_out_of_order_chat_check";
+ }
+}
diff --git a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java
index 300929a406905f5ff1ede664d5b99fb0938d4d2e..7c82730e9a66f9b44dd559d7b8da511f9c5f8ca8 100644
--- a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java
+++ b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java
@@ -45,7 +45,7 @@ public class SignedMessageChain {
SignedMessageLink signedMessageLink = SignedMessageChain.this.nextLink;
if (signedMessageLink == null) {
throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.CHAIN_BROKEN);
- } else if (body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) {
+ } else if (me.earthme.luminol.config.modules.misc.InorderChatConfig.enabled && body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) { // Luminol - Add config for out-of-order chat checks
this.setChainBroken();
throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.OUT_OF_ORDER_CHAT, org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event causes
} else {

View File

@@ -1,98 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sat, 25 Nov 2023 21:28:45 +0800
Subject: [PATCH] Kaiiju region format settings
diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/RegionFileFormat.java b/src/main/java/dev/kaiijumc/kaiiju/region/RegionFileFormat.java
new file mode 100644
index 0000000000000000000000000000000000000000..7164d9cd03186f0657783f83de3d6435cda2b17e
--- /dev/null
+++ b/src/main/java/dev/kaiijumc/kaiiju/region/RegionFileFormat.java
@@ -0,0 +1,16 @@
+package dev.kaiijumc.kaiiju.region;
+
+public enum RegionFileFormat {
+ ANVIL,
+ LINEAR,
+ INVALID;
+
+ public static RegionFileFormat fromString(String format) {
+ for (RegionFileFormat rff : values()) {
+ if (rff.name().equalsIgnoreCase(format)) {
+ return rff;
+ }
+ }
+ return RegionFileFormat.INVALID;
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 74573c50c903cfbe5f9617be5b75c21647f05a91..3d526d7cfb313e419de89be1b275651982be42c7 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -1,10 +1,13 @@
package me.earthme.luminol;
+import dev.kaiijumc.kaiiju.region.RegionFileFormat;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import net.minecraft.server.level.ServerLevel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import java.util.Arrays;
+import java.util.logging.Level;
import java.io.File;
import java.io.IOException;
@@ -24,6 +27,9 @@ public class LuminolConfig {
public static boolean allowIncorrectTripwireUpdating = false;
public static boolean useVanillaRandomSource = false;
+ public static RegionFileFormat regionFormatName = RegionFileFormat.ANVIL;
+ public static int regionFormatLinearCompressionLevel = 1;
+
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -48,6 +54,19 @@ public class LuminolConfig {
enableVoidTrading = get("fixes.enable_void_trading",enableVoidTrading);
allowIncorrectTripwireUpdating = get("fixes.allow_incorrect_trip_wire_updaing",allowIncorrectTripwireUpdating);
useVanillaRandomSource = get("fixes.use_vanilla_random_source",useVanillaRandomSource,"RNG feature related");
+
+ regionFormatName = RegionFileFormat.fromString(get("save.region-format.format", regionFormatName.name()));
+ if (regionFormatName.equals(RegionFileFormat.INVALID)) {
+ logger.error("Unknown region format in luminol global config: " + regionFormatName);
+ logger.error("Falling back to ANVIL region file format.");
+ regionFormatName = RegionFileFormat.ANVIL;
+ }
+ regionFormatLinearCompressionLevel = get("save.region-format.linear.compression-level", regionFormatLinearCompressionLevel);
+ if (regionFormatLinearCompressionLevel > 23 || regionFormatLinearCompressionLevel < 1) {
+ logger.error("Linear region compression level should be between 1 and 22 in luminol global config: " + regionFormatLinearCompressionLevel);
+ logger.error("Falling back to compression level 1.");
+ regionFormatLinearCompressionLevel = 1;
+ }
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 03165a7791aeac54e44391bbb0f432b613369bfa..675bbf1f69011f7f95fabc050c9877d6e70070b2 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -882,7 +882,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper start - rewrite chunk system
worldserver.save((ProgressListener) null, flush, worldserver.noSave && !force, close);
if (flush) {
- MinecraftServer.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", worldserver.getChunkSource().chunkMap.getStorageName());
+ MinecraftServer.LOGGER.info("ThreadedChunkStorage ({}): All chunks are saved", worldserver.getChunkSource().chunkMap.getStorageName()); // Kaiiju
}
// Paper end - rewrite chunk system
}
@@ -906,7 +906,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
//MinecraftServer.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", worldserver2.getChunkSource().chunkMap.getStorageName()); // Paper - move up
}
- MinecraftServer.LOGGER.info("ThreadedAnvilChunkStorage: All dimensions are saved");
+ MinecraftServer.LOGGER.info("ThreadedChunkStorage: All dimensions are saved"); // Kaiiju
}
return flag3;

View File

@@ -0,0 +1,62 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Stabrinai <wujiaxin752@outlook.com>
Date: Sun, 30 Jun 2024 20:46:42 +0800
Subject: [PATCH] Add config to verify signature only in online-mode
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/PublickeyVerifyConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/PublickeyVerifyConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..e45ce3abf49684c911678abcefd69586246cc0e3
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/PublickeyVerifyConfig.java
@@ -0,0 +1,21 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class PublickeyVerifyConfig implements IConfigModule {
+
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "verify_publickey_only_in_online_mode";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java b/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java
index 2fa51c3a70f43cd23b8f494fc643d66cecfda7d2..2c541f300ea1657e2d75d0eeb36809aaf437b205 100644
--- a/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java
+++ b/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java
@@ -9,12 +9,15 @@ import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.UUID;
+
+import me.earthme.luminol.config.modules.misc.PublickeyVerifyConfig;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ThrowingComponent;
import net.minecraft.util.Crypt;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.util.SignatureValidator;
+import org.bukkit.Bukkit;
public record ProfilePublicKey(ProfilePublicKey.Data data) {
public static final Component EXPIRED_PROFILE_PUBLIC_KEY = Component.translatable("multiplayer.disconnect.expired_public_key");
@@ -23,7 +26,7 @@ public record ProfilePublicKey(ProfilePublicKey.Data data) {
public static final Codec<ProfilePublicKey> TRUSTED_CODEC = ProfilePublicKey.Data.CODEC.xmap(ProfilePublicKey::new, ProfilePublicKey::data);
public static ProfilePublicKey createValidated(SignatureValidator servicesSignatureVerifier, UUID playerUuid, ProfilePublicKey.Data publicKeyData) throws ProfilePublicKey.ValidationException {
- if (!publicKeyData.validateSignature(servicesSignatureVerifier, playerUuid)) {
+ if ((!PublickeyVerifyConfig.enabled || Bukkit.getServer().getOnlineMode()) && !publicKeyData.validateSignature(servicesSignatureVerifier, playerUuid)) { // Luminol - Verify signature only in online-mode
throw new ProfilePublicKey.ValidationException(INVALID_SIGNATURE, org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PUBLIC_KEY_SIGNATURE); // Paper - kick event causes
} else {
return new ProfilePublicKey(publicKeyData);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,274 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Sun, 10 Mar 2024 05:04:33 +0000
Subject: [PATCH] Add a simple watchdog for tick regions
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java
index fc3d332aa1c1d469cedfe2aaa7102dcd78e25642..1ae61bc6603dd3ac290e3ead20416f9c5b63ff02 100644
--- a/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java
@@ -279,6 +279,7 @@ public final class RegionizedServer {
*/
private void globalTick(final int tickCount) {
+ me.earthme.luminol.utils.LuminolWatchDog.globalRegionHeartBeat(); //Luminol
/*
if (false) {
io.papermc.paper.threadedregions.ThreadedTicketLevelPropagator.main(null);
diff --git a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java
index 2ad25dd345ab42125d456f2b9cf67d8c4515c8b7..183fede965c3d227bbcc7e54781869e09796081f 100644
--- a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java
+++ b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java
@@ -402,10 +402,11 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
@Override
protected void tickRegion(final int tickCount, final long startTime, final long scheduledEnd) {
+ me.earthme.luminol.utils.LuminolWatchDog.tickRegionHeartBeat(); //Luminol - Simple watchdog
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
profiler.startTick(); try { // Folia - profiler
MinecraftServer.getServer().tickServer(startTime, scheduledEnd, TimeUnit.MILLISECONDS.toMillis(10L), this.region);
- } finally { profiler.stopTick(); } // Folia - profiler
+ } finally { profiler.stopTick(); me.earthme.luminol.utils.LuminolWatchDog.releaseTickRegion(); } // Folia - profiler //Luminol - Simple watchdog
}
@Override
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/WatchdogConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/WatchdogConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..71d80b401470db777a86274d32f178bb2aa023d5
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/WatchdogConfig.java
@@ -0,0 +1,27 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.HotReloadUnsupported;
+import me.earthme.luminol.config.IConfigModule;
+
+public class WatchdogConfig implements IConfigModule {
+
+ @HotReloadUnsupported
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+ @ConfigInfo(baseName = "warn_period_ticks")
+ public static long warnPeriodTicks = 5 * 20;
+ @ConfigInfo(baseName = "timeout_ticks")
+ public static long timeOutTicks = 30 * 20;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "watchdog";
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/utils/LuminolWatchDog.java b/src/main/java/me/earthme/luminol/utils/LuminolWatchDog.java
new file mode 100644
index 0000000000000000000000000000000000000000..e19c6330a48cee402b1a999ca71cb2329d530356
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/utils/LuminolWatchDog.java
@@ -0,0 +1,178 @@
+package me.earthme.luminol.utils;
+
+import com.google.common.collect.Maps;
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
+import io.papermc.paper.threadedregions.TickRegionScheduler;
+import io.papermc.paper.util.StacktraceDeobfuscator;
+import me.earthme.luminol.config.modules.misc.WatchdogConfig;
+import net.minecraft.server.MinecraftServer;
+import org.apache.commons.lang3.tuple.Pair;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+public class LuminolWatchDog {
+ private static final Object keepaliveDataLock = new Object();
+ private static Pair<Thread,Long> globalRegionLastKeepalive = null;
+ private static final Map<Thread,Pair<ThreadedRegionizer.ThreadedRegion<?,?>,Long>> otherTickRegionKeepalive = Maps.newHashMap();
+ private static final Executor checkTimer = CompletableFuture.delayedExecutor(50, TimeUnit.MILLISECONDS,Executors.newSingleThreadExecutor());
+ private static final Logger logger = MinecraftServer.LOGGER;
+ private static int tickCount = 0;
+ private static volatile boolean runScheduleNext = true;
+
+ public static void boot(){
+ if (!WatchdogConfig.enabled){
+ return;
+ }
+
+ runCheck();
+ }
+
+ private static void scheduleCheck(){
+ checkTimer.execute(LuminolWatchDog::runCheck);
+ }
+
+ public static void stopTicking(){
+ runScheduleNext = false;
+ }
+
+ private static void runCheck(){
+ try {
+ if (MinecraftServer.getServer().isStopped() || !runScheduleNext){
+ return;
+ }
+
+ tickCount++;
+
+ final List<Pair<Thread,Long>> threadsToWarn = new ArrayList<>();
+ final long currentTimeNano = System.nanoTime();
+ boolean shouldStopServer = false;
+
+ synchronized (keepaliveDataLock){
+ if (globalRegionLastKeepalive != null){
+ final Thread lastGlobalRegionThread = globalRegionLastKeepalive.getLeft();
+ final long lastTicked = globalRegionLastKeepalive.getRight();
+
+ final long timeEscaped = currentTimeNano - lastTicked;
+
+ if (timeEscaped >= WatchdogConfig.warnPeriodTicks * 50 * 1000 * 1000){
+ threadsToWarn.add(Pair.of(lastGlobalRegionThread,timeEscaped));
+ }
+ }
+
+ for (Map.Entry<Thread,Pair<ThreadedRegionizer.ThreadedRegion<?,?>,Long>> tickData : otherTickRegionKeepalive.entrySet()){
+ final Thread targetThread = tickData.getKey();
+ final Pair<ThreadedRegionizer.ThreadedRegion<?, ?>, Long> keepaliveData = tickData.getValue();
+ final long lastKeepalive = keepaliveData.getRight();
+
+ final long timeEscaped = currentTimeNano - lastKeepalive;
+
+ if (timeEscaped >= WatchdogConfig.warnPeriodTicks * 50 * 1000 * 1000){
+ threadsToWarn.add(Pair.of(targetThread,timeEscaped));
+ }
+ }
+
+ for(Pair<Thread,Long> warnInfo : threadsToWarn){
+ final Thread targetThread = warnInfo.getLeft();
+ final long timeEscaped = warnInfo.getRight();
+
+ final ThreadedRegionizer.ThreadedRegion<?,?> targetRegion = targetThread == globalRegionLastKeepalive.getKey() ? null : otherTickRegionKeepalive.get(targetThread).getLeft();
+
+ if (tickCount % WatchdogConfig.warnPeriodTicks == 0){
+ dumpSingleRegion(targetThread,targetRegion,timeEscaped);
+ }
+
+ if (timeEscaped > WatchdogConfig.timeOutTicks * 50 * 1000 * 1000){
+ shouldStopServer = true;
+ runScheduleNext = false;
+ }
+ }
+
+ if (shouldStopServer){
+ MinecraftServer.getServer().stopServer();
+ }
+ }
+ }finally {
+ if (runScheduleNext){
+ scheduleCheck();
+ }
+ }
+ }
+
+ private static void dumpSingleRegion(@NotNull Thread thread, @Nullable ThreadedRegionizer.ThreadedRegion<?,?> region,long timeEscaped){
+ final StringBuilder messageBuilder = new StringBuilder();
+ messageBuilder.append("====================================").append("\n");
+ messageBuilder.append("There is a single region that has no responding in " + TimeUnit.NANOSECONDS.toSeconds(timeEscaped) + " seconds!").append("\n");
+ messageBuilder.append("If you believe this is a bug,please send it to github issue after checking your plugins!").append("\n");
+ messageBuilder.append("Tick Region: ").append(region == null ? "Global Region" : "ChunkX(Center): " + region.getCenterChunk().x + " ChunkZ(Center): " + region.getCenterChunk().z).append("\n");
+ messageBuilder.append("Thread Name: ").append(thread.getName()).append("\n");
+ messageBuilder.append("Thread Id: ").append(thread.getId()).append("\n");
+
+ final ThreadInfo targetThreadInfo = ManagementFactory.getThreadMXBean().getThreadInfo(thread.getId());
+
+ messageBuilder.append("Is Suspend: ").append(targetThreadInfo.isSuspended()).append("\n");
+ messageBuilder.append("Thread State: ").append(targetThreadInfo.getThreadState()).append("\n");
+ messageBuilder.append("Thread Priority: ").append(targetThreadInfo.getPriority()).append("\n");
+ messageBuilder.append("Thread Stack Trace:").append("\n");
+
+ for (StackTraceElement stackTraceElement : StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(thread.getStackTrace())){
+ messageBuilder.append("\t\t").append(stackTraceElement).append("\n");
+ }
+
+ messageBuilder.append("\n");
+ messageBuilder.append("====================================");
+
+ logger.error(messageBuilder.toString());
+ }
+
+ public static void globalRegionHeartBeat(){
+ if (!WatchdogConfig.enabled){
+ return;
+ }
+
+ synchronized (keepaliveDataLock){
+ globalRegionLastKeepalive = Pair.of(Thread.currentThread(),System.nanoTime());
+ }
+ }
+
+ public static void tickRegionHeartBeat(){
+ if (!WatchdogConfig.enabled){
+ return;
+ }
+
+ final ThreadedRegionizer.ThreadedRegion<?,?> currentRegion = TickRegionScheduler.getCurrentRegion();
+
+ if (currentRegion == null) {
+ return;
+ }
+
+ synchronized (keepaliveDataLock){
+ if (!otherTickRegionKeepalive.containsKey(Thread.currentThread())){
+ otherTickRegionKeepalive.put(Thread.currentThread(),Pair.of(currentRegion,System.nanoTime()));
+ return;
+ }
+
+ otherTickRegionKeepalive.replace(Thread.currentThread(),Pair.of(currentRegion,System.nanoTime()));
+ }
+ }
+
+ public static void releaseTickRegion(){
+ if (!WatchdogConfig.enabled){
+ return;
+ }
+
+ synchronized (keepaliveDataLock){
+ otherTickRegionKeepalive.remove(Thread.currentThread());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 3a6d567ee9db93606aec30255400dff4f9f87b05..14114e868d3547f2f2d4149312742d5e995e8959 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1003,6 +1003,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Folia end - region threading
public void stopServer() {
+ me.earthme.luminol.utils.LuminolWatchDog.stopTicking(); // Luminol - Watchdog
// Folia start - region threading
// halt scheduler
// don't wait, we may be on a scheduler thread
@@ -1223,6 +1224,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.statusIcon = (ServerStatus.Favicon) this.loadStatusIcon().orElse(null); // CraftBukkit - decompile error
this.status = this.buildServerStatus();
+ me.earthme.luminol.utils.LuminolWatchDog.boot(); //Luminol - Simple watchdog
+
// Folia start - region threading
if (true) {
io.papermc.paper.threadedregions.RegionizedServer.getInstance().init(); // Folia - region threading - only after loading worlds

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Mon, 12 Aug 2024 21:30:50 +0800
Subject: [PATCH] Add config to disable entity tick catchers
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/DisableEntityCatchConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/DisableEntityCatchConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..0fd71151a85dd87c2294033e2e7512ac365caa62
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/DisableEntityCatchConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class DisableEntityCatchConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.EXPERIMENT;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "disable_entity_exception_catchers";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 75ecbdb5bdacb4d4b27d60fe1c1a35c3a9c16207..fc43204a9234ebac35003121e7ae29e566a6386b 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -1351,7 +1351,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
tickConsumer.accept(entity);
MinecraftServer.getServer().executeMidTickTasks(); // Paper - execute chunk tasks mid tick
} catch (Throwable throwable) {
- if (throwable instanceof ThreadDeath) throw throwable; // Paper
+ if (throwable instanceof ThreadDeath || me.earthme.luminol.config.modules.experiment.DisableEntityCatchConfig.enabled) throw throwable; // Paper // Luminol
// Paper start - Prevent block entity and entity crashes
final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ());
MinecraftServer.LOGGER.error(msg, throwable);

View File

@@ -1,55 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 15:36:59 +0800
Subject: [PATCH] Petal Reduce sensor work
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 0657fce8aabb956a400b3cead53c28ef52e67fe9..c3a481cb7bea0619b1af0e3203e9d88514e84c62 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -40,6 +40,8 @@ public class LuminolConfig {
public static int linearFlushFrequency = 10;
public static int linearFlushThreads = 1;
+ public static boolean reduceSensorWork = true;
+
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -98,6 +100,8 @@ public class LuminolConfig {
linearFlushThreads = Math.max(Runtime.getRuntime().availableProcessors() + linearFlushThreads, 1);
else
linearFlushThreads = Math.max(linearFlushThreads, 1);
+
+ reduceSensorWork = get("optimizations.reduce_sensor_work",reduceSensorWork,"This optimization is from petal.You can find out more about it on petal's repository");
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 4e9d510646abbc2d2b6f2d935f7416b6872eb234..d3f8aa29b05a3813c0ec6e2ea5a253868abd6b07 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -9,6 +9,8 @@ import java.util.Optional;
import java.util.UUID;
import java.util.function.Predicate;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.core.Vec3i;
@@ -924,10 +926,11 @@ public abstract class Mob extends LivingEntity implements Targeting {
return;
}
// Paper end
+ int i = this.tickCount + this.getId(); // Folia - region threading //Luminol - Petal - Move up
+
this.level().getProfiler().push("sensing");
- this.sensing.tick();
+ if (i % 10 == 0 || !LuminolConfig.reduceSensorWork)this.sensing.tick(); //Luminol - Petal - Reduce sensor work
this.level().getProfiler().pop();
- int i = this.tickCount + this.getId(); // Folia - region threading
if (i % 2 != 0 && this.tickCount > 1) {
this.level().getProfiler().push("targetSelector");

View File

@@ -1,52 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 15:56:26 +0800
Subject: [PATCH] Add config for username check
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index c3a481cb7bea0619b1af0e3203e9d88514e84c62..0929a5a167691bde7dedaa1e2812b34ad69913d6 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -28,6 +28,7 @@ public class LuminolConfig {
public static String tpsBarFormat = "<gray>TPS<yellow>:</yellow> <tps> MSPT<yellow>:</yellow> <mspt> Ping<yellow>:</yellow> <ping>ms";
public static String[] tpsColors = new String[]{"GREEN","YELLOW","RED","PURPLE"};
public static String[] pingColors = new String[]{"GREEN","YELLOW","RED","PURPLE"};
+ public static boolean disableUsernameCheck = false;
public static boolean safeTeleportation = true;
public static boolean enableSandDuping = false;
@@ -71,6 +72,7 @@ public class LuminolConfig {
tpsBarFormat = get("misc.tpsbar_title_format",tpsBarFormat,"The format of tpsbar.");
tpsColors = get("misc.tpsbar_range_colors", List.of(tpsColors),"The bar and text color of each tps ranges.The last is the color of initial bar's color").toArray(String[]::new);
pingColors = get("misc.tpsbar_ping_range_colors",List.of(pingColors),"As same as the tpsColors").toArray(String[]::new);
+ disableUsernameCheck = get("misc.disable_username_check",disableUsernameCheck,"Disable username check that can accept usernames with other characters(such as Chinese).Not recommended to use");
if (tpsbarEnabled){
initTpsbar();
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index f7c2d6d82ee1b5975cd114934b7beaec3d5d490d..f26c44bb8c4e3d8556c8c5ac7389e02381239594 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -16,6 +16,8 @@ import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.DefaultUncaughtExceptionHandler;
import net.minecraft.core.UUIDUtil;
import net.minecraft.network.Connection;
@@ -162,10 +164,10 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
@Override
public void handleHello(ServerboundHelloPacket packet) {
Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", new Object[0]);
- Validate.validState(ServerLoginPacketListenerImpl.isValidUsername(packet.name()), "Invalid characters in username", new Object[0]);
+ if (!LuminolConfig.disableUsernameCheck) Validate.validState(ServerLoginPacketListenerImpl.isValidUsername(packet.name()), "Invalid characters in username", new Object[0]); //Luminol - Add config for usename check
// Paper start - validate usernames
if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation) {
- if (!this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation && !validateUsername(packet.name())) {
+ if (!this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation && !validateUsername(packet.name()) && !LuminolConfig.disableUsernameCheck) { //Luminol - Add config for username check
ServerLoginPacketListenerImpl.this.disconnect("Failed to verify username!");
return;
}

View File

@@ -0,0 +1,106 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Mon, 12 Aug 2024 21:29:59 +0800
Subject: [PATCH] Add config to disable async catchers
diff --git a/src/main/java/io/papermc/paper/util/TickThread.java b/src/main/java/io/papermc/paper/util/TickThread.java
index 906f1c9e619a924c622acc76652a4569305edc8d..aaa72fd0bb866ac18ee06e8f50b1374b24c4a8de 100644
--- a/src/main/java/io/papermc/paper/util/TickThread.java
+++ b/src/main/java/io/papermc/paper/util/TickThread.java
@@ -46,49 +46,49 @@ public class TickThread extends Thread {
*/
@Deprecated
public static void ensureTickThread(final String reason) {
- if (!isTickThread()) {
+ if (!isTickThread() && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
throw new IllegalStateException(reason);
}
}
public static void ensureTickThread(final ServerLevel world, final BlockPos pos, final String reason) {
- if (!isTickThreadFor(world, pos)) {
+ if (!isTickThreadFor(world, pos) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
throw new IllegalStateException(reason);
}
}
public static void ensureTickThread(final ServerLevel world, final ChunkPos pos, final String reason) {
- if (!isTickThreadFor(world, pos)) {
+ if (!isTickThreadFor(world, pos) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
throw new IllegalStateException(reason);
}
}
public static void ensureTickThread(final ServerLevel world, final int chunkX, final int chunkZ, final String reason) {
- if (!isTickThreadFor(world, chunkX, chunkZ)) {
+ if (!isTickThreadFor(world, chunkX, chunkZ) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
throw new IllegalStateException(reason);
}
}
public static void ensureTickThread(final Entity entity, final String reason) {
- if (!isTickThreadFor(entity)) {
+ if (!isTickThreadFor(entity) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
throw new IllegalStateException(reason);
}
}
public static void ensureTickThread(final ServerLevel world, final AABB aabb, final String reason) {
- if (!isTickThreadFor(world, aabb)) {
+ if (!isTickThreadFor(world, aabb) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
throw new IllegalStateException(reason);
}
}
public static void ensureTickThread(final ServerLevel world, final double blockX, final double blockZ, final String reason) {
- if (!isTickThreadFor(world, blockX, blockZ)) {
+ if (!isTickThreadFor(world, blockX, blockZ) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
throw new IllegalStateException(reason);
}
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/DisableAsyncCatcherConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/DisableAsyncCatcherConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..61f653eeca366672ded88c491cf5c59e546e7301
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/DisableAsyncCatcherConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class DisableAsyncCatcherConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.EXPERIMENT;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "disable_async_catchers";
+ }
+}
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
index 2e074c16dab1ead47914070329da0398c3274048..0a9151125539bb20f94a3d8b307b328d4abbe010 100644
--- a/src/main/java/org/spigotmc/AsyncCatcher.java
+++ b/src/main/java/org/spigotmc/AsyncCatcher.java
@@ -9,7 +9,7 @@ public class AsyncCatcher
public static void catchOp(String reason)
{
- if (!(io.papermc.paper.util.TickThread.isTickThread())) // Paper
+ if (!(io.papermc.paper.util.TickThread.isTickThread()) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) // Luminol
{
MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper
throw new IllegalStateException( "Asynchronous " + reason + "!" );

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sat, 31 Aug 2024 11:00:47 +0800
Subject: [PATCH] Add experiment config for command block command execution
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..3eafc59cc015569d3da8b1d8c4bfd046af17e0be
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class CommandBlockConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enable")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.EXPERIMENT;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "force_enable_command_block_execution";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
index b8a571fcc44f67ac8f6089e039a8620bf6c40603..c973535eba031f102c6cae8f9b75547ba3a95376 100644
--- a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
+++ b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
@@ -117,7 +117,7 @@ public abstract class BaseCommandBlock implements CommandSource {
}
public boolean performCommand(Level world) {
- if (true) return false; // Folia - region threading
+ if (!me.earthme.luminol.config.modules.experiment.CommandBlockConfig.enabled) return false; // Folia - region threading // Luminol
if (!world.isClientSide && world.getGameTime() != this.lastExecution) {
if ("Searge".equalsIgnoreCase(this.command)) {
this.lastOutput = Component.literal("#itzlipofutzli");

View File

@@ -0,0 +1,67 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 06:30:03 +0000
Subject: [PATCH] Try fixing folia spector teleportation
diff --git a/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaSpectorTeleportationFixConfig.java b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaSpectorTeleportationFixConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..01f8c6ff3662569be5a4ff998bcd4fbbcb555105
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaSpectorTeleportationFixConfig.java
@@ -0,0 +1,25 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class FoliaSpectorTeleportationFixConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments =
+ """
+ The teleportation of spector players would call absMoveTo directly.\s
+ And when the camera teleported to another region,this would call absMoveTo\s
+ to let the spector player move to another region without any checks, which \s
+ would trigger the async catcher and crash the server""")
+ public static boolean fixSpectorTeleportFolia = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.FIXES;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "folia.fix_spector_teleportation";
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 92e9860b146b6e3e1dc593bfd5bfddab3318761d..cd411f0a178e3c4c20f1b5aecee2617a2ce6c8f3 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -894,9 +894,24 @@ public class ServerPlayer extends Player {
}
Entity entity = this.getCamera();
+ //Luminol start - Fix folia spector teleportation
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(entity) && me.earthme.luminol.config.modules.fixes.FoliaSpectorTeleportationFixConfig.fixSpectorTeleportFolia){
+ this.setCamera(this);
+ }
+ //Luminol end
if (entity != this) {
- if (entity.isAlive()) {
+ // Luminol start - Fix folia spector teleportation
+ var flag = false;
+ var cameraPos = entity.blockPosition();
+ var cameraLevel = entity.level();
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor((ServerLevel) cameraLevel, cameraPos) && me.earthme.luminol.config.modules.fixes.FoliaSpectorTeleportationFixConfig.fixSpectorTeleportFolia){
+ this.setCamera(this);
+ flag = true;
+ }
+ // Luminol end
+
+ if (entity.isAlive() && !flag) { // Luminol - Fix folia spector teleportation
this.absMoveTo(entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot());
this.serverLevel().getChunkSource().move(this);
if (this.wantsToStopRiding()) {

View File

@@ -0,0 +1,88 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 06:34:15 +0000
Subject: [PATCH] Teleport async if entity was moving to another region at once
diff --git a/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaEntityMovingFixConfig.java b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaEntityMovingFixConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..0e51d465db3554ac80d00c6b85cc1f013f3949ba
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaEntityMovingFixConfig.java
@@ -0,0 +1,28 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class FoliaEntityMovingFixConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments =
+ """
+ A simple fix of a issue on folia\s
+ (Some times the entity would\s
+ have a large moment that cross the\s
+ different tick regions and it would\s
+ make the server crashed) but sometimes it might doesn't work""")
+ public static boolean enabled = false;
+ @ConfigInfo(baseName = "warn_on_detected")
+ public static boolean warnOnDetected = true;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.FIXES;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "folia.fix_high_velocity_issue";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 681f1476754f49d01b99a892ef2618cac341cd25..fd1dbe0067d074101884fe1a66045f5316adeafc 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -1127,6 +1127,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
// Paper end - detailed watchdog information
+ //Luminol start - Fix large pos moving
+ private volatile boolean preventMoving = false;
+ //Luminol end
+
public void move(MoverType movementType, Vec3 movement) {
final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
// Paper start - detailed watchdog information
@@ -1137,6 +1141,32 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.moveStartZ = this.getZ();
this.moveVector = movement;
}
+ //Luminol start - Fix high position moving
+ if (me.earthme.luminol.config.modules.fixes.FoliaEntityMovingFixConfig.enabled && io.papermc.paper.util.TickThread.isTickThread()){ //Except the threads because it may be called by the chunk system worker thread
+ var finalPosition = movement.add(this.position);
+ if (this.preventMoving || Double.isNaN(finalPosition.x) || Double.isNaN(finalPosition.y) || Double.isNaN(finalPosition.z)){
+ return;
+ }
+
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(((ServerLevel) this.level),finalPosition)){
+ this.preventMoving = true;
+ this.teleportAsync(
+ (ServerLevel) this.level(),
+ finalPosition,
+ this.getYRot(), this.getXRot(),
+ null, PlayerTeleportEvent.TeleportCause.UNKNOWN,
+ Entity.TELEPORT_FLAG_LOAD_CHUNK | Entity.TELEPORT_FLAG_TELEPORT_PASSENGERS,
+ result -> {
+ this.preventMoving = false;
+ }
+ );
+ if (me.earthme.luminol.config.modules.fixes.FoliaEntityMovingFixConfig.warnOnDetected){
+ MinecraftServer.LOGGER.warn("Entity {} with entityId {} has tried moving to another region!",this.type.getCategory().getName(),this.getId());
+ }
+ return;
+ }
+ }
+ //Luminol end
try {
// Paper end - detailed watchdog information
if (this.noPhysics) {

View File

@@ -0,0 +1,97 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Mon, 10 Jun 2024 10:51:08 +0000
Subject: [PATCH] Try fixing folia off region POI accessing issue
diff --git a/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaPOIAccessOffRegionFixConfig.java b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaPOIAccessOffRegionFixConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..7812a71f05dd32646037afd22cdabf72bb23b0d1
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaPOIAccessOffRegionFixConfig.java
@@ -0,0 +1,25 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class FoliaPOIAccessOffRegionFixConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments =
+ """
+ The POIManager of folia has something which has not been patched\s
+ for regionized ticking and these would trigger the async catcher\s
+ and make the server crash.If you would like to prevent it and didn't\s
+ mind the side effect(currently unknown), you can enable this""")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.FIXES;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "folia.fix_poi_access_off_region";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/GoToPotentialJobSite.java b/src/main/java/net/minecraft/world/entity/ai/behavior/GoToPotentialJobSite.java
index aac1df9e2c0652bc6348af0404deba7465f82d42..4dcf71e9f861596bd02902d0851ffa57ff9e4170 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/GoToPotentialJobSite.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/GoToPotentialJobSite.java
@@ -49,10 +49,17 @@ public class GoToPotentialJobSite extends Behavior<Villager> {
ServerLevel serverLevel2 = serverLevel.getServer().getLevel(pos.dimension());
if (serverLevel2 != null) {
PoiManager poiManager = serverLevel2.getPoiManager();
+ //Luminol start - Fix off region POI accessing
+ java.lang.Runnable scheduledRelease = () -> {
if (poiManager.exists(blockPos, poiType -> true)) {
poiManager.release(blockPos);
}
-
+ };
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(serverLevel2, blockPos) && me.earthme.luminol.config.modules.fixes.FoliaPOIAccessOffRegionFixConfig.enabled)
+ io.papermc.paper.threadedregions.RegionizedServer.getInstance().taskQueue.queueTickTaskQueue(serverLevel2, blockPos.getX() >> 4, blockPos.getZ() >> 4, scheduledRelease);
+ else
+ scheduledRelease.run();
+ //Luminol end
DebugPackets.sendPoiTicketCountPacket(serverLevel, blockPos);
}
});
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/YieldJobSite.java b/src/main/java/net/minecraft/world/entity/ai/behavior/YieldJobSite.java
index d1a9b62d3304916275dd6b4c4e783cf1563b5e21..dd1baee4bc36b28b7e10d98525d55cbcfb562649 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/YieldJobSite.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/YieldJobSite.java
@@ -6,6 +6,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.GlobalPos;
import net.minecraft.core.Holder;
import net.minecraft.network.protocol.game.DebugPackets;
+import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder;
@@ -33,7 +34,10 @@ public class YieldJobSite {
} else if (entity.getVillagerData().getProfession() != VillagerProfession.NONE) {
return false;
} else {
- BlockPos blockPos = context.<GlobalPos>get(potentialJobSite).pos();
+ final GlobalPos globalPos = context.<GlobalPos>get(potentialJobSite); //Luminol - Try fixing off main POI accessing
+ final ServerLevel targetLevel = net.minecraft.server.MinecraftServer.getServer().getLevel(globalPos.dimension()); //Luminol - Try fixing off main POI accessing
+ BlockPos blockPos = globalPos.pos(); //Luminol - Try fixing off main POI accessing
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(targetLevel, blockPos) && me.earthme.luminol.config.modules.fixes.FoliaPOIAccessOffRegionFixConfig.enabled) return true; //Luminol - Try fixing off main POI accessing
Optional<Holder<PoiType>> optional = world.getPoiManager().getType(blockPos);
if (optional.isEmpty()) {
return true;
diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
index cf69b4ed4a40015a23d053230c3f326a700788ef..5fdcad0038aad61d68cd329e72c8db309c5e3926 100644
--- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
@@ -96,7 +96,7 @@ public class PoiManager extends SectionStorage<PoiSection> {
public Stream<PoiRecord> getInSquare(Predicate<Holder<PoiType>> typePredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus) {
int i = Math.floorDiv(radius, 16) + 1;
- return ChunkPos.rangeClosed(new ChunkPos(pos), i).flatMap(chunkPos -> this.getInChunk(typePredicate, chunkPos, occupationStatus)).filter(poi -> {
+ return ChunkPos.rangeClosed(new ChunkPos(pos), i).filter(cpos -> me.earthme.luminol.config.modules.fixes.FoliaPOIAccessOffRegionFixConfig.enabled ? io.papermc.paper.util.TickThread.isTickThreadFor(this.world,cpos) : true).flatMap(chunkPos -> this.getInChunk(typePredicate, chunkPos, occupationStatus)).filter(poi -> { //Luminol - Fix off region POI access
BlockPos blockPos2 = poi.getPos();
return Math.abs(blockPos2.getX() - pos.getX()) <= radius && Math.abs(blockPos2.getZ() - pos.getZ()) <= radius;
});

View File

@@ -0,0 +1,151 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 06:58:52 +0000
Subject: [PATCH] Prevent teleportAsync calling during moving event being
diff --git a/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaTeleportAsyncFixConfig.java b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaTeleportAsyncFixConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f1449545d6d217b46a9ffae705123daefe55b25
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaTeleportAsyncFixConfig.java
@@ -0,0 +1,24 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class FoliaTeleportAsyncFixConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments =
+ "A fix which fixed some bugs of teleportAsync " +
+ "that caused by plugins(such as Residence)")
+ public static boolean enabled = false;
+ @ConfigInfo(baseName = "throw_on_detected")
+ public static boolean throwOnDetected = true;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.FIXES;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "folia.prevent_teleportasync_call_during_moving";
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index bdcf43104a53f530453615b17bd690c7a5c0a78d..8ec763f933e79a1c8e7a7d3b3c0277ca2fca4b74 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -348,6 +348,10 @@ public class ServerPlayer extends Player {
public double lastEntitySpawnRadiusSquared = -1.0;
// Paper end - optimise chunk tick iteration
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ public boolean handlingMoveEvent = false;
+ //Luminol end
+
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) {
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
this.chatVisibility = ChatVisiblity.FULL;
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index e16d24bd83cddce7ead70a2a3847d09e988c715e..dcbfc99e0877f9e87d6329542ec11664d527e7e4 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -695,7 +695,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
Location oldTo = to.clone();
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
+ this.player.handlingMoveEvent = true; //Luminol - Prevent teleportAsync calling during moving event being handled
this.cserver.getPluginManager().callEvent(event);
+ this.player.handlingMoveEvent = false; //Luminol - Prevent teleportAsync calling during moving event being handled
// If the event is cancelled we move the player back to their old location.
if (event.isCancelled()) {
@@ -1610,7 +1612,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
Location oldTo = to.clone();
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
+ this.player.handlingMoveEvent = true; //Luminol - Prevent teleportAsync calling during moving event being handled
this.cserver.getPluginManager().callEvent(event);
+ this.player.handlingMoveEvent = false; //Luminol - Prevent teleportAsync calling during moving event being handled
// If the event is cancelled we move the player back to their old location.
if (event.isCancelled()) {
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index fd1dbe0067d074101884fe1a66045f5316adeafc..816196016cad939c033a583e326ffff3894dca29 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -4038,6 +4038,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
java.util.function.Consumer<Entity> teleportComplete) {
io.papermc.paper.util.TickThread.ensureTickThread(this, "Cannot teleport entity async");
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ if (this instanceof ServerPlayer player && me.earthme.luminol.config.modules.fixes.FoliaTeleportAsyncFixConfig.enabled){
+ if (player.handlingMoveEvent){
+ if (me.earthme.luminol.config.modules.fixes.FoliaTeleportAsyncFixConfig.throwOnDetected){
+ throw new IllegalStateException("Player " + player.getScoreboardName() + " is trying to teleport to " + pos + " during move event handling!");
+ }
+ MinecraftServer.LOGGER.warn("Player {} is trying to teleport to {} during move event handling!",player.getScoreboardName(),pos);
+ return false;
+ }
+ }
+ //Luminol end
+
if (!ServerLevel.isInSpawnableBounds(new BlockPos(io.papermc.paper.util.CoordinateUtils.getBlockX(pos), io.papermc.paper.util.CoordinateUtils.getBlockY(pos), io.papermc.paper.util.CoordinateUtils.getBlockZ(pos)))) {
return false;
}
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
index 4d7454e5a64fc18e63793a221daa94617f17c666..a1dc46ec6d53389eb7c801a7a14c4169406de580 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
@@ -375,7 +375,21 @@ public abstract class AbstractMinecart extends VehicleEntity {
this.level().getCraftServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle));
if (!from.equals(to)) {
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ for (Entity passenger : this.getPassengers()) {
+ if (passenger instanceof net.minecraft.server.level.ServerPlayer player){
+ player.handlingMoveEvent = true;
+ }
+ }
+ //Luminol end
this.level().getCraftServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleMoveEvent(vehicle, from, to));
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ for (Entity passenger : this.getPassengers()) {
+ if (passenger instanceof net.minecraft.server.level.ServerPlayer player){
+ player.handlingMoveEvent = false;
+ }
+ }
+ //Luminol end
}
// CraftBukkit end
if (this.getMinecartType() == AbstractMinecart.Type.RIDEABLE && this.getDeltaMovement().horizontalDistanceSqr() > 0.01D) {
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
index b068cff9b5aa457d65b679529956e8210296d799..d002519a356072284faa5f879e188f3e3062939f 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
@@ -370,8 +370,22 @@ public class Boat extends VehicleEntity implements VariantHolder<Boat.Type> {
server.getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle));
if (this.lastLocation != null && !this.lastLocation.equals(to)) {
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ for (Entity passenger : this.getPassengers()) {
+ if (passenger instanceof net.minecraft.server.level.ServerPlayer player){
+ player.handlingMoveEvent = true;
+ }
+ }
+ //Luminol end
VehicleMoveEvent event = new VehicleMoveEvent(vehicle, this.lastLocation, to);
server.getPluginManager().callEvent(event);
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ for (Entity passenger : this.getPassengers()) {
+ if (passenger instanceof net.minecraft.server.level.ServerPlayer player){
+ player.handlingMoveEvent = false;
+ }
+ }
+ //Luminol end
}
this.lastLocation = vehicle.getLocation();
// CraftBukkit end

File diff suppressed because it is too large Load Diff

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Kaiiju Don't pathfind outside region
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java b/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
index 1ab77f3518d1df30f66ae44d7d4fa69e5b32d93a..98bf17441da3169d49de55fe89d79ebe250a2b7e 100644
index 2a7a26ca447cc78f24e61a2bf557411c31eb16b2..28602455d659dfac4653ab5b7bf4139f65c190ad 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
@@ -107,7 +107,9 @@ public class MoveToTargetSink extends Behavior<Mob> {
@@ -120,7 +120,9 @@ public class MoveToTargetSink extends Behavior<Mob> {
private boolean tryComputePath(Mob entity, WalkTarget walkTarget, long time) {
BlockPos blockPos = walkTarget.getTarget().currentBlockPosition();

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Kaiiju Vanilla end portal teleportation
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 6f3e87661c3181b6537e4d6d96e50d8d5680c040..3a5c8f1f9a8173777b00d43c15e8e313526d3e28 100644
index 816196016cad939c033a583e326ffff3894dca29..a424a9c9921eabca90bd7a49946e5814d4aea8dd 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -4108,12 +4108,17 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -4245,12 +4245,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
targetPos, 16, // load 16 blocks to be safe from block physics
ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGH,
(chunks) -> {
@@ -28,7 +28,7 @@ index 6f3e87661c3181b6537e4d6d96e50d8d5680c040..3a5c8f1f9a8173777b00d43c15e8e313
);
}
);
@@ -4300,6 +4305,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -4437,6 +4442,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
if (!this.canPortalAsync(takePassengers)) {
return false;
}
@@ -39,7 +39,7 @@ index 6f3e87661c3181b6537e4d6d96e50d8d5680c040..3a5c8f1f9a8173777b00d43c15e8e313
Vec3 initialPosition = this.position();
ChunkPos initialPositionChunk = new ChunkPos(
@@ -4358,7 +4367,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -4495,7 +4504,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// place
passengerTree.root.placeInAsync(
originWorld, destination, Entity.TELEPORT_FLAG_LOAD_CHUNK | (takePassengers ? Entity.TELEPORT_FLAG_TELEPORT_PASSENGERS : 0L),

View File

@@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 04:46:30 +0000
Subject: [PATCH] Petal Reduce sensor work
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/PetalReduceSensorWorkConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/PetalReduceSensorWorkConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd45cf1fde5ee4cf8347064f106c64b861b77ead
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/PetalReduceSensorWorkConfig.java
@@ -0,0 +1,22 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class PetalReduceSensorWorkConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = true;
+ @ConfigInfo(baseName = "delay_ticks")
+ public static int delayTicks = 10;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.OPTIMIZATIONS;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "reduce_sensor_work";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index bb5de770b6659379a68c077ff1cfc8d95d149c5c..a6c1d59085e0c58d9d1996d9e905bc24a3678e0c 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -983,12 +983,12 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
return;
}
// Paper end - Allow nerfed mobs to jump and float
+ int i = this.tickCount + this.getId(); //Luminol - Petal - Move up
ProfilerFiller gameprofilerfiller = this.level().getProfiler();
gameprofilerfiller.push("sensing");
- this.sensing.tick();
+ if (i % me.earthme.luminol.config.modules.optimizations.PetalReduceSensorWorkConfig.delayTicks == 0 || !me.earthme.luminol.config.modules.optimizations.PetalReduceSensorWorkConfig.enabled) this.sensing.tick(); // Luminol - Petal - Reduce sensor work
gameprofilerfiller.pop();
- int i = this.tickCount + this.getId();
if (i % 2 != 0 && this.tickCount > 1) {
gameprofilerfiller.push("targetSelector");

View File

@@ -1,153 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 16:10:26 +0800
Subject: [PATCH] Pufferfish Reduce entity fluid lookups if no fluids
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 3c9ec0f5fef49b0abc42382551de11ab942b3b20..967c7a953084dc68a0ecd4b1a0f13ead7e72cb3d 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -5132,16 +5132,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tag, double speed) {
- if (this.touchingUnloadedChunk()) {
+ if (false && this.touchingUnloadedChunk()) { // Pufferfish - cost of a lookup here is the same cost as below, so skip
return false;
} else {
AABB axisalignedbb = this.getBoundingBox().deflate(0.001D);
- int i = Mth.floor(axisalignedbb.minX);
- int j = Mth.ceil(axisalignedbb.maxX);
- int k = Mth.floor(axisalignedbb.minY);
- int l = Mth.ceil(axisalignedbb.maxY);
- int i1 = Mth.floor(axisalignedbb.minZ);
- int j1 = Mth.ceil(axisalignedbb.maxZ);
+ // Pufferfish start - rename
+ int minBlockX = Mth.floor(axisalignedbb.minX);
+ int maxBlockX = Mth.ceil(axisalignedbb.maxX);
+ int minBlockY = Mth.floor(axisalignedbb.minY);
+ int maxBlockY = Mth.ceil(axisalignedbb.maxY);
+ int minBlockZ = Mth.floor(axisalignedbb.minZ);
+ int maxBlockZ = Mth.ceil(axisalignedbb.maxZ);
+ // Pufferfish end
double d1 = 0.0D;
boolean flag = this.isPushedByFluid();
boolean flag1 = false;
@@ -5149,14 +5151,61 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
int k1 = 0;
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
- for (int l1 = i; l1 < j; ++l1) {
- for (int i2 = k; i2 < l; ++i2) {
- for (int j2 = i1; j2 < j1; ++j2) {
- blockposition_mutableblockposition.set(l1, i2, j2);
- FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition);
+ // Pufferfish start - based off CollisionUtil.getCollisionsForBlocksOrWorldBorder
+ final int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this.level());
+ final int maxSection = io.papermc.paper.util.WorldUtil.getMaxSection(this.level());
+ final int minBlock = minSection << 4;
+ final int maxBlock = (maxSection << 4) | 15;
+
+ // special cases:
+ if (minBlockY > maxBlock || maxBlockY < minBlock) {
+ // no point in checking
+ return false;
+ }
+
+ int minYIterate = Math.max(minBlock, minBlockY);
+ int maxYIterate = Math.min(maxBlock, maxBlockY);
+
+ int minChunkX = minBlockX >> 4;
+ int maxChunkX = maxBlockX >> 4;
+
+ int minChunkZ = minBlockZ >> 4;
+ int maxChunkZ = maxBlockZ >> 4;
+
+ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) {
+ int minZ = currChunkZ == minChunkZ ? minBlockZ & 15 : 0; // coordinate in chunk
+ int maxZ = currChunkZ == maxChunkZ ? maxBlockZ & 15 : 16; // coordinate in chunk
+
+ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) {
+ int minX = currChunkX == minChunkX ? minBlockX & 15 : 0; // coordinate in chunk
+ int maxX = currChunkX == maxChunkX ? maxBlockX & 15 : 16; // coordinate in chunk
+
+ net.minecraft.world.level.chunk.ChunkAccess chunk = this.level().getChunkIfLoadedImmediately(currChunkX, currChunkZ);
+ if (chunk == null) {
+ return false; // if we're touching an unloaded chunk then it's false
+ }
+
+ net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections();
+
+ for (int currY = minYIterate; currY < maxYIterate; ++currY) {
+ net.minecraft.world.level.chunk.LevelChunkSection section = sections[(currY >> 4) - minSection];
+
+ if (section == null || section.hasOnlyAir() || section.fluidStateCount == 0) { // if no fluids, nothing in this section
+ // empty
+ // skip to next section
+ currY = (currY & ~(15)) + 15; // increment by 15: iterator loop increments by the extra one
+ continue;
+ }
+
+ net.minecraft.world.level.chunk.PalettedContainer<BlockState> blocks = section.states;
+
+ for (int currZ = minZ; currZ < maxZ; ++currZ) {
+ for (int currX = minX; currX < maxX; ++currX) {
+ FluidState fluid = blocks.get(currX & 15, currY & 15, currZ & 15).getFluidState();
if (fluid.is(tag)) {
- double d2 = (double) ((float) i2 + fluid.getHeight(this.level(), blockposition_mutableblockposition));
+ blockposition_mutableblockposition.set((currChunkX << 4) + currX, currY, (currChunkZ << 4) + currZ);
+ double d2 = (double) ((float) currY + fluid.getHeight(this.level(), blockposition_mutableblockposition));
if (d2 >= axisalignedbb.minY) {
flag1 = true;
@@ -5178,9 +5227,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
// CraftBukkit end
}
}
+ }
+ }
}
}
}
+ // Pufferfish end
if (vec3d.length() > 0.0D) {
if (k1 > 0) {
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
index f0de72afad4bb571153436399386a6a8a70582a6..45b7527341fcb6d24f35318cedb522646b5ee1c2 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
@@ -25,6 +25,7 @@ public class LevelChunkSection {
public final PalettedContainer<BlockState> states;
// CraftBukkit start - read/write
private PalettedContainer<Holder<Biome>> biomes;
+ public short fluidStateCount; // Pufferfish
public final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper
// Paper start - optimise collisions
private int specialCollidingBlocks;
@@ -102,6 +103,7 @@ public class LevelChunkSection {
if (!fluid.isEmpty()) {
--this.tickingFluidCount;
+ --this.fluidStateCount; // Pufferfish
}
if (!state.isAir()) {
@@ -116,6 +118,7 @@ public class LevelChunkSection {
if (!fluid1.isEmpty()) {
++this.tickingFluidCount;
+ ++this.fluidStateCount; // Pufferfish
}
this.updateBlockCallback(x, y, z, iblockdata1, state); // Paper - optimise collisions
@@ -161,6 +164,7 @@ public class LevelChunkSection {
if (fluid.isRandomlyTicking()) {
this.tickingFluidCount = (short) (this.tickingFluidCount + 1);
}
+ this.fluidStateCount++; // Pufferfish
}
// Paper start - optimise collisions

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Pufferfish Optimize entity coordinate key
diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
index 8f91b7f44baaf62b829a81afc0633311e6c13f19..a149d98be7b4744f18d4ed4940881e13a76e4a7c 100644
index bb915f30997059f22c9002b1ddc1c3aecbf4e979..2034c67f5702b7b8d093ef2dd7601901c5fef363 100644
--- a/src/main/java/io/papermc/paper/util/MCUtil.java
+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
@@ -213,7 +213,7 @@ public final class MCUtil {
@@ -215,7 +215,7 @@ public final class MCUtil {
}
public static long getCoordinateKey(final Entity entity) {

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 16:00:17 +0800
From: MrHua269 <novau233@163.com>
Date: Sun, 14 Jan 2024 00:40:35 +0000
Subject: [PATCH] Pufferfish Cache climbing check for activation
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index cb32a3851a315f1f1b4fb6d26fdffbcb471bfc06..3c9ec0f5fef49b0abc42382551de11ab942b3b20 100644
index a424a9c9921eabca90bd7a49946e5814d4aea8dd..76911946c4ad5c87abc4a82c20d52a2e755801ef 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -308,7 +308,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -311,7 +311,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
public double yo;
public double zo;
private Vec3 position;
@@ -18,18 +18,10 @@ index cb32a3851a315f1f1b4fb6d26fdffbcb471bfc06..3c9ec0f5fef49b0abc42382551de11ab
private Vec3 deltaMovement;
private float yRot;
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 82996d0c2891871bd6ef9ff81aef123add08ebda..51dee7adc0dc534fac66bf3e8709865157dd763b 100644
index ed628d38136534b3391c0a06b9c892a922710235..b3f0de04a7448a31a87d50f630dd4d929a6b6f37 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -142,7 +142,6 @@ import org.bukkit.event.entity.EntityTeleportEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
// CraftBukkit end
-import co.aikar.timings.MinecraftTimings; // Paper
public abstract class LivingEntity extends Entity implements Attackable {
@@ -2006,6 +2005,20 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -2053,6 +2053,20 @@ public abstract class LivingEntity extends Entity implements Attackable {
return this.lastClimbablePos;
}
@@ -51,15 +43,15 @@ index 82996d0c2891871bd6ef9ff81aef123add08ebda..51dee7adc0dc534fac66bf3e87098651
if (this.isSpectator()) {
return false;
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
index d88988200016c1a3cc76c017dfb7deabf6fc17af..22daed525b023998a05884db603e2c7385ce0873 100644
index 4fc4690d03fd5f39e019f16845954052210c7361..c77beef9651aa2f7333d536e8ff4af3281834619 100644
--- a/src/main/java/org/spigotmc/ActivationRange.java
+++ b/src/main/java/org/spigotmc/ActivationRange.java
@@ -305,7 +305,7 @@ public class ActivationRange
@@ -307,7 +307,7 @@ public class ActivationRange
if ( entity instanceof LivingEntity )
{
LivingEntity living = (LivingEntity) entity;
- if ( living.onClimbable() || living.jumping || living.hurtTime > 0 || living.activeEffects.size() > 0 ) // Paper
+ if ( living.onClimableCached() || living.jumping || living.hurtTime > 0 || living.activeEffects.size() > 0 ) // Paper // Pufferfish - use cached
- if ( living.onClimbable() || living.jumping || living.hurtTime > 0 || living.activeEffects.size() > 0 || living.isFreezing()) // Paper
+ if ( living.onClimableCached() || living.jumping || living.hurtTime > 0 || living.activeEffects.size() > 0 || living.isFreezing()) // Paper // Pufferfish - use cached
{
return 1; // Paper
}

View File

@@ -1,87 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 16:30:24 +0800
Subject: [PATCH] Pufferfish Entity TTL
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index de0855656ad3882b182aa5674fd0117288268e71..d0c0b4daec59f23a989a8b8f66ea3c704b0e309c 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -4,13 +4,16 @@ import dev.kaiijumc.kaiiju.region.RegionFileFormat;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import me.earthme.luminol.commands.TpsBarCommand;
import me.earthme.luminol.functions.GlobalServerTpsBar;
+import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.entity.EntityType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import java.util.Arrays;
import java.util.List;
+import java.util.Locale;
import java.util.logging.Level;
import java.io.File;
import java.io.IOException;
@@ -65,6 +68,22 @@ public class LuminolConfig {
}
}
+ private static void initEntityTTL() {
+ // Set some defaults
+ get("optimizations.entity_timeouts.SNOWBALL", -1);
+ get("optimizations.entity_timeouts.LLAMA_SPIT", -1);
+ MAIN_CONFIG.setComment("optimizations.entity_timeouts",
+ """
+ These values define a entity's maximum lifespan. If an
+ entity is in this list and it has survived for longer than
+ that number of ticks, then it will be removed. Setting a value to
+ -1 disables this feature.""");
+ for (EntityType<?> entityType : BuiltInRegistries.ENTITY_TYPE) {
+ String type = EntityType.getKey(entityType).getPath().toUpperCase(Locale.ROOT);
+ entityType.ttl = get("optimizations.entity_timeouts." + type, -1);
+ }
+ }
+
public static void initValues(){
serverModName = get("misc.server_mod_name",serverModName,"The servermod name will be sent to players,and you can see it in F3 or motd responses");
fakeVanillaModeEnabled = get("misc.enable_fake_vanilla_mode",fakeVanillaModeEnabled,"Enable this to make the ping response of your server like a vanilla server");
@@ -106,6 +125,7 @@ public class LuminolConfig {
reduceSensorWork = get("optimizations.reduce_sensor_work",reduceSensorWork,"This optimization is from petal.You can find out more about it on petal's repository");
enableSuffocationOptimization = get("optimizations.optimize_suffocation_check",enableSuffocationOptimization);
+ initEntityTTL();
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 967c7a953084dc68a0ecd4b1a0f13ead7e72cb3d..8bdaab46c2e128aa58d13101170ce358146377a8 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -798,6 +798,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}
public void tick() {
+ // Pufferfish start - entity TTL
+ if (type != EntityType.PLAYER && type.ttl >= 0 && this.tickCount >= type.ttl) {
+ discard();
+ return;
+ }
+ // Pufferfish end - entity TTL
this.baseTick();
}
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
index 3f3494c20cd15a721090f1b36293562a6b834b14..4d60ac50a1d3860f2a2e9265aef9507d790220a3 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -309,6 +309,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
private ResourceLocation lootTable;
private final EntityDimensions dimensions;
private final FeatureFlagSet requiredFeatures;
+ public int ttl = -1; // Pufferfish
private static <T extends Entity> EntityType<T> register(String id, EntityType.Builder type) { // CraftBukkit - decompile error
return (EntityType) Registry.register(BuiltInRegistries.ENTITY_TYPE, id, (EntityType<T>) type.build(id)); // CraftBukkit - decompile error

View File

@@ -0,0 +1,99 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Mon, 29 Jul 2024 19:53:42 +0800
Subject: [PATCH] Pufferfish Make EntityCollisionContext a live representation
diff --git a/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java b/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java
index 88a4a72bb390947dc17e5da09a99b2d1b3ac4621..284c76ddb9724b44bb2e93f590685c728e843e6d 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java
@@ -17,50 +17,69 @@ public class EntityCollisionContext implements CollisionContext {
return defaultValue;
}
};
- private final boolean descending;
- private final double entityBottom;
- private final ItemStack heldItem;
- private final Predicate<FluidState> canStandOnFluid;
+ // Pufferfish start - remove these and pray no plugin uses them
+ // private final boolean descending;
+ // private final double entityBottom;
+ // private final ItemStack heldItem;
+ // private final Predicate<FluidState> canStandOnFluid;
+ // Pufferfish end
@Nullable
private final Entity entity;
protected EntityCollisionContext(boolean descending, double minY, ItemStack heldItem, Predicate<FluidState> walkOnFluidPredicate, @Nullable Entity entity) {
- this.descending = descending;
- this.entityBottom = minY;
- this.heldItem = heldItem;
- this.canStandOnFluid = walkOnFluidPredicate;
+ // Pufferfish start - remove these
+ // this.descending = descending;
+ // this.entityBottom = minY;
+ // this.heldItem = heldItem;
+ // this.canStandOnFluid = walkOnFluidPredicate;
+ // Pufferfish end
this.entity = entity;
}
@Deprecated
protected EntityCollisionContext(Entity entity) {
- this(
- entity.isDescending(),
- entity.getY(),
- entity instanceof LivingEntity ? ((LivingEntity)entity).getMainHandItem() : ItemStack.EMPTY,
- entity instanceof LivingEntity ? ((LivingEntity)entity)::canStandOnFluid : fluidState -> false,
- entity
- );
+ // Pufferfish start - remove this
+ // this(
+ // entity.isDescending(),
+ // entity.getY(),
+ // entity instanceof LivingEntity ? ((LivingEntity)entity).getMainHandItem() : ItemStack.EMPTY,
+ // entity instanceof LivingEntity ? ((LivingEntity)entity)::canStandOnFluid : fluidState -> false,
+ // entity
+ // );
+ // Pufferfish end
+ this.entity = entity;
}
@Override
public boolean isHoldingItem(Item item) {
- return this.heldItem.is(item);
+ // Pufferfish start
+ Entity entity = this.entity;
+ if (entity instanceof LivingEntity livingEntity) {
+ return livingEntity.getMainHandItem().is(item);
+ }
+ return ItemStack.EMPTY.is(item);
+ // Pufferfish end
}
@Override
public boolean canStandOnFluid(FluidState stateAbove, FluidState state) {
- return this.canStandOnFluid.test(state) && !stateAbove.getType().isSame(state.getType());
+ // Pufferfish start
+ Entity entity = this.entity;
+ if (entity instanceof LivingEntity livingEntity) {
+ return livingEntity.canStandOnFluid(state) && !stateAbove.getType().isSame(state.getType());
+ }
+ return false;
+ // Pufferfish end
}
@Override
public boolean isDescending() {
- return this.descending;
+ return this.entity != null && this.entity.isDescending(); // Pufferfish
}
@Override
public boolean isAbove(VoxelShape shape, BlockPos pos, boolean defaultValue) {
- return this.entityBottom > (double)pos.getY() + shape.max(Direction.Axis.Y) - 1.0E-5F;
+ return (this.entity == null ? -Double.MAX_VALUE : entity.getY()) > (double)pos.getY() + shape.max(Direction.Axis.Y) - 1.0E-5F; // Pufferfish
}
@Nullable

View File

@@ -1,78 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 16:35:37 +0800
Subject: [PATCH] Pufferfish Reduce projectile chunk loading
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index d0c0b4daec59f23a989a8b8f66ea3c704b0e309c..11c1a367fbc25cb63738a00ad93fb0b0b3500e7d 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -46,6 +46,8 @@ public class LuminolConfig {
public static boolean reduceSensorWork = true;
public static boolean enableSuffocationOptimization = true;
+ public static int maxProjectileLoadsPerTick;
+ public static int maxProjectileLoadsPerProjectile;
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -126,6 +128,8 @@ public class LuminolConfig {
reduceSensorWork = get("optimizations.reduce_sensor_work",reduceSensorWork,"This optimization is from petal.You can find out more about it on petal's repository");
enableSuffocationOptimization = get("optimizations.optimize_suffocation_check",enableSuffocationOptimization);
initEntityTTL();
+ maxProjectileLoadsPerTick = get("optimizations.projectile.max-loads-per-tick", maxProjectileLoadsPerTick, "Controls how many chunks are allowed \nto be sync loaded by projectiles in a tick.");
+ maxProjectileLoadsPerProjectile = get("optimizations.projectile.max-loads-per-projectile", maxProjectileLoadsPerProjectile, "Controls how many chunks a projectile \n can load in its lifetime before it gets \nautomatically removed.");
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
index 0c8f90a904c01105ba5fa6a8037150697bc2621e..527168199605c8c606c6dde563e4fe096b6f17ac 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
@@ -4,6 +4,8 @@ import com.google.common.base.MoreObjects;
import java.util.Iterator;
import java.util.UUID;
import javax.annotation.Nullable;
+
+import io.papermc.paper.threadedregions.TickRegionScheduler;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
@@ -44,6 +46,36 @@ public abstract class Projectile extends Entity implements TraceableEntity {
super(type, world);
}
+ // Pufferfish start
+ private static long loadedThisTick = 0;
+ private static long loadedTick;
+
+ private int loadedLifetime = 0;
+ @Override
+ public void setPos(double x, double y, double z) {
+ long currentTick = TickRegionScheduler.getCurrentRegion().getData().getCurrentTick();
+ if (loadedTick != currentTick) {
+ loadedTick = currentTick;
+ loadedThisTick = 0;
+ }
+ int previousX = Mth.floor(this.getX()) >> 4, previousZ = Mth.floor(this.getZ()) >> 4;
+ int newX = Mth.floor(x) >> 4, newZ = Mth.floor(z) >> 4;
+ if (previousX != newX || previousZ != newZ) {
+ boolean isLoaded = ((net.minecraft.server.level.ServerChunkCache) this.level().getChunkSource()).getChunkAtIfLoadedMainThread(newX, newZ) != null;
+ if (!isLoaded) {
+ if (Projectile.loadedThisTick > me.earthme.luminol.LuminolConfig.maxProjectileLoadsPerTick) {
+ if (++this.loadedLifetime > me.earthme.luminol.LuminolConfig.maxProjectileLoadsPerProjectile) {
+ this.discard();
+ }
+ return;
+ }
+ Projectile.loadedThisTick++;
+ }
+ }
+ super.setPos(x, y, z);
+ }
+ // Pufferfish end
+
public void setOwner(@Nullable Entity entity) {
if (entity != null) {
this.ownerUUID = entity.getUUID();

View File

@@ -147,7 +147,7 @@ index 0000000000000000000000000000000000000000..aa8467b9dda1f7707e41f50ac7b3e9d7
+ }
+}
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..c55f51e6db55f9fa66f53eef0e7a56af5f81d742 100644
index c2943d892b067b3f1fb3b93301a092e912d71f08..58296b67f80587af485b0068e461cfd3d8d6f96f 100644
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
@@ -45,6 +45,8 @@ public abstract class FlowingFluid extends Fluid {
@@ -174,7 +174,7 @@ index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..c55f51e6db55f9fa66f53eef0e7a56af
private final Map<FluidState, VoxelShape> shapes = Maps.newIdentityHashMap();
public FlowingFluid() {}
@@ -252,6 +262,8 @@ public abstract class FlowingFluid extends Fluid {
@@ -251,6 +261,8 @@ public abstract class FlowingFluid extends Fluid {
return false;
}
// Paper end - optimise collisions
@@ -183,7 +183,7 @@ index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..c55f51e6db55f9fa66f53eef0e7a56af
Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap;
if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) {
@@ -259,9 +271,16 @@ public abstract class FlowingFluid extends Fluid {
@@ -258,9 +270,16 @@ public abstract class FlowingFluid extends Fluid {
} else {
object2bytelinkedopenhashmap = null;
}
@@ -200,7 +200,7 @@ index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..c55f51e6db55f9fa66f53eef0e7a56af
if (object2bytelinkedopenhashmap != null) {
block_a = new Block.BlockStatePairKey(state, fromState, face);
byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(block_a);
@@ -272,11 +291,22 @@ public abstract class FlowingFluid extends Fluid {
@@ -271,11 +290,22 @@ public abstract class FlowingFluid extends Fluid {
} else {
block_a = null;
}
@@ -223,7 +223,7 @@ index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..c55f51e6db55f9fa66f53eef0e7a56af
if (object2bytelinkedopenhashmap != null) {
if (object2bytelinkedopenhashmap.size() == 200) {
object2bytelinkedopenhashmap.removeLastByte();
@@ -284,6 +314,11 @@ public abstract class FlowingFluid extends Fluid {
@@ -283,6 +313,11 @@ public abstract class FlowingFluid extends Fluid {
object2bytelinkedopenhashmap.putAndMoveToFirst(block_a, (byte) (flag ? 1 : 0));
}

View File

@@ -1,43 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 16:05:32 +0800
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 04:55:43 +0000
Subject: [PATCH] Pufferfish Optimize suffocation
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 0929a5a167691bde7dedaa1e2812b34ad69913d6..de0855656ad3882b182aa5674fd0117288268e71 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -42,6 +42,7 @@ public class LuminolConfig {
public static int linearFlushThreads = 1;
public static boolean reduceSensorWork = true;
+ public static boolean enableSuffocationOptimization = true;
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -104,6 +105,7 @@ public class LuminolConfig {
linearFlushThreads = Math.max(linearFlushThreads, 1);
reduceSensorWork = get("optimizations.reduce_sensor_work",reduceSensorWork,"This optimization is from petal.You can find out more about it on petal's repository");
+ enableSuffocationOptimization = get("optimizations.optimize_suffocation_check",enableSuffocationOptimization);
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/SuffocationOptimizationConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/SuffocationOptimizationConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e48cd297b4869e5c89b6abc43c726d3a7511e7f
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/SuffocationOptimizationConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class SuffocationOptimizationConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.OPTIMIZATIONS;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "suffocation_optimization";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 51dee7adc0dc534fac66bf3e8709865157dd763b..f13d26b280f095d006ffccb36af66bb7487cb8da 100644
index b3f0de04a7448a31a87d50f630dd4d929a6b6f37..216af15f706f777bd6350cdd2187a8e7c98dfa21 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -19,6 +19,8 @@ import java.util.Optional;
import java.util.UUID;
import java.util.function.Predicate;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.BlockUtil;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.commands.arguments.EntityAnchorArgument;
@@ -420,7 +422,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -442,7 +442,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
boolean flag = this instanceof net.minecraft.world.entity.player.Player;
if (!this.level().isClientSide) {
@@ -46,7 +43,7 @@ index 51dee7adc0dc534fac66bf3e8709865157dd763b..f13d26b280f095d006ffccb36af66bb7
this.hurt(this.damageSources().inWall(), 1.0F);
} else if (flag && !this.level().getWorldBorder().isWithinBounds(this.getBoundingBox())) {
double d0 = this.level().getWorldBorder().getDistanceToBorder(this) + this.level().getWorldBorder().getDamageSafeZone();
@@ -1410,6 +1412,19 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -1450,6 +1450,19 @@ public abstract class LivingEntity extends Entity implements Attackable {
return this.getHealth() <= 0.0F;
}
@@ -59,7 +56,7 @@ index 51dee7adc0dc534fac66bf3e8709865157dd763b..f13d26b280f095d006ffccb36af66bb7
+ }
+
+ public boolean shouldCheckForSuffocation() {
+ return !LuminolConfig.enableSuffocationOptimization || (tickCount % 10 == 0 && couldPossiblyBeHurt(1.0F));
+ return !me.earthme.luminol.config.modules.optimizations.SuffocationOptimizationConfig.enabled || (tickCount % 10 == 0 && couldPossiblyBeHurt(1.0F));
+ }
+ // Pufferfish end
+
@@ -67,10 +64,10 @@ index 51dee7adc0dc534fac66bf3e8709865157dd763b..f13d26b280f095d006ffccb36af66bb7
public boolean hurt(DamageSource source, float amount) {
if (this.isInvulnerableTo(source)) {
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
index 1e07febcf7a3dfb281728cc5e3e4f15dd776d7e0..c65ab566c6241dd6a44bd11a449ef0c4b2f6dc65 100644
index 7ddca52f7fe3f289b4b867e134326b1ead1a2aee..5040b1a7125dd9647a98fd812f558ec3a2171092 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -150,6 +150,13 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
@@ -154,6 +154,13 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
this.bossEvent.setName(this.getDisplayName());
}

View File

@@ -0,0 +1,178 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Mon, 29 Jul 2024 19:53:42 +0800
Subject: [PATCH] Pufferfish Use aging cache for biome temperatures
diff --git a/src/main/java/gg/airplane/structs/Long2FloatAgingCache.java b/src/main/java/gg/airplane/structs/Long2FloatAgingCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7f297ebb569f7c1f205e967ca485be70013a714
--- /dev/null
+++ b/src/main/java/gg/airplane/structs/Long2FloatAgingCache.java
@@ -0,0 +1,119 @@
+package gg.airplane.structs;
+
+import it.unimi.dsi.fastutil.HashCommon;
+
+/**
+ * A replacement for the cache used in Biome.
+ */
+public class Long2FloatAgingCache {
+
+ private static class AgingEntry {
+ private long data;
+ private float value;
+ private int uses = 0;
+ private int age = 0;
+
+ private AgingEntry(long data, float value) {
+ this.data = data;
+ this.value = value;
+ }
+
+ public void replace(long data, float flag) {
+ this.data = data;
+ this.value = flag;
+ }
+
+ public int getValue() {
+ return this.uses - (this.age >> 1); // age isn't as important as uses
+ }
+
+ public void incrementUses() {
+ this.uses = this.uses + 1 & Integer.MAX_VALUE;
+ }
+
+ public void incrementAge() {
+ this.age = this.age + 1 & Integer.MAX_VALUE;
+ }
+ }
+
+ private final AgingEntry[] entries;
+ private final int mask;
+ private final int maxDistance; // the most amount of entries to check for a value
+
+ public Long2FloatAgingCache(int size) {
+ int arraySize = HashCommon.nextPowerOfTwo(size);
+ this.entries = new AgingEntry[arraySize];
+ this.mask = arraySize - 1;
+ this.maxDistance = Math.min(arraySize, 4);
+ }
+
+ public float getValue(long data) {
+ AgingEntry curr;
+ int pos;
+
+ if ((curr = this.entries[pos = HashCommon.mix(HashCommon.long2int(data)) & this.mask]) == null) {
+ return Float.NaN;
+ } else if (data == curr.data) {
+ curr.incrementUses();
+ return curr.value;
+ }
+
+ int checked = 1; // start at 1 because we already checked the first spot above
+
+ while ((curr = this.entries[pos = (pos + 1) & this.mask]) != null) {
+ if (data == curr.data) {
+ curr.incrementUses();
+ return curr.value;
+ } else if (++checked >= this.maxDistance) {
+ break;
+ }
+ }
+
+ return Float.NaN;
+ }
+
+ public void putValue(long data, float value) {
+ AgingEntry curr;
+ int pos;
+
+ if ((curr = this.entries[pos = HashCommon.mix(HashCommon.long2int(data)) & this.mask]) == null) {
+ this.entries[pos] = new AgingEntry(data, value); // add
+ return;
+ } else if (data == curr.data) {
+ curr.incrementUses();
+ return;
+ }
+
+ int checked = 1; // start at 1 because we already checked the first spot above
+
+ while ((curr = this.entries[pos = (pos + 1) & this.mask]) != null) {
+ if (data == curr.data) {
+ curr.incrementUses();
+ return;
+ } else if (++checked >= this.maxDistance) {
+ this.forceAdd(data, value);
+ return;
+ }
+ }
+
+ this.entries[pos] = new AgingEntry(data, value); // add
+ }
+
+ private void forceAdd(long data, float value) {
+ int expectedPos = HashCommon.mix(HashCommon.long2int(data)) & this.mask;
+ AgingEntry entryToRemove = this.entries[expectedPos];
+
+ for (int i = expectedPos + 1; i < expectedPos + this.maxDistance; i++) {
+ int pos = i & this.mask;
+ AgingEntry entry = this.entries[pos];
+ if (entry.getValue() < entryToRemove.getValue()) {
+ entryToRemove = entry;
+ }
+
+ entry.incrementAge(); // use this as a mechanism to age the other entries
+ }
+
+ // remove the least used/oldest entry
+ entryToRemove.replace(data, value);
+ }
+}
diff --git a/src/main/java/net/minecraft/world/level/biome/Biome.java b/src/main/java/net/minecraft/world/level/biome/Biome.java
index 15f82c9a1ce1fef2e951d1b3c7a65e64b82061ea..f9fbfb63f19decb3b15284306d7edda072e609af 100644
--- a/src/main/java/net/minecraft/world/level/biome/Biome.java
+++ b/src/main/java/net/minecraft/world/level/biome/Biome.java
@@ -63,13 +63,18 @@ public final class Biome {
private final BiomeGenerationSettings generationSettings;
private final MobSpawnSettings mobSettings;
private final BiomeSpecialEffects specialEffects;
- private final ThreadLocal<Long2FloatLinkedOpenHashMap> temperatureCache = ThreadLocal.withInitial(() -> Util.make(() -> {
+ // Pufferfish start - use our cache
+ private final ThreadLocal<gg.airplane.structs.Long2FloatAgingCache> temperatureCache = ThreadLocal.withInitial(() -> Util.make(() -> {
+ /*
Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = new Long2FloatLinkedOpenHashMap(1024, 0.25F) {
protected void rehash(int i) {
}
};
long2FloatLinkedOpenHashMap.defaultReturnValue(Float.NaN);
return long2FloatLinkedOpenHashMap;
+ */
+ return new gg.airplane.structs.Long2FloatAgingCache(TEMPERATURE_CACHE_SIZE);
+ // Pufferfish end
}));
Biome(Biome.ClimateSettings weather, BiomeSpecialEffects effects, BiomeGenerationSettings generationSettings, MobSpawnSettings spawnSettings) {
@@ -112,17 +117,15 @@ public final class Biome {
@Deprecated
public float getTemperature(BlockPos blockPos) {
long l = blockPos.asLong();
- Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = this.temperatureCache.get();
- float f = long2FloatLinkedOpenHashMap.get(l);
+ // Pufferfish start
+ gg.airplane.structs.Long2FloatAgingCache cache = this.temperatureCache.get();
+ float f = cache.getValue(l);
if (!Float.isNaN(f)) {
return f;
} else {
float g = this.getHeightAdjustedTemperature(blockPos);
- if (long2FloatLinkedOpenHashMap.size() == 1024) {
- long2FloatLinkedOpenHashMap.removeFirstFloat();
- }
-
- long2FloatLinkedOpenHashMap.put(l, g);
+ cache.putValue(l, g);
+ // Pufferfish end
return g;
}
}

View File

@@ -1,19 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 16:07:30 +0800
From: MrHua269 <novau233@163.com>
Date: Tue, 6 Feb 2024 03:17:39 +0000
Subject: [PATCH] Pufferfish Early return optimization for target finding
diff --git a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java
index c157309ac78e7af084d3acb6e8b2bcd469a39d5e..ac5e5676b194a2a99e5cf53eb89c1152cac963b8 100644
index d2f0c3b26d4beedb49d86e0242d843590d469d02..c55fe31f3fc1c9ccb949c6bfb64e1bd6f37b8356 100644
--- a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java
+++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java
@@ -75,9 +75,18 @@ public class TargetingConditions {
@@ -76,9 +76,18 @@ public class TargetingConditions {
}
if (this.range > 0.0D) {
- double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D;
- double e = Math.max((this.useFollowRange ? this.getFollowRange(baseEntity) : this.range) * d, 2.0D); // Paper
if (this.range > 0.0) {
- double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0;
- double e = Math.max((this.useFollowRange ? this.getFollowRange(baseEntity) : this.range) * d, 2.0); // Paper - Fix MC-145656
+ // Pufferfish start - check range before getting visibility
+ // d = invisibility percent, e = follow range adjusted for invisibility, f = distance
double f = baseEntity.distanceToSqr(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ());
@@ -23,8 +23,8 @@ index c157309ac78e7af084d3acb6e8b2bcd469a39d5e..ac5e5676b194a2a99e5cf53eb89c1152
+ return false;
+ }
+
+ double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D;
+ double e = Math.max((followRangeRaw) * d, 2.0D); // Paper
+ double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0;
+ double e = Math.max((followRangeRaw) * d, 2.0D); // Paper - Fix MC-145656
+ // Pufferfish end
if (f > e * e) {
return false;

View File

@@ -1,90 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 17:30:32 +0800
Subject: [PATCH] Gale Reduce acquire POI for stuck entities
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index fcd532898e099a809969603941b90fdd415b03c3..d032786938db9725e1be72dae63a1387bcb69d79 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -12,14 +12,10 @@ import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import java.util.*;
-import java.util.logging.Level;
import java.io.File;
import java.io.IOException;
-import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.MinecraftServer;
-import org.bukkit.configuration.ConfigurationSection;
-import net.minecraft.world.entity.EntityType;
public class LuminolConfig {
private static final Logger logger = LogManager.getLogger();
@@ -58,6 +54,7 @@ public class LuminolConfig {
public static int activationDistanceMod;
public static double entityWakeUpDurationRatioStandardDeviation = 0.2;
public static boolean loadChunksToActiveClimbingEntities = false;
+ public static int acquirePoiForStuckEntityInterval = 60;
public static void init() throws IOException {
@@ -171,6 +168,7 @@ public class LuminolConfig {
initDAB();
entityWakeUpDurationRatioStandardDeviation = get("optimizations.entity_wakeup_duration_ratio_standard_deviation",entityWakeUpDurationRatioStandardDeviation);
loadChunksToActiveClimbingEntities = get("optimizations.load_chunks_to_active_climbing_entities",loadChunksToActiveClimbingEntities);
+ acquirePoiForStuckEntityInterval = get("optimizations.acquire_poi_for_stuck_entity_interval", acquirePoiForStuckEntityInterval);
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
index 8f8b29f80d1573981ccffd207dd6e0941e71a352..ba4cdaf499c7ffef0c7fbdd575bdba841bcb7282 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
@@ -7,12 +7,14 @@ import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
-import java.util.stream.Collectors;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.core.GlobalPos;
import net.minecraft.core.Holder;
import net.minecraft.network.protocol.game.DebugPackets;
+import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.PathfinderMob;
@@ -26,6 +28,13 @@ import org.apache.commons.lang3.mutable.MutableLong;
public class AcquirePoi {
public static final int SCAN_RANGE = 48;
+ // Gale start - Airplane - reduce acquire POI for stuck entities
+ public static void addAdditionalTimeToMutableLongIfEntityIsStuck(MutableLong mutableLong, ServerLevel world, PathfinderMob entity) {
+ long stuckEntityAdditionalWaitTime = LuminolConfig.acquirePoiForStuckEntityInterval;
+ mutableLong.add(stuckEntityAdditionalWaitTime <= 0L ? 0L : entity.getNavigation().isStuck() ? stuckEntityAdditionalWaitTime : 0L);
+ }
+ // Gale end - Airplane - reduce acquire POI for stuck entities
+
public static BehaviorControl<PathfinderMob> create(Predicate<Holder<PoiType>> poiPredicate, MemoryModuleType<GlobalPos> poiPosModule, boolean onlyRunIfChild, Optional<Byte> entityStatus) {
return create(poiPredicate, poiPosModule, poiPosModule, onlyRunIfChild, entityStatus);
}
@@ -42,12 +51,13 @@ public class AcquirePoi {
return false;
} else if (mutableLong.getValue() == 0L) {
mutableLong.setValue(world.getGameTime() + (long)world.random.nextInt(20));
+ addAdditionalTimeToMutableLongIfEntityIsStuck(mutableLong, world, entity); // Gale - Airplane - reduce acquire POI for stuck entities
return false;
} else if (world.getGameTime() < mutableLong.getValue()) {
return false;
} else {
mutableLong.setValue(time + 20L + (long)world.getRandom().nextInt(20));
- if (entity.getNavigation().isStuck()) mutableLong.add(200); // Paper - Wait an additional 10s to check again if they're stuck
+ addAdditionalTimeToMutableLongIfEntityIsStuck(mutableLong, world, entity); // Gale - Airplane - reduce acquire POI for stuck entities
PoiManager poiManager = world.getPoiManager();
long2ObjectMap.long2ObjectEntrySet().removeIf((entry) -> {
return !entry.getValue().isStillValid(time);

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Pufferfish Reduce chunk loading & lookups
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
index bd5996eef2d946e9d7765b6b315bc5951158810e..0d51f435f18f3f9d59a3241a0b7fa1c4af841b72 100644
index 260202fab3ac300552c557b44dcf251f083c6a78..9cf4e2f309e182c69e9592ac606c0ae85a1200b6 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
@@ -333,11 +333,17 @@ public class EnderMan extends Monster implements NeutralMob {
@@ -318,11 +318,17 @@ public class EnderMan extends Monster implements NeutralMob {
private boolean teleport(double x, double y, double z) {
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(x, y, z);

View File

@@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 17:30:32 +0800
Subject: [PATCH] Gale Skip secondary POI sensor if absent
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
index cb1d91f9fe98f21c2afbe3894dfd9bca3bdd3ba6..75dc06a3041bfdfb08c914eb50cfa282ae9eb2fe 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
@@ -22,6 +22,13 @@ public class SecondaryPoiSensor extends Sensor<Villager> {
@Override
protected void doTick(ServerLevel world, Villager entity) {
+ // Gale start - Lithium - skip secondary POI sensor if absent
+ var secondaryPoi = entity.getVillagerData().getProfession().secondaryPoi();
+ if (secondaryPoi.isEmpty()) {
+ entity.getBrain().eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE);
+ return;
+ }
+ // Gale end - Lithium - skip secondary POI sensor if absent
ResourceKey<Level> resourceKey = world.dimension();
BlockPos blockPos = entity.blockPosition();
List<GlobalPos> list = Lists.newArrayList();

View File

@@ -1,18 +1,18 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 16:09:27 +0800
From: MrHua269 <novau233@163.com>
Date: Tue, 6 Feb 2024 03:21:56 +0000
Subject: [PATCH] Pufferfish Fix Paper#6045, block goal shouldn't load chunks
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
index 34f319ad09276c6f68dde449c79351de0d7d86f5..a719af0b512d9ef243d0d54f3b744b1b1a5f2772 100644
index aee0147649d458b87d92496eda0c1723ebe570d2..89e9ea999d2fbd81a1d74382ef3fcd675fc8b94e 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
@@ -119,6 +119,7 @@ public abstract class MoveToBlockGoal extends Goal {
for(int m = 0; m <= l; m = m > 0 ? -m : 1 - m) {
for(int n = m < l && m > -l ? l : 0; n <= l; n = n > 0 ? -n : 1 - n) {
@@ -121,6 +121,7 @@ public abstract class MoveToBlockGoal extends Goal {
for (int m = 0; m <= l; m = m > 0 ? -m : 1 - m) {
for (int n = m < l && m > -l ? l : 0; n <= l; n = n > 0 ? -n : 1 - n) {
mutableBlockPos.setWithOffset(blockPos, m, k - 1, n);
+ if (!this.mob.level().hasChunkAt(mutableBlockPos)) continue; // Pufferfish - if this block isn't loaded, continue
if (this.mob.isWithinRestriction(mutableBlockPos) && this.isValidTarget(this.mob.level(), mutableBlockPos)) {
this.blockPos = mutableBlockPos;
setTargetPosition(mutableBlockPos.immutable()); // Paper
this.mob.movingTarget = mutableBlockPos == BlockPos.ZERO ? null : mutableBlockPos.immutable(); // Paper

View File

@@ -0,0 +1,218 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Sun, 16 Jun 2024 10:56:41 +0000
Subject: [PATCH] Pufferfish Reduce entity fluid lookups if no fluids
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/ReduceEntityFluidLookupConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/ReduceEntityFluidLookupConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..0523b3da3fb254bce1998bae6410c6323ccac2ef
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/ReduceEntityFluidLookupConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class ReduceEntityFluidLookupConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments = "See the optimization on Pufferfish")
+ public static boolean enabled = true;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.OPTIMIZATIONS;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "reduce_entity_fluid_lookups_if_no_fluids";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 76911946c4ad5c87abc4a82c20d52a2e755801ef..19d901c4560be4c44adc6513adca95c9ac4e0b95 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -5325,6 +5325,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
if (this.touchingUnloadedChunk()) {
return false;
} else {
+ //Luminol start - Configurable pufferfish optimization: Reduce entity fluid lookups if no fluids
+ if (me.earthme.luminol.config.modules.optimizations.ReduceEntityFluidLookupConfig.enabled){
+ return this.updateFluidHeightAndDoFluidPushingPufferfish$half(tag, speed);
+ }
+ //Luminol end
AABB axisalignedbb = this.getBoundingBox().deflate(0.001D);
int i = Mth.floor(axisalignedbb.minX);
int j = Mth.ceil(axisalignedbb.maxX);
@@ -5398,6 +5403,133 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
}
+ //Luminol start - Configurable pufferfish optimization: Reduce entity fluid lookups if no fluids
+ private boolean updateFluidHeightAndDoFluidPushingPufferfish$half(TagKey<Fluid> tag, double speed) {
+ AABB axisalignedbb = this.getBoundingBox().deflate(0.001D);
+ // Pufferfish start - rename
+ int minBlockX = Mth.floor(axisalignedbb.minX);
+ int maxBlockX = Mth.ceil(axisalignedbb.maxX);
+ int minBlockY = Mth.floor(axisalignedbb.minY);
+ int maxBlockY = Mth.ceil(axisalignedbb.maxY);
+ int minBlockZ = Mth.floor(axisalignedbb.minZ);
+ int maxBlockZ = Mth.ceil(axisalignedbb.maxZ);
+ // Pufferfish end
+ double d1 = 0.0D;
+ boolean flag = this.isPushedByFluid();
+ boolean flag1 = false;
+ Vec3 vec3d = Vec3.ZERO;
+ int k1 = 0;
+ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
+
+ // Pufferfish start - based off CollisionUtil.getCollisionsForBlocksOrWorldBorder
+ final int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this.level());
+ final int maxSection = io.papermc.paper.util.WorldUtil.getMaxSection(this.level());
+ final int minBlock = minSection << 4;
+ final int maxBlock = (maxSection << 4) | 15;
+
+ // special cases:
+ if (minBlockY > maxBlock || maxBlockY < minBlock) {
+ // no point in checking
+ return false;
+ }
+
+ int minYIterate = Math.max(minBlock, minBlockY);
+ int maxYIterate = Math.min(maxBlock, maxBlockY);
+
+ int minChunkX = minBlockX >> 4;
+ int maxChunkX = maxBlockX >> 4;
+
+ int minChunkZ = minBlockZ >> 4;
+ int maxChunkZ = maxBlockZ >> 4;
+
+ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) {
+ int minZ = currChunkZ == minChunkZ ? minBlockZ & 15 : 0; // coordinate in chunk
+ int maxZ = currChunkZ == maxChunkZ ? maxBlockZ & 15 : 16; // coordinate in chunk
+
+ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) {
+ int minX = currChunkX == minChunkX ? minBlockX & 15 : 0; // coordinate in chunk
+ int maxX = currChunkX == maxChunkX ? maxBlockX & 15 : 16; // coordinate in chunk
+
+ net.minecraft.world.level.chunk.ChunkAccess chunk = this.level().getChunkIfLoadedImmediately(currChunkX, currChunkZ);
+ if (chunk == null) {
+ return false; // if we're touching an unloaded chunk then it's false
+ }
+
+ net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections();
+
+ for (int currY = minYIterate; currY < maxYIterate; ++currY) {
+ net.minecraft.world.level.chunk.LevelChunkSection section = sections[(currY >> 4) - minSection];
+
+ if (section == null || section.hasOnlyAir() || section.fluidStateCount == 0) { // if no fluids, nothing in this section
+ // empty
+ // skip to next section
+ currY = (currY & ~(15)) + 15; // increment by 15: iterator loop increments by the extra one
+ continue;
+ }
+
+ net.minecraft.world.level.chunk.PalettedContainer<BlockState> blocks = section.states;
+
+ for (int currZ = minZ; currZ < maxZ; ++currZ) {
+ for (int currX = minX; currX < maxX; ++currX) {
+ FluidState fluid = blocks.get(currX & 15, currY & 15, currZ & 15).getFluidState();
+
+ if (fluid.is(tag)) {
+ blockposition_mutableblockposition.set((currChunkX << 4) + currX, currY, (currChunkZ << 4) + currZ);
+ double d2 = (double) ((float) currY + fluid.getHeight(this.level(), blockposition_mutableblockposition));
+
+ if (d2 >= axisalignedbb.minY) {
+ flag1 = true;
+ d1 = Math.max(d2 - axisalignedbb.minY, d1);
+ if (flag) {
+ Vec3 vec3d1 = fluid.getFlow(this.level(), blockposition_mutableblockposition);
+
+ if (d1 < 0.4D) {
+ vec3d1 = vec3d1.scale(d1);
+ }
+
+ vec3d = vec3d.add(vec3d1);
+ ++k1;
+ }
+ // CraftBukkit start - store last lava contact location
+ if (tag == FluidTags.LAVA) {
+ this.lastLavaContact = blockposition_mutableblockposition.immutable();
+ }
+ // CraftBukkit end
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // Pufferfish end
+
+ if (vec3d.length() > 0.0D) {
+ if (k1 > 0) {
+ vec3d = vec3d.scale(1.0D / (double) k1);
+ }
+
+ if (!(this instanceof Player)) {
+ vec3d = vec3d.normalize();
+ }
+
+ Vec3 vec3d2 = this.getDeltaMovement();
+
+ vec3d = vec3d.scale(speed * 1.0D);
+ double d3 = 0.003D;
+
+ if (Math.abs(vec3d2.x) < 0.003D && Math.abs(vec3d2.z) < 0.003D && vec3d.length() < 0.0045000000000000005D) {
+ vec3d = vec3d.normalize().scale(0.0045000000000000005D);
+ }
+
+ this.setDeltaMovement(this.getDeltaMovement().add(vec3d));
+ }
+
+ this.fluidHeight.put(tag, d1);
+ return flag1;
+ }
+ //Luminol end
+
public boolean touchingUnloadedChunk() {
AABB axisalignedbb = this.getBoundingBox().inflate(1.0D);
int i = Mth.floor(axisalignedbb.minX);
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
index a2a5aef769ee8bb638a5a9f3da9812fa4a85dda5..7288261b8924d08e93abecb664e2273c624a325b 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
@@ -25,6 +25,7 @@ public class LevelChunkSection {
public final PalettedContainer<BlockState> states;
// CraftBukkit start - read/write
private PalettedContainer<Holder<Biome>> biomes;
+ public short fluidStateCount; // Pufferfish
public final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper
// Paper start - optimise collisions
private int specialCollidingBlocks;
@@ -102,6 +103,7 @@ public class LevelChunkSection {
if (!fluid.isEmpty()) {
--this.tickingFluidCount;
+ --this.fluidStateCount; // Pufferfish
}
if (!state.isAir()) {
@@ -116,6 +118,7 @@ public class LevelChunkSection {
if (!fluid1.isEmpty()) {
++this.tickingFluidCount;
+ ++this.fluidStateCount; // Pufferfish
}
this.updateBlockCallback(x, y, z, iblockdata1, state); // Paper - optimise collisions
@@ -162,6 +165,7 @@ public class LevelChunkSection {
if (fluid.isRandomlyTicking()) {
this.tickingFluidCount = (short) (this.tickingFluidCount + 1);
}
+ this.fluidStateCount++; // Pufferfish
}
// Paper start - optimise collisions

View File

@@ -5,21 +5,10 @@ Subject: [PATCH] Pufferfish Only check for spooky season once an hour
diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
index 5beaa849a250ea005733250ad3edfa8382224667..2028ae6cc50d86c579ec062536e8c6339196ce09 100644
index dc27ddf5131e7398a5390a5187261d4c7fb6ccaa..39cc49b746b0a775fde5d173dd4f712ab4a84a97 100644
--- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java
+++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
@@ -3,6 +3,10 @@ package net.minecraft.world.entity.ambient;
import java.time.LocalDate;
import java.time.temporal.ChronoField;
import javax.annotation.Nullable;
+
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
+import io.papermc.paper.threadedregions.TickRegionScheduler;
+import io.papermc.paper.threadedregions.TickRegions;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
@@ -237,13 +241,25 @@ public class Bat extends AmbientCreature {
@@ -239,13 +239,25 @@ public class Bat extends AmbientCreature {
}
}
@@ -28,8 +17,8 @@ index 5beaa849a250ea005733250ad3edfa8382224667..2028ae6cc50d86c579ec062536e8c633
+ private static final int ONE_HOUR = 20 * 60 * 60;
+ private static int lastSpookyCheck = -ONE_HOUR;
private static boolean isHalloween() {
+ final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> region =
+ TickRegionScheduler.getCurrentRegion();
+ final io.papermc.paper.threadedregions.ThreadedRegionizer.ThreadedRegion<io.papermc.paper.threadedregions.TickRegions.TickRegionData, io.papermc.paper.threadedregions.TickRegions.TickRegionSectionData> region =
+ io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegion();
+ final long tickCount = region.getData().getCurrentTick();
+ if (tickCount - lastSpookyCheck > ONE_HOUR) {
LocalDate localdate = LocalDate.now();
@@ -44,5 +33,5 @@ index 5beaa849a250ea005733250ad3edfa8382224667..2028ae6cc50d86c579ec062536e8c633
}
+ // Pufferfish end
@Override
protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) {
private void setupAnimationStates() {
if (this.isResting()) {

View File

@@ -1,99 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 21:23:06 +0800
Subject: [PATCH] Try fixing folia spector teleportation
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index d032786938db9725e1be72dae63a1387bcb69d79..dcc52141b34b87a67c3d6070b68b58af4a7c4f26 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -31,6 +31,7 @@ public class LuminolConfig {
public static String[] tpsColors = new String[]{"GREEN","YELLOW","RED","PURPLE"};
public static String[] pingColors = new String[]{"GREEN","YELLOW","RED","PURPLE"};
public static boolean disableUsernameCheck = false;
+ public static boolean fixSpectorTeleportFolia = false;
public static boolean safeTeleportation = true;
public static boolean enableSandDuping = false;
@@ -130,6 +131,7 @@ public class LuminolConfig {
tpsColors = get("misc.tpsbar_range_colors", List.of(tpsColors),"The bar and text color of each tps ranges.The last is the color of initial bar's color").toArray(String[]::new);
pingColors = get("misc.tpsbar_ping_range_colors",List.of(pingColors),"As same as the tpsColors").toArray(String[]::new);
disableUsernameCheck = get("misc.disable_username_check",disableUsernameCheck,"Disable username check that can accept usernames with other characters(such as Chinese).Not recommended to use");
+ fixSpectorTeleportFolia = get("misc.fix_folia_spector_teleport",fixSpectorTeleportFolia);
if (tpsbarEnabled){
initTpsbar();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index d7a280427442bac8cc8ccb542d24d4e0901df70a..755294e3f5b3fbcfbdc0cc85627b2487663ce591 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -18,6 +18,9 @@ import java.util.Optional;
import java.util.OptionalInt;
import java.util.Set;
import javax.annotation.Nullable;
+
+import io.papermc.paper.util.TickThread;
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.BlockUtil;
import net.minecraft.ChatFormatting;
import net.minecraft.CrashReport;
@@ -836,18 +839,7 @@ public class ServerPlayer extends Player {
Entity entity = this.getCamera();
- if (entity != this) {
- if (entity.isAlive()) {
- this.absMoveTo(entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot());
- this.serverLevel().getChunkSource().move(this);
- if (this.wantsToStopRiding()) {
- this.setCamera(this);
- }
- } else {
- this.setCamera(this);
- }
- }
-
+ //Luminol - move up
CriteriaTriggers.TICK.trigger(this);
if (this.levitationStartPos != null) {
CriteriaTriggers.LEVITATION.trigger(this, this.levitationStartPos, this.tickCount - this.levitationStartTime);
@@ -856,6 +848,38 @@ public class ServerPlayer extends Player {
this.trackStartFallingPosition();
this.trackEnteredOrExitedLavaOnVehicle();
this.advancements.flushDirty(this);
+
+ if (entity != this) {
+ if (entity.isAlive()) {
+ //Luminol start - Fix spector camera
+ if (TickThread.isTickThreadFor(entity) || !LuminolConfig.fixSpectorTeleportFolia){
+ this.absMoveTo(entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot());
+ this.serverLevel().getChunkSource().move(this);
+ if (this.wantsToStopRiding()) {
+ this.setCamera(this);
+ }
+ }else{
+ this.teleportAsync(
+ ((ServerLevel) entity.level()),
+ entity.position,
+ entity.getYRot(),
+ entity.getXRot(),
+ null,
+ TeleportCause.SPECTATE,
+ Entity.TELEPORT_FLAG_LOAD_CHUNK | Entity.TELEPORT_FLAG_TELEPORT_PASSENGERS,
+ r -> {
+ this.serverLevel().getChunkSource().move(this);
+ if (this.wantsToStopRiding()) {
+ this.setCamera(this);
+ }
+ }
+ );
+ }
+ //Luminol end
+ } else {
+ this.setCamera(this);
+ }
+ }
}
public void doTick() {

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Wed, 29 Nov 2023 21:15:32 +0800
Subject: [PATCH] Add config for offline mode warning
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index dcc52141b34b87a67c3d6070b68b58af4a7c4f26..8bf7a0235ed292d6cb3beca9b786a69148e0b4d9 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -31,6 +31,7 @@ public class LuminolConfig {
public static String[] tpsColors = new String[]{"GREEN","YELLOW","RED","PURPLE"};
public static String[] pingColors = new String[]{"GREEN","YELLOW","RED","PURPLE"};
public static boolean disableUsernameCheck = false;
+ public static boolean disableOfflineModeWarning = false;
public static boolean fixSpectorTeleportFolia = false;
public static boolean safeTeleportation = true;
@@ -132,6 +133,7 @@ public class LuminolConfig {
pingColors = get("misc.tpsbar_ping_range_colors",List.of(pingColors),"As same as the tpsColors").toArray(String[]::new);
disableUsernameCheck = get("misc.disable_username_check",disableUsernameCheck,"Disable username check that can accept usernames with other characters(such as Chinese).Not recommended to use");
fixSpectorTeleportFolia = get("misc.fix_folia_spector_teleport",fixSpectorTeleportFolia);
+ disableOfflineModeWarning = get("misc.disable_offline_mode_warning",disableOfflineModeWarning);
if (tpsbarEnabled){
initTpsbar();
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 4a1e068c27853a38db0641806626e7ac740bd8de..4cc62104942e58ededd5c838f4bd5c4db0d574d4 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -278,7 +278,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord";
String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/";
// Paper end
- if (!this.usesAuthentication()) {
+ if (!this.usesAuthentication() && !LuminolConfig.disableOfflineModeWarning) { //Luminol - Add config for offline mod warning
DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware.");
// Spigot start

View File

@@ -0,0 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Mon, 29 Jul 2024 20:12:08 +0800
Subject: [PATCH] Pufferfish Skip cloning loot parameters
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java b/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java
index 37a0002bbe6539648db5219bb373e0404ae48dc0..ca0571d232e102c4b177a1ea44b96f5f0f440211 100644
--- a/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java
+++ b/src/main/java/net/minecraft/world/level/storage/loot/LootParams.java
@@ -21,8 +21,10 @@ public class LootParams {
public LootParams(ServerLevel world, Map<LootContextParam<?>, Object> parameters, Map<ResourceLocation, LootParams.DynamicDrop> dynamicDrops, float luck) {
this.level = world;
- this.params = parameters;
- this.dynamicDrops = dynamicDrops;
+ // Pufferfish start - use unmodifiable maps instead of immutable ones to skip the copy
+ this.params = java.util.Collections.unmodifiableMap(parameters);
+ this.dynamicDrops = java.util.Collections.unmodifiableMap(dynamicDrops);
+ // Pufferfish end
this.luck = luck;
}

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Thu, 30 Nov 2023 22:41:04 +0800
Subject: [PATCH] Add config for root user warning
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 8bf7a0235ed292d6cb3beca9b786a69148e0b4d9..7ada58f2fa83a47908723bdf1e5c5fbbc2f5ffa9 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -33,6 +33,7 @@ public class LuminolConfig {
public static boolean disableUsernameCheck = false;
public static boolean disableOfflineModeWarning = false;
public static boolean fixSpectorTeleportFolia = false;
+ public static boolean disableRootUserWarning = false;
public static boolean safeTeleportation = true;
public static boolean enableSandDuping = false;
@@ -134,6 +135,7 @@ public class LuminolConfig {
disableUsernameCheck = get("misc.disable_username_check",disableUsernameCheck,"Disable username check that can accept usernames with other characters(such as Chinese).Not recommended to use");
fixSpectorTeleportFolia = get("misc.fix_folia_spector_teleport",fixSpectorTeleportFolia);
disableOfflineModeWarning = get("misc.disable_offline_mode_warning",disableOfflineModeWarning);
+ disableRootUserWarning = get("misc.disable_root_user_warning",disableRootUserWarning);
if (tpsbarEnabled){
initTpsbar();
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 4cc62104942e58ededd5c838f4bd5c4db0d574d4..964777e992974dc02ee106ec47efd2e04f3b76c3 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -178,7 +178,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
}
// Paper start - detect running as root
- if (io.papermc.paper.util.ServerEnvironment.userIsRootOrAdmin()) {
+ if (io.papermc.paper.util.ServerEnvironment.userIsRootOrAdmin() && !LuminolConfig.disableRootUserWarning) { //Luminol - Add config for root user warning
DedicatedServer.LOGGER.warn("****************************");
DedicatedServer.LOGGER.warn("YOU ARE RUNNING THIS SERVER AS AN ADMINISTRATIVE OR ROOT USER. THIS IS NOT ADVISED.");
DedicatedServer.LOGGER.warn("YOU ARE OPENING YOURSELF UP TO POTENTIAL RISKS WHEN DOING THIS.");

View File

@@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 05:19:37 +0000
Subject: [PATCH] Pufferfish Entity TTL
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/EntityTTLOptimizationConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/EntityTTLOptimizationConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..15697d69659b6e1e776acf5094684b5f0c079b57
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/EntityTTLOptimizationConfig.java
@@ -0,0 +1,38 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.world.entity.EntityType;
+
+import java.util.Locale;
+
+public class EntityTTLOptimizationConfig implements IConfigModule {
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.OPTIMIZATIONS;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "entity_time_outs";
+ }
+
+ @Override
+ public void onLoaded(CommentedFileConfig config) {
+ // Set some defaults
+ this.get("optimizations.entity_timeouts.SNOWBALL", -1,config);
+ this.get("optimizations.entity_timeouts.LLAMA_SPIT", -1,config);
+ config.setComment("optimizations.entity_timeouts",
+ """
+ These values define a entity's maximum lifespan. If an
+ entity is in this list and it has survived for longer than
+ that number of ticks, then it will be removed. Setting a value to
+ -1 disables this feature.""");
+ for (EntityType<?> entityType : BuiltInRegistries.ENTITY_TYPE) {
+ String type = EntityType.getKey(entityType).getPath().toUpperCase(Locale.ROOT);
+ entityType.ttl = this.get("optimizations.entity_timeouts." + type, -1,config);
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 19d901c4560be4c44adc6513adca95c9ac4e0b95..053e9204104a886f4b7e828b7c5e0d277c44d676 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -855,6 +855,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public void tick() {
+ // Pufferfish start - entity TTL
+ if (type != EntityType.PLAYER && type.ttl >= 0 && this.tickCount >= type.ttl) {
+ discard();
+ return;
+ }
+ // Pufferfish end - entity TTL
this.baseTick();
}
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
index a2f0fb8b4057bd3a84d18298e49c4d02955240d3..aa2bb97ef305ed234a11b05e665ac1062b571591 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -325,6 +325,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
private final EntityDimensions dimensions;
private final float spawnDimensionsScale;
private final FeatureFlagSet requiredFeatures;
+ public int ttl = -1; // Pufferfish
private static <T extends Entity> EntityType<T> register(String id, EntityType.Builder type) { // CraftBukkit - decompile error
return (EntityType) Registry.register(BuiltInRegistries.ENTITY_TYPE, id, (EntityType<T>) type.build(id)); // CraftBukkit - decompile error

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 05:45:24 +0000
Subject: [PATCH] Pufferfish Reduce projectile chunk loading
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/ProjectileChunkReduceConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/ProjectileChunkReduceConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..12683ec5a5102e45b6171fea0b833ba57e5e188c
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/ProjectileChunkReduceConfig.java
@@ -0,0 +1,22 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class ProjectileChunkReduceConfig implements IConfigModule {
+ @ConfigInfo(baseName = "max-loads-per-tick")
+ public static int maxProjectileLoadsPerTick;
+ @ConfigInfo(baseName = "max-loads-per-projectile")
+ public static int maxProjectileLoadsPerProjectile;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.OPTIMIZATIONS;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "projectile";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
index a8d2f7a9d0bcb6db0b38ac30b098d59951053b47..829b63c8a7574d6aefe95b7d190dccc4c6ecf1ba 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
@@ -46,6 +46,38 @@ public abstract class Projectile extends Entity implements TraceableEntity {
super(type, world);
}
+ // Pufferfish start
+ private static long loadedThisTick = 0;
+ private static long loadedTick;
+
+ private int loadedLifetime = 0;
+ @Override
+ public void setPos(double x, double y, double z) {
+ if (io.papermc.paper.util.TickThread.isTickThreadFor(this) && io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegion() != null){
+ long currentTick = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegion().getData().getCurrentTick();
+ if (loadedTick != currentTick) {
+ loadedTick = currentTick;
+ loadedThisTick = 0;
+ }
+ int previousX = Mth.floor(this.getX()) >> 4, previousZ = Mth.floor(this.getZ()) >> 4;
+ int newX = Mth.floor(x) >> 4, newZ = Mth.floor(z) >> 4;
+ if ((previousX != newX || previousZ != newZ) && io.papermc.paper.util.TickThread.isTickThreadFor(((ServerLevel) this.level()), newX, newZ)) {
+ boolean isLoaded = ((net.minecraft.server.level.ServerChunkCache) this.level().getChunkSource()).getChunkAtIfLoadedMainThread(newX, newZ) != null;
+ if (!isLoaded) {
+ if (Projectile.loadedThisTick > me.earthme.luminol.config.modules.optimizations.ProjectileChunkReduceConfig.maxProjectileLoadsPerTick) {
+ if (++this.loadedLifetime > me.earthme.luminol.config.modules.optimizations.ProjectileChunkReduceConfig.maxProjectileLoadsPerProjectile) {
+ this.discard();
+ }
+ return;
+ }
+ Projectile.loadedThisTick++;
+ }
+ }
+ }
+ super.setPos(x, y, z);
+ }
+ // Pufferfish end
+
public void setOwner(@Nullable Entity entity) {
if (entity != null) {
this.ownerUUID = entity.getUUID();

View File

@@ -1,483 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sat, 9 Dec 2023 22:19:49 +0800
Subject: [PATCH] Optimize mob spawning(Async mob spawn state calc)
diff --git a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
index 41b9405d6759d865e0d14dd4f95163e9690e967d..091b1ae822e1c0517e59572e7a9bda11e998c0ee 100644
--- a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
+++ b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
@@ -26,7 +26,7 @@ public abstract class AreaMap<E> {
// we use linked for better iteration.
// map of: coordinate to set of objects in coordinate
- protected final Long2ObjectOpenHashMap<PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<E>> areaMap = new Long2ObjectOpenHashMap<>(1024, 0.7f);
+ protected Long2ObjectOpenHashMap<PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<E>> areaMap = new Long2ObjectOpenHashMap<>(1024, 0.7f); // Pufferfish - not actually final
protected final PooledLinkedHashSets<E> pooledHashSets;
protected final ChangeCallback<E> addCallback;
@@ -160,7 +160,8 @@ public abstract class AreaMap<E> {
protected abstract PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<E> getEmptySetFor(final E object);
// expensive op, only for debug
- protected void validate(final E object, final int viewDistance) {
+ protected void validate0(final E object, final int viewDistance) { // Pufferfish - rename this thing just in case it gets used I'd rather a compile time error.
+ if (true) throw new UnsupportedOperationException(); // Pufferfish - not going to put in the effort to fix this if it doesn't ever get used.
int entiesGot = 0;
int expectedEntries = (2 * viewDistance + 1);
expectedEntries *= expectedEntries;
diff --git a/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java
index 46954db7ecd35ac4018fdf476df7c8020d7ce6c8..1ad890a244bdf6df48a8db68cb43450e08c788a6 100644
--- a/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java
+++ b/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java
@@ -5,7 +5,7 @@ import net.minecraft.server.level.ServerPlayer;
/**
* @author Spottedleaf
*/
-public final class PlayerAreaMap extends AreaMap<ServerPlayer> {
+public class PlayerAreaMap extends AreaMap<ServerPlayer> { // Pufferfish - not actually final
public PlayerAreaMap() {
super();
diff --git a/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java b/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..fdcb62d12164024a5f354d60cc863821a18d1b2a
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java
@@ -0,0 +1,31 @@
+package gg.pufferfish.pufferfish.util;
+
+import com.destroystokyo.paper.util.misc.PlayerAreaMap;
+import com.destroystokyo.paper.util.misc.PooledLinkedHashSets;
+import java.util.concurrent.ConcurrentHashMap;
+import net.minecraft.server.level.ServerPlayer;
+
+public final class AsyncPlayerAreaMap extends PlayerAreaMap {
+
+ public AsyncPlayerAreaMap() {
+ super();
+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f));
+ }
+
+ public AsyncPlayerAreaMap(final PooledLinkedHashSets<ServerPlayer> pooledHashSets) {
+ super(pooledHashSets);
+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f));
+ }
+
+ public AsyncPlayerAreaMap(final PooledLinkedHashSets<ServerPlayer> pooledHashSets, final ChangeCallback<ServerPlayer> addCallback,
+ final ChangeCallback<ServerPlayer> removeCallback) {
+ this(pooledHashSets, addCallback, removeCallback, null);
+ }
+
+ public AsyncPlayerAreaMap(final PooledLinkedHashSets<ServerPlayer> pooledHashSets, final ChangeCallback<ServerPlayer> addCallback,
+ final ChangeCallback<ServerPlayer> removeCallback, final ChangeSourceCallback<ServerPlayer> changeSourceCallback) {
+ super(pooledHashSets, addCallback, removeCallback, changeSourceCallback);
+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f));
+ }
+
+}
diff --git a/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java b/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..facd55463d44cb7e3d2ca6892982f5497b8dded1
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java
@@ -0,0 +1,40 @@
+package gg.pufferfish.pufferfish.util;
+
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
+import java.util.Map;
+import org.jetbrains.annotations.Nullable;
+
+public class Long2ObjectOpenHashMapWrapper<V> extends Long2ObjectOpenHashMap<V> {
+
+ private final Map<Long, V> backingMap;
+
+ public Long2ObjectOpenHashMapWrapper(Map<Long, V> map) {
+ backingMap = map;
+ }
+
+ @Override
+ public V put(Long key, V value) {
+ return backingMap.put(key, value);
+ }
+
+ @Override
+ public V get(Object key) {
+ return backingMap.get(key);
+ }
+
+ @Override
+ public V remove(Object key) {
+ return backingMap.remove(key);
+ }
+
+ @Nullable
+ @Override
+ public V putIfAbsent(Long key, V value) {
+ return backingMap.putIfAbsent(key, value);
+ }
+
+ @Override
+ public int size() {
+ return backingMap.size();
+ }
+}
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
index 7ca275826609bcf96f103a8c50beaa47c3b4068b..dc5399bd5dba9dd33a7cfd644327c2568a6ad051 100644
--- a/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
@@ -4,6 +4,7 @@ import com.destroystokyo.paper.util.maplist.ReferenceList;
import com.destroystokyo.paper.util.misc.PlayerAreaMap;
import com.destroystokyo.paper.util.misc.PooledLinkedHashSets;
import com.mojang.logging.LogUtils;
+import gg.pufferfish.pufferfish.util.AsyncPlayerAreaMap;
import io.papermc.paper.chunk.system.scheduling.ChunkHolderManager;
import io.papermc.paper.util.CoordinateUtils;
import io.papermc.paper.util.TickThread;
@@ -14,6 +15,7 @@ import it.unimi.dsi.fastutil.longs.Long2ReferenceMap;
import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.CrashReport;
import net.minecraft.ReportedException;
import net.minecraft.core.BlockPos;
@@ -58,6 +60,10 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -145,6 +151,10 @@ public final class RegionizedWorldData {
into.wanderingTraderSpawnDelay = Math.max(from.wanderingTraderSpawnDelay, into.wanderingTraderSpawnDelay);
into.wanderingTraderSpawnChance = Math.max(from.wanderingTraderSpawnChance, into.wanderingTraderSpawnChance);
}
+
+ //Luminol start - Async mob spawning
+ from.lastAsyncSpawnStateTask = null; //Discard the task currently processing
+ //Luminol end
}
@Override
@@ -302,6 +312,10 @@ public final class RegionizedWorldData {
regionizedWorldData.wanderingTraderSpawnDelay = from.wanderingTraderSpawnDelay;
regionizedWorldData.villageSiegeState = new VillageSiegeState(); // just re set it, as the spawn pos will be invalid
}
+
+ //Luminol start - Async mob spawning
+ from.lastAsyncSpawnStateTask = null; //Reset the task
+ //Luminol end
}
};
@@ -398,6 +412,22 @@ public final class RegionizedWorldData {
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos;
public final Long2IntOpenHashMap chunksBeingWorkedOn = new Long2IntOpenHashMap();
+ //Luminol start - Asnc mob spawning
+ public volatile CompletableFuture<NaturalSpawner.SpawnState> lastAsyncSpawnStateTask = null;
+ public static ThreadPoolExecutor ASYNC_MOB_SPAWNING_EXECUTOR;
+ public static void initMobSpawningExecutor(){
+ if (LuminolConfig.enableAsyncMobSpawning){
+ ASYNC_MOB_SPAWNING_EXECUTOR = new ThreadPoolExecutor(
+ 1,
+ Integer.MAX_VALUE,
+ 1,
+ TimeUnit.MINUTES,
+ new LinkedBlockingQueue<>()
+ );
+ }
+ }
+ //Luminol end
+
public static final class TempCollisionList<T> {
final UnsafeList<T> list = new UnsafeList<>(64);
boolean inUse;
@@ -430,7 +460,7 @@ public final class RegionizedWorldData {
// Mob spawning
private final PooledLinkedHashSets<ServerPlayer> pooledHashSets = new PooledLinkedHashSets<>();
- public final PlayerAreaMap mobSpawnMap = new PlayerAreaMap(this.pooledHashSets);
+ public final PlayerAreaMap mobSpawnMap = new AsyncPlayerAreaMap(this.pooledHashSets); //Luminol - Async mob spawning
public int catSpawnerNextTick = 0;
public int patrolSpawnerNextTick = 0;
public int phantomSpawnerNextTick = 0;
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index e8cd180bab5c196db09ded74aea676b4412fc6e9..534f54be1495b1a8f754bec0eb1aba8306c1d902 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -2,6 +2,7 @@ package me.earthme.luminol;
import dev.kaiijumc.kaiiju.region.RegionFileFormat;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import io.papermc.paper.threadedregions.RegionizedWorldData;
import me.earthme.luminol.commands.TpsBarCommand;
import me.earthme.luminol.functions.GlobalServerTpsBar;
import net.minecraft.core.registries.BuiltInRegistries;
@@ -62,6 +63,7 @@ public class LuminolConfig {
public static boolean asyncPathProcessing = false;
public static int asyncPathProcessingMaxThreads = 0;
public static int asyncPathProcessingKeepalive = 60;
+ public static boolean enableAsyncMobSpawning = false;
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -188,6 +190,8 @@ public class LuminolConfig {
asyncPathProcessingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1);
if (!asyncPathProcessing)
asyncPathProcessingMaxThreads = 0;
+ enableAsyncMobSpawning = get("optimizations.enable_async_mob_spawning",enableAsyncMobSpawning);
+ RegionizedWorldData.initMobSpawningExecutor();
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/me/earthme/luminol/utils/AsyncMobSpawnExecutor.java b/src/main/java/me/earthme/luminol/utils/AsyncMobSpawnExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..88d5b188ccfb17fe1ae4b08f32565f27569cad5c
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/utils/AsyncMobSpawnExecutor.java
@@ -0,0 +1,71 @@
+package me.earthme.luminol.utils;
+
+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue;
+import net.minecraft.server.MinecraftServer;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.LockSupport;
+
+public class AsyncMobSpawnExecutor implements Runnable, Executor {
+ private final MultiThreadedQueue<Runnable> allTasks = new MultiThreadedQueue<>();
+ private final Thread worker = new Thread(this);
+ private AtomicBoolean shouldRunNext = new AtomicBoolean(true);
+ private AtomicBoolean isRunning = new AtomicBoolean(false);
+ private AtomicBoolean isIdle = new AtomicBoolean(false);
+
+ public boolean isRunning(){
+ return this.isRunning.get();
+ }
+
+ public void startExecutor(){
+ this.worker.setDaemon(true);
+ this.worker.setContextClassLoader(MinecraftServer.class.getClassLoader());
+ this.worker.start();
+ }
+
+ public void forceTerminate(){
+ this.shouldRunNext.set(false);
+ if (this.isRunning.get()){
+ this.allTasks.clear();
+ LockSupport.unpark(this.worker);
+ }
+ }
+
+ public void dropAllTasks(){
+ this.allTasks.clear();
+ }
+
+ @Override
+ public void run() {
+ this.isRunning.set(true);
+ try {
+ while (this.shouldRunNext.get()){
+ final Runnable task = this.allTasks.poll();
+ if (task != null){
+ this.isIdle.set(false);
+
+ try {
+ task.run();
+ }catch (Exception e){
+ e.printStackTrace(); //TODO - Exception processing?
+ }
+
+ continue;
+ }
+
+ this.isIdle.set(true);
+ LockSupport.park();
+ }
+ }finally {
+ this.isRunning.set(false);
+ }
+ }
+
+ @Override
+ public void execute(@NotNull Runnable command) {
+ this.allTasks.offer(command);
+ LockSupport.unpark(this.worker); //Notify
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index b9b1dfe04eda8498f0ceff0aee66489d2a02b814..c470eafef884075b6e4d170adc2ced96a4beb517 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -11,13 +11,15 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
-import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Supplier;
import javax.annotation.Nullable;
+
+import io.papermc.paper.threadedregions.RegionizedWorldData;
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
@@ -487,32 +489,38 @@ public class ServerChunkCache extends ChunkSource {
this.level.timings.countNaturalMobs.startTiming(); // Paper - timings
int l = this.distanceManager.getNaturalSpawnChunkCount();
// Paper start - per player mob spawning
- NaturalSpawner.SpawnState spawnercreature_d; // moved down
+ NaturalSpawner.SpawnState spawnercreature_d = null; // moved down
profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); try { // Folia - profiler
- if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
- // re-set mob counts
- for (ServerPlayer player : regionizedWorldData.getLocalPlayers()) { // Folia - region threading
- // Paper start - per player mob spawning backoff
- for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) {
- player.mobCounts[ii] = 0;
-
- int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm?
- if (newBackoff < 0) {
- newBackoff = 0;
+ if (!LuminolConfig.enableAsyncMobSpawning){ //Luminol
+ if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
+ // re-set mob counts
+ for (ServerPlayer player : regionizedWorldData.getLocalPlayers()) { // Folia - region threading
+ // Paper start - per player mob spawning backoff
+ for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) {
+ player.mobCounts[ii] = 0;
+
+ int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm?
+ if (newBackoff < 0) {
+ newBackoff = 0;
+ }
+ player.mobBackoffCounts[ii] = newBackoff;
}
- player.mobBackoffCounts[ii] = newBackoff;
+ // Paper end - per player mob spawning backoff
}
- // Paper end - per player mob spawning backoff
+ spawnercreature_d = NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true); // Folia - region threading
+ } else {
+ spawnercreature_d = NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading
}
- spawnercreature_d = NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true); // Folia - region threading
- } else {
- spawnercreature_d = NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading
+ }//Luminol
+ //Luminol start - Async mob spawning
+ if (!LuminolConfig.enableAsyncMobSpawning){
+ regionizedWorldData.lastAsyncSpawnStateTask = CompletableFuture.completedFuture(spawnercreature_d);
}
} finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); } // Folia - profiler
// Paper end
this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings
- regionizedWorldData.lastSpawnState = spawnercreature_d; // Folia - region threading
+ //regionizedWorldData.lastSpawnState = spawnercreature_d; // Folia - region threading //Luminol - Async mob spawning
gameprofilerfiller.popPush("filteringLoadedChunks");
// Paper - optimise chunk tick iteration
// Paper - optimise chunk tick iteration
@@ -610,7 +618,12 @@ public class ServerChunkCache extends ChunkSource {
chunk1.incrementInhabitedTime(j);
if (spawn && flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration
++spawnChunkCount; // Folia - profiler
- NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1);
+
+ //Luminol start - Async mob spawning
+ if (regionizedWorldData.lastAsyncSpawnStateTask != null && regionizedWorldData.lastAsyncSpawnStateTask.isDone()){
+ NaturalSpawner.spawnForChunk(this.level, chunk1, regionizedWorldData.lastAsyncSpawnStateTask.join(), this.spawnFriendlies, this.spawnEnemies, flag1);
+ }
+ //Luminol end
}
if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration
@@ -667,6 +680,36 @@ public class ServerChunkCache extends ChunkSource {
gameprofilerfiller.pop();
gameprofilerfiller.pop();
this.chunkMap.tick();
+
+ //Luminol start - Async mob spawning
+ if (LuminolConfig.enableAsyncMobSpawning){
+ //Luminol - Copied down
+ if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
+ // re-set mob counts
+ for (ServerPlayer player : regionizedWorldData.getLocalPlayers()) { // Folia - region threading
+ // Paper start - per player mob spawning backoff
+ for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) {
+ player.mobCounts[ii] = 0;
+
+ int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm?
+ if (newBackoff < 0) {
+ newBackoff = 0;
+ }
+ player.mobBackoffCounts[ii] = newBackoff;
+ }
+ // Paper end - per player mob spawning backoff
+ }
+
+ if (regionizedWorldData.lastAsyncSpawnStateTask == null || regionizedWorldData.lastAsyncSpawnStateTask.isDone()){
+ regionizedWorldData.lastAsyncSpawnStateTask = CompletableFuture.supplyAsync(() -> NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true),RegionizedWorldData.ASYNC_MOB_SPAWNING_EXECUTOR);
+ }
+ } else {
+ if (regionizedWorldData.lastAsyncSpawnStateTask == null || regionizedWorldData.lastAsyncSpawnStateTask.isDone()){
+ regionizedWorldData.lastAsyncSpawnStateTask = CompletableFuture.supplyAsync(() -> NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false), RegionizedWorldData.ASYNC_MOB_SPAWNING_EXECUTOR);
+ }
+ }
+ }
+ //Luminol end
}
}
@@ -809,7 +852,7 @@ public class ServerChunkCache extends ChunkSource {
@VisibleForDebug
public NaturalSpawner.SpawnState getLastSpawnState() {
io.papermc.paper.threadedregions.RegionizedWorldData worldData = this.level.getCurrentWorldData(); // Folia - region threading
- return worldData == null ? null : worldData.lastSpawnState; // Folia - region threading
+ return worldData.lastAsyncSpawnStateTask != null && worldData.lastAsyncSpawnStateTask.isDone() ? worldData.lastAsyncSpawnStateTask.join() : null; // Folia - region threading //Luminol - Async mob spawning
}
public void removeTicketsOnClosing() {
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
index 5caca2a34849189ea42d2699f6d8672e0d7251cb..b21243d494fd1989e7d6c2b98b08e090dc2f38b7 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -1,6 +1,9 @@
package net.minecraft.world.level;
+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor;
import com.mojang.logging.LogUtils;
+import io.papermc.paper.threadedregions.RegionizedServer;
+import io.papermc.paper.util.TickThread;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
@@ -117,6 +120,15 @@ public final class NaturalSpawner {
object2intopenhashmap.addTo(enumcreaturetype, 1);
// Paper start
if (countMobs) {
+ //Luminol start - Async mob spawning
+ if (!TickThread.isTickThread()){
+ RegionizedServer.getInstance().taskQueue.queueTickTaskQueue(chunk.level,chunk.locX,chunk.locZ,()->{
+ chunk.level.getChunkSource().chunkMap.updatePlayerMobTypeMap(entity);
+ });
+ return;
+ }
+ //Luminol end
+
chunk.level.getChunkSource().chunkMap.updatePlayerMobTypeMap(entity);
}
// Paper end

View File

@@ -1,93 +1,80 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 16:44:23 +0800
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 05:56:56 +0000
Subject: [PATCH] Pufferfish Dynamic Activation of Brain
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 11c1a367fbc25cb63738a00ad93fb0b0b3500e7d..4f6af1fa55047e7be9e57c1dd1c60e9d96d12187 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -11,13 +11,16 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
+import java.util.*;
import java.util.logging.Level;
import java.io.File;
import java.io.IOException;
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/EntityDABConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/EntityDABConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..af5893ba1f738ec9827d7b714682c314229292d9
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/EntityDABConfig.java
@@ -0,0 +1,60 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.DoNotLoad;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.server.MinecraftServer;
+import org.bukkit.configuration.ConfigurationSection;
+import net.minecraft.world.entity.EntityType;
+import java.util.Collections;
+import java.util.List;
+
public class LuminolConfig {
private static final Logger logger = LogManager.getLogger();
private static final File PARENT_FOLDER = new File("luminol_config");
@@ -48,6 +51,12 @@ public class LuminolConfig {
public static boolean enableSuffocationOptimization = true;
public static int maxProjectileLoadsPerTick;
public static int maxProjectileLoadsPerProjectile;
+ public static boolean dearEnabled;
+ public static int startDistance;
+public class EntityDABConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean dearEnabled = false;
+ @ConfigInfo(baseName = "start_distance",comments =
+ "This value determines how far away an entity has to be\n" +
+ " from the player to start being effected by DEAR."
+ )
+ public static int startDistance = 12;
+ @DoNotLoad
+ public static int startDistanceSquared;
+ public static int maximumActivationPrio;
+ @ConfigInfo(baseName = "max-tick-freq",comments =
+ "This value defines how often in ticks, the furthest entity\n"+
+ "will get their pathfinders and behaviors ticked. 20 = 1s")
+ public static int maximumActivationPrio = 20;
+ @ConfigInfo(baseName = "activation-dist-mod",comments =
+ """
+ This value defines how much distance modifies an entity's
+ tick frequency. freq = (distanceToPlayer^2) / (2^value)
+ If you want further away entities to tick less often, use 7.
+ If you want further away entities to tick more often, try 9.""")
+ public static int activationDistanceMod;
+ @ConfigInfo(baseName = "blacklisted-entities")
+ public static List<String> blackedEntities = Collections.emptyList();
+
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -86,6 +95,33 @@ public class LuminolConfig {
}
}
+ private static void initDAB(){
+ dearEnabled = get("optimizations.dab.enabled", true);
+ startDistance = get("optimizations.dab.start-distance", 12,
+ "This value determines how far away an entity has to be\n"+
+ "from the player to start being effected by DEAR.");
+ startDistanceSquared = startDistance * startDistance;
+ maximumActivationPrio = get("optimizations.dab.max-tick-freq",20,
+ "This value defines how often in ticks, the furthest entity\n"+
+ "will get their pathfinders and behaviors ticked. 20 = 1s");
+ activationDistanceMod = get("optimizations.dab.activation-dist-mod",8,
+ """
+ This value defines how much distance modifies an entity's
+ tick frequency. freq = (distanceToPlayer^2) / (2^value)
+ If you want further away entities to tick less often, use 7.
+ If you want further away entities to tick more often, try 9.""");
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.OPTIMIZATIONS;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "dab";
+ }
+
+ @Override
+ public void onLoaded(CommentedFileConfig config) {
+ for (EntityType<?> entityType : BuiltInRegistries.ENTITY_TYPE) {
+ entityType.dabEnabled = true; // reset all, before setting the ones to true
+ }
+ get("optimizations.dab.blacklisted-entities",Collections.<String>emptyList(), "A list of entities to ignore for activation")
+ .forEach(name -> EntityType.byString(name).ifPresentOrElse(entityType -> {
+
+ blackedEntities.forEach(name -> EntityType.byString(name).ifPresentOrElse(entityType -> {
+ entityType.dabEnabled = false;
+ }, () -> MinecraftServer.LOGGER.warn("Unknown entity \"" + name + "\"")));
+ }, () -> MinecraftServer.LOGGER.warn("Unknown entity \"" + name + "\"")));
+
+ MAIN_CONFIG.setComment("optimizations.dab", "Optimizes entity brains when\n"+"they're far away from the player");
+ config.setComment("optimizations.dab", "Optimizes entity brains when\n" + "they're far away from the player");
+ }
+
public static void initValues(){
serverModName = get("misc.server_mod_name",serverModName,"The servermod name will be sent to players,and you can see it in F3 or motd responses");
fakeVanillaModeEnabled = get("misc.enable_fake_vanilla_mode",fakeVanillaModeEnabled,"Enable this to make the ping response of your server like a vanilla server");
@@ -130,6 +166,7 @@ public class LuminolConfig {
initEntityTTL();
maxProjectileLoadsPerTick = get("optimizations.projectile.max-loads-per-tick", maxProjectileLoadsPerTick, "Controls how many chunks are allowed \nto be sync loaded by projectiles in a tick.");
maxProjectileLoadsPerProjectile = get("optimizations.projectile.max-loads-per-projectile", maxProjectileLoadsPerProjectile, "Controls how many chunks a projectile \n can load in its lifetime before it gets \nautomatically removed.");
+ initDAB();
}
public static <T> T get(String key,T def){
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 561681deaf647277ecde64eed4cfbd9f38b5fed1..2ba86122ccb444908c35ea5cc1e245f5068a054a 100644
index 6b8cbf681203c20eebb214c5c0b0fe0374aa30dc..12c46e7a3f6a8675921d95dee97ece4a83252282 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -982,6 +982,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -994,6 +994,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.timings.entityTick.startTiming(); // Spigot
profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_TICK); try { // Folia - profiler
regionizedWorldData.forEachTickingEntity((entity) -> { // Folia - regionised ticking
@@ -96,26 +83,26 @@ index 561681deaf647277ecde64eed4cfbd9f38b5fed1..2ba86122ccb444908c35ea5cc1e245f5
if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed
entity.discard();
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 8bdaab46c2e128aa58d13101170ce358146377a8..56efbcc29adca0239ef09a269f0899a3a6e2801b 100644
index 053e9204104a886f4b7e828b7c5e0d277c44d676..a999e3204d89ce2107026940cec7399360739ef0 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -436,6 +436,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
return this.originWorld;
}
// Paper end
+ // Pufferfish start
@@ -482,6 +482,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// Folia - region ticking
// Paper end - optimise entity tracking
+ //Pufferfish start
+ public boolean activatedPriorityReset = false; // DAB
+ public int activatedPriority = LuminolConfig.maximumActivationPrio; // golf score
+ public int activatedPriority = me.earthme.luminol.config.modules.optimizations.EntityDABConfig.maximumActivationPrio; // golf score
+ // Pufferfish end
+
+
public float getBukkitYaw() {
return this.yRot;
}
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
index 4d60ac50a1d3860f2a2e9265aef9507d790220a3..0867c85964952ec118ea7517cd5ef570be1ee982 100644
index aa2bb97ef305ed234a11b05e665ac1062b571591..29699e51b3e791a1a82a19c95fd6a3f30bac75d5 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -301,6 +301,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
@@ -316,6 +316,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
private final boolean canSpawnFarFromPlayer;
private final int clientTrackingRange;
private final int updateInterval;
@@ -124,10 +111,10 @@ index 4d60ac50a1d3860f2a2e9265aef9507d790220a3..0867c85964952ec118ea7517cd5ef570
private String descriptionId;
@Nullable
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index d3f8aa29b05a3813c0ec6e2ea5a253868abd6b07..54e821351e46d25e8b0ead52d2c8dfecd1957544 100644
index a6c1d59085e0c58d9d1996d9e905bc24a3678e0c..fae60501284a68238c53ffc19075d46ac49cfdaa 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -234,10 +234,10 @@ public abstract class Mob extends LivingEntity implements Targeting {
@@ -249,10 +249,10 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
@Override
public void inactiveTick() {
super.inactiveTick();
@@ -140,60 +127,52 @@ index d3f8aa29b05a3813c0ec6e2ea5a253868abd6b07..54e821351e46d25e8b0ead52d2c8dfec
this.targetSelector.tick();
}
}
@@ -934,16 +934,20 @@ public abstract class Mob extends LivingEntity implements Targeting {
@@ -992,16 +992,20 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
if (i % 2 != 0 && this.tickCount > 1) {
this.level().getProfiler().push("targetSelector");
gameprofilerfiller.push("targetSelector");
+ if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
this.targetSelector.tickRunningGoals(false);
this.level().getProfiler().pop();
this.level().getProfiler().push("goalSelector");
gameprofilerfiller.pop();
gameprofilerfiller.push("goalSelector");
+ if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
this.goalSelector.tickRunningGoals(false);
this.level().getProfiler().pop();
gameprofilerfiller.pop();
} else {
this.level().getProfiler().push("targetSelector");
gameprofilerfiller.push("targetSelector");
+ if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
this.targetSelector.tick();
this.level().getProfiler().pop();
this.level().getProfiler().push("goalSelector");
gameprofilerfiller.pop();
gameprofilerfiller.push("goalSelector");
+ if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
this.goalSelector.tick();
this.level().getProfiler().pop();
gameprofilerfiller.pop();
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
index b738ee2d3801fadfd09313f05ae24593e56b0ec6..9306ab8d2b6eeb73f86d4d94c0065d461905d702 100644
index 74d4f653d5c7f1923c59019effd78337402f7025..73f2a527d18f61db97d5b5050ebe67822771cf58 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
@@ -11,6 +11,8 @@ import java.util.Set;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.util.profiling.ProfilerFiller;
import org.slf4j.Logger;
@@ -53,9 +55,12 @@ public class GoalSelector {
@@ -43,9 +43,13 @@ public class GoalSelector {
}
// Paper start
- public boolean inactiveTick() {
+ public boolean inactiveTick(int tickRate, boolean inactive) { // Pufferfish start
+ if (inactive && !LuminolConfig.dearEnabled) tickRate = 4; // reset to Paper's
+ tickRate = Math.min(tickRate, this.newGoalRate);
+ if (inactive && !me.earthme.luminol.config.modules.optimizations.EntityDABConfig.dearEnabled) tickRate = 4; // reset to Paper's
+ tickRate = Math.min(tickRate, 3);
this.curRate++;
- return this.curRate % this.newGoalRate == 0;
+ return this.curRate % tickRate == 0;
- return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct
+ //return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct
+ return this.curRate % tickRate == 0; // Luminol - Waiting Paper
+ // Pufferfish end
}
public boolean hasTasks() {
for (WrappedGoal task : this.availableGoals) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
index 5ad5f22e5aa26445e5eb229958e7bf356bdd460e..d241ca4d0295f9fce39c11197bd435cfac7f6e54 100644
index 991e3274091c4e25eebc6debd44653e5b566eedb..789d3469ce4983868e4b880b6053bd2d8c33a10a 100644
--- a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
+++ b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
@@ -221,9 +221,11 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
@@ -215,9 +215,11 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
return 0.4F;
}
@@ -206,10 +185,10 @@ index 5ad5f22e5aa26445e5eb229958e7bf356bdd460e..d241ca4d0295f9fce39c11197bd435cf
this.level().getProfiler().pop();
this.level().getProfiler().push("allayActivityUpdate");
diff --git a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
index d5b97d4316390028f54aa9bb9fa52b0b003e32a0..b4793b88688bd568a428aa520e880f0038de45a7 100644
index a8cc6ddbf45370fe632e5c5fb7ceef3d299e62a4..98766696556b520cf565ccadc8dba207832b4ae3 100644
--- a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
+++ b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
@@ -280,9 +280,11 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder<Axolo
@@ -268,9 +268,11 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder<Axolo
return true;
}
@@ -222,11 +201,11 @@ index d5b97d4316390028f54aa9bb9fa52b0b003e32a0..b4793b88688bd568a428aa520e880f00
this.level().getProfiler().pop();
this.level().getProfiler().push("axolotlActivityUpdate");
diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
index 5000ebc5f19dee72a86360062b822aecd60beb47..c8e3d47b3f2dc919cca8ad397095437f1da6c762 100644
index 816977990639ec0559b652fc9666afd5046f0a5d..714703519965e8dae42be7442f292b581cc7c049 100644
--- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
+++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
@@ -164,9 +164,11 @@ public class Frog extends Animal implements VariantHolder<FrogVariant> {
return true;
@@ -181,9 +181,11 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
.ifPresent(this::setVariant);
}
+ private int behaviorTick = 0; // Pufferfish
@@ -238,10 +217,10 @@ index 5000ebc5f19dee72a86360062b822aecd60beb47..c8e3d47b3f2dc919cca8ad397095437f
this.level().getProfiler().pop();
this.level().getProfiler().push("frogActivityUpdate");
diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java
index 4aeab90e778629c355189dfe79c39c4b21f5f5ac..6ed4ac06c76b8d0d6e8db778cade15dbd1e3e5f5 100644
index 290d41136f5ec7671bc4990dfe50da0a770c124d..0d34e9e0f7ce35c3c28a9216cf3cdd5eddfe90f6 100644
--- a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java
+++ b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java
@@ -77,9 +77,11 @@ public class Tadpole extends AbstractFish {
@@ -83,9 +83,11 @@ public class Tadpole extends AbstractFish {
return SoundEvents.TADPOLE_FLOP;
}
@@ -254,10 +233,10 @@ index 4aeab90e778629c355189dfe79c39c4b21f5f5ac..6ed4ac06c76b8d0d6e8db778cade15db
this.level().getProfiler().pop();
this.level().getProfiler().push("tadpoleActivityUpdate");
diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
index 111a244087e24f25ba8524a46a228da10cd9498a..ff12ba2b79cb2e7e0bfd0e3b58ff6cb9e770092b 100644
index 376bcbc189008464f4d518c1e07643431ba96306..07bdea8a7d6706839a758afe0242202c7e841416 100644
--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
@@ -191,9 +191,11 @@ public class Goat extends Animal {
@@ -190,9 +190,11 @@ public class Goat extends Animal {
return (Brain<Goat>) super.getBrain(); // CraftBukkit - decompile error
}
@@ -270,11 +249,11 @@ index 111a244087e24f25ba8524a46a228da10cd9498a..ff12ba2b79cb2e7e0bfd0e3b58ff6cb9
this.level().getProfiler().pop();
this.level().getProfiler().push("goatActivityUpdate");
diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
index 4257f2282152aee09533c9a2e53018d3e49effa4..e703320717ff620a19ff76d1c10066117c9895d5 100644
index c583d883118ded5e1884c757427dc5e73c10dd27..6f8a22c51ba5e2713dcdfc61c61b35123f9bf326 100644
--- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
@@ -128,9 +128,11 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
return (Brain<Hoglin>) super.getBrain(); // Paper - decompile fix
@@ -153,9 +153,11 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
return (Brain<Hoglin>)super.getBrain();
}
+ private int behaviorTick; // Pufferfish
@@ -286,10 +265,10 @@ index 4257f2282152aee09533c9a2e53018d3e49effa4..e703320717ff620a19ff76d1c1006611
this.level().getProfiler().pop();
HoglinAi.updateActivity(this);
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
index 6407ddef8442fce4f310ac4babf3e3de0dd5fc9a..cfdc1650783d6855e0d4f33ec68aab48dbee09f0 100644
index a8ab486c7e11ec137da48174af6f1030dfd48056..5878a6ecadc2b9f7ac9f70622a8c85e2940e139a 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -300,9 +300,11 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
@@ -294,9 +294,11 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
return !this.cannotHunt;
}
@@ -302,10 +281,10 @@ index 6407ddef8442fce4f310ac4babf3e3de0dd5fc9a..cfdc1650783d6855e0d4f33ec68aab48
this.level().getProfiler().pop();
PiglinAi.updateActivity(this);
diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
index b2bc3a832c310448046ccde37a04918aa6d63197..5e43912708f9074dee1bb351efa737a7e6796fc3 100644
index ddd60be52dce5773c80934be5aa5705db239e3dd..9cf56f2ada025aae0710099bcc3b5c62fd7bbb9e 100644
--- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
+++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
@@ -272,11 +272,13 @@ public class Warden extends Monster implements VibrationSystem {
@@ -271,11 +271,13 @@ public class Warden extends Monster implements VibrationSystem {
}
@@ -320,10 +299,10 @@ index b2bc3a832c310448046ccde37a04918aa6d63197..5e43912708f9074dee1bb351efa737a7
this.level().getProfiler().pop();
super.customServerAiStep();
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
index 4e9ccc518f37755e86687653f7724240db754682..a94661deaa6e1288bb957dc5d7711c5d03b9e460 100644
index 6339967b154af1ca9632c7b8b315d612f4b80ea2..c4b7fd6c9d0f26361295a70d63f6fc080063d129 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -142,6 +142,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@@ -143,6 +143,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
return holder.is(PoiTypes.MEETING);
});
@@ -332,7 +311,7 @@ index 4e9ccc518f37755e86687653f7724240db754682..a94661deaa6e1288bb957dc5d7711c5d
public Villager(EntityType<? extends Villager> entityType, Level world) {
this(entityType, world, VillagerType.PLAINS);
}
@@ -245,6 +247,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@@ -246,6 +248,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
}
// Spigot End
@@ -340,7 +319,7 @@ index 4e9ccc518f37755e86687653f7724240db754682..a94661deaa6e1288bb957dc5d7711c5d
@Override
@Deprecated // Paper
protected void customServerAiStep() {
@@ -254,7 +257,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@@ -255,7 +258,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
protected void customServerAiStep(final boolean inactive) {
// Paper end
this.level().getProfiler().push("villagerBrain");
@@ -354,17 +333,10 @@ index 4e9ccc518f37755e86687653f7724240db754682..a94661deaa6e1288bb957dc5d7711c5d
if (this.assignProfessionWhenSpawned) {
this.assignProfessionWhenSpawned = false;
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
index 22daed525b023998a05884db603e2c7385ce0873..e77e1c60a611c49489c65d66e54236a86c3093e3 100644
index c77beef9651aa2f7333d536e8ff4af3281834619..9628cc2b7f200e0bab4fed48997dde3e266200ee 100644
--- a/src/main/java/org/spigotmc/ActivationRange.java
+++ b/src/main/java/org/spigotmc/ActivationRange.java
@@ -1,5 +1,6 @@
package org.spigotmc;
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerChunkCache;
@@ -38,6 +39,10 @@ import co.aikar.timings.MinecraftTimings;
@@ -38,6 +38,10 @@ import co.aikar.timings.MinecraftTimings;
import net.minecraft.world.entity.schedule.Activity;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
@@ -375,24 +347,24 @@ index 22daed525b023998a05884db603e2c7385ce0873..e77e1c60a611c49489c65d66e54236a8
public class ActivationRange
{
@@ -230,6 +235,25 @@ public class ActivationRange
@@ -232,6 +236,25 @@ public class ActivationRange
}
// Paper end - configurable marker ticking
ActivationRange.activateEntity(entity);
// Paper end - Configurable marker ticking
ActivationRange.activateEntity(entity, bbByType); // Folia - threaded regions
+
+ // Pufferfish start
+ if (LuminolConfig.dearEnabled && entity.getType().dabEnabled) {
+ if (me.earthme.luminol.config.modules.optimizations.EntityDABConfig.dearEnabled && entity.getType().dabEnabled) {
+ if (!entity.activatedPriorityReset) {
+ entity.activatedPriorityReset = true;
+ entity.activatedPriority = LuminolConfig.maximumActivationPrio;
+ entity.activatedPriority = me.earthme.luminol.config.modules.optimizations.EntityDABConfig.maximumActivationPrio;
+ }
+ Vec3 playerVec = player.position();
+ Vec3 entityVec = entity.position();
+ double diffX = playerVec.x - entityVec.x, diffY = playerVec.y - entityVec.y, diffZ = playerVec.z - entityVec.z;
+ int squaredDistance = (int) (diffX * diffX + diffY * diffY + diffZ * diffZ);
+ entity.activatedPriority = squaredDistance > LuminolConfig.startDistanceSquared ?
+ Math.max(1, Math.min(squaredDistance >> LuminolConfig.activationDistanceMod, entity.activatedPriority)) :
+ 1;
+ entity.activatedPriority = squaredDistance > me.earthme.luminol.config.modules.optimizations.EntityDABConfig.startDistanceSquared ?
+ Math.max(1, Math.min(squaredDistance >> me.earthme.luminol.config.modules.optimizations.EntityDABConfig.activationDistanceMod, entity.activatedPriority)) :
+ 1;
+ } else {
+ entity.activatedPriority = 1;
+ }
@@ -401,7 +373,7 @@ index 22daed525b023998a05884db603e2c7385ce0873..e77e1c60a611c49489c65d66e54236a8
}
// Paper end
}
@@ -246,12 +270,12 @@ public class ActivationRange
@@ -248,12 +271,12 @@ public class ActivationRange
if ( io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() > entity.activatedTick ) // Folia - threaded regions
{
if ( entity.defaultActivationState )
@@ -410,7 +382,7 @@ index 22daed525b023998a05884db603e2c7385ce0873..e77e1c60a611c49489c65d66e54236a8
entity.activatedTick = io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick(); // Folia - threaded regions
return;
}
if ( entity.activationType.boundingBox.intersects( entity.getBoundingBox() ) )
if ( bbByType[entity.activationType.ordinal()].intersects( entity.getBoundingBox() ) ) // Folia - threaded regions
- {
+ { // Pufferfish - diff on change
entity.activatedTick = io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick(); // Folia - threaded regions

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Mon, 11 Dec 2023 20:00:10 +0800
Subject: [PATCH] Added back worldborder command
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 3435bdeaf723c64103f7c924ea42a4ec78f2ba01..a7732effbb2885b398d18df2e581f7a0f279a85a 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -202,7 +202,7 @@ public class Commands {
TitleCommand.register(this.dispatcher);
//TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later
WeatherCommand.register(this.dispatcher);
- //WorldBorderCommand.register(this.dispatcher); // Folia - region threading - TODO later
+ WorldBorderCommand.register(this.dispatcher); // Folia - region threading - TODO later //Lumino - Add back world border
if (JvmProfiler.INSTANCE.isAvailable()) {
JfrCommand.register(this.dispatcher);
}

View File

@@ -0,0 +1,51 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Tue, 20 Feb 2024 13:03:42 +0000
Subject: [PATCH] Pufferfish Throttle goal selector during inactive ticking
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/EntityGoalSelectorInactiveTickConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/EntityGoalSelectorInactiveTickConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..acc032f727e605e79b688efb4873ff474fe7e132
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/EntityGoalSelectorInactiveTickConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class EntityGoalSelectorInactiveTickConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.OPTIMIZATIONS;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "skip_goal_selector_tick_in_inactive_tick";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index fae60501284a68238c53ffc19075d46ac49cfdaa..03cf4ef6fd09de13709400dc508266c2b3d99330 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -245,11 +245,13 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
return this.lookControl;
}
+ int _pufferfish_inactiveTickDisableCounter = 0; // Pufferfish - throttle inactive goal selector ticking
// Paper start
@Override
public void inactiveTick() {
super.inactiveTick();
- if (this.goalSelector.inactiveTick(this.activatedPriority, true)) { // Pufferfish - pass activated priroity
+ boolean isThrottled = me.earthme.luminol.config.modules.optimizations.EntityGoalSelectorInactiveTickConfig.enabled && _pufferfish_inactiveTickDisableCounter++ % 20 != 0; // Pufferfish - throttle inactive goal selector ticking
+ if (this.goalSelector.inactiveTick(this.activatedPriority, true) && !isThrottled) { // Pufferfish - pass activated priroity // Pufferfish - throttle inactive goal selector ticking
this.goalSelector.tick();
}
if (this.targetSelector.inactiveTick(this.activatedPriority, true)) { // Pufferfish - pass activated priority

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Tue, 20 Feb 2024 13:11:11 +0000
Subject: [PATCH] Pufferfish Reduce entity allocations
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
index 9ef8f014af332da129bfcd3370da983ec035ecc6..bc178967affd21ad04b83ea26639a2dd9b497454 100644
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
@@ -22,9 +22,11 @@ public class AttributeMap {
private final Map<Holder<Attribute>, AttributeInstance> attributes = new Object2ObjectOpenHashMap<>();
private final Set<AttributeInstance> dirtyAttributes = new ObjectOpenHashSet<>();
private final AttributeSupplier supplier;
+ private final java.util.function.Function<Holder<Attribute>, AttributeInstance> createInstance; // Pufferfish
public AttributeMap(AttributeSupplier defaultAttributes) {
this.supplier = defaultAttributes;
+ this.createInstance = attributex -> this.supplier.createInstance(this::onAttributeModified, attributex); // Pufferfish
}
private void onAttributeModified(AttributeInstance instance) {
@@ -43,7 +45,7 @@ public class AttributeMap {
@Nullable
public AttributeInstance getInstance(Holder<Attribute> attribute) {
- return this.attributes.computeIfAbsent(attribute, attributex -> this.supplier.createInstance(this::onAttributeModified, attributex));
+ return this.attributes.computeIfAbsent(attribute, this.createInstance); // Pufferfish - cache lambda, as for some reason java allocates it anyways
}
public boolean hasAttribute(Holder<Attribute> attribute) {

View File

@@ -1,77 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 17 Dec 2023 20:32:49 +0800
Subject: [PATCH] Purpur use alternative keep alive
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 6edafcdbc188cd6c78e4c4237363e41d927a665e..a62680768068b611fe723fedeb617d42c643e59e 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -64,6 +64,7 @@ public class LuminolConfig {
public static int asyncPathProcessingMaxThreads = 0;
public static int asyncPathProcessingKeepalive = 60;
public static boolean enableAsyncMobSpawning = false;
+ public static boolean useAlternateKeepAlive = false;
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -192,6 +193,7 @@ public class LuminolConfig {
asyncPathProcessingMaxThreads = 0;
enableAsyncMobSpawning = get("optimizations.enable_async_mob_spawning",enableAsyncMobSpawning);
RegionizedWorldData.initMobSpawningExecutor();
+ useAlternateKeepAlive = get("optimizations.enable_alternative_keep_alive_handling",useAlternateKeepAlive,"Enabling this sends a keepalive packet once per second to a player, and only kicks for timeout if none of them were responded to in 30 seconds. Responding to any of them in any order will keep the player connected. AKA, it won't kick your players because one packet gets dropped somewhere along the lines(From purpur)");
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
index 2bb944cef9bc8c5e56023ef20921ef13509d4823..9d23285f97ac5d90eb177ddc325281fa197d7f76 100644
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
@@ -51,6 +51,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
private long keepAliveTime = Util.getMillis(); // Paper
private boolean keepAlivePending;
private long keepAliveChallenge;
+ private it.unimi.dsi.fastutil.longs.LongList keepAlives = new it.unimi.dsi.fastutil.longs.LongArrayList(); // Purpur
private int latency;
private volatile boolean suspendFlushingOnServerThread = false;
private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit
@@ -91,6 +92,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@Override
public void handleKeepAlive(ServerboundKeepAlivePacket packet) {
+ // Purpur start
+ if (me.earthme.luminol.LuminolConfig.useAlternateKeepAlive) {
+ long id = packet.getId();
+ if (keepAlives.size() > 0 && keepAlives.contains(id)) {
+ int ping = (int) (Util.getMillis() - id);
+ this.latency = (this.latency * 3 + ping) / 4;
+ keepAlives.clear(); // we got a valid response, lets roll with it and forget the rest
+ }
+ } else
+ // Purpur end
//PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // CraftBukkit // Paper - This shouldn't be on the main thread
if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) {
int i = (int) (Util.getMillis() - this.keepAliveTime);
@@ -197,6 +208,21 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
long currentTime = Util.getMillis();
long elapsedTime = currentTime - this.keepAliveTime;
+ // Purpur start
+ if (me.earthme.luminol.LuminolConfig.useAlternateKeepAlive) {
+ if (elapsedTime >= 1000L) { // 1 second
+ if (!processedDisconnect && keepAlives.size() * 1000L >= KEEPALIVE_LIMIT) {
+ LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName());
+ disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT);
+ } else {
+ keepAliveTime = currentTime; // hijack this field for 1 second intervals
+ keepAlives.add(currentTime); // currentTime is ID
+ send(new ClientboundKeepAlivePacket(currentTime));
+ }
+ }
+ } else
+ // Purpur end
+
if (this.keepAlivePending) {
if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName()); // more info

View File

@@ -1,579 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 17 Dec 2023 20:39:21 +0800
Subject: [PATCH] Leaves Protocol Core
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java
index 1e3117ccd51be58d988089207a3efdbff02fc374..a28cdeed2a0a2d5194edcfc13cac38f2f2d80489 100644
--- a/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java
@@ -313,6 +313,8 @@ public final class RegionizedServer {
// player list
MinecraftServer.getServer().getPlayerList().tick();
+
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleTick(); //Leaves
}
private void tickPlayerSample() {
diff --git a/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java b/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java
index af86f752c33a2990405fea058b7c41c437ba9d46..bada9fae1e7178162429e1f5a1608b9c4a680a6c 100644
--- a/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java
@@ -20,7 +20,12 @@ public record ServerboundCustomPayloadPacket(CustomPacketPayload payload) implem
private static CustomPacketPayload readPayload(ResourceLocation id, FriendlyByteBuf buf) {
FriendlyByteBuf.Reader<? extends CustomPacketPayload> packetdataserializer_a = (FriendlyByteBuf.Reader) ServerboundCustomPayloadPacket.KNOWN_TYPES.get(id);
-
+ // Leaves start - protocol
+ CustomPacketPayload leavesPayload = top.leavesmc.leaves.protocol.core.LeavesProtocolManager.getPayload(id, buf);
+ if (leavesPayload != null) {
+ return leavesPayload;
+ }
+ // Leaves end - protocol
return (CustomPacketPayload) (packetdataserializer_a != null ? (CustomPacketPayload) packetdataserializer_a.apply(buf) : readUnknownPayload(id, buf));
}
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
index 9d23285f97ac5d90eb177ddc325281fa197d7f76..e1ace2ad411b8d54c56660b41e774a1c998b3ac3 100644
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
@@ -127,6 +127,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@Override
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePayload(player, packet.payload()); // Leaves - protocol
// Paper start - handle brand payload packet
if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.BrandPayload brandPayload) {
this.player.clientBrandName = brandPayload.brand();
@@ -144,6 +145,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
String channels = payload.toString(com.google.common.base.Charsets.UTF_8);
for (String channel : channels.split("\0")) {
this.getCraftPlayer().addChannel(channel);
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleMinecraftRegister(channel, player); // Leaves - protocol
}
} catch (Exception ex) {
ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t register custom payload", ex);
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 7edaa7558e40942f94c459e9b480ef640146ec6b..3f366ad035ada0ac8170d2925bbfe86b80bd84cb 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -435,6 +435,8 @@ public abstract class PlayerList {
//return; // Folia - region threading - must still allow the player to connect, as we must add to chunk map before handling disconnect
}
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); // Leaves - protocol
+
final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
@@ -691,6 +693,7 @@ public abstract class PlayerList {
return this.remove(entityplayer, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName())));
}
public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) {
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerLeave(entityplayer); // Leaves - protocol
// Paper end
ServerLevel worldserver = entityplayer.serverLevel();
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 5fe36cbb14f0f0e9692cfa40381cebdb4e142bbe..ee66241a422acb8920395fd5e41578a966746f5c 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -478,6 +478,7 @@ public final class CraftServer implements Server {
MapPalette.setMapColorCache(new CraftMapColorCache(this.logger));
}
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.init(); // Leaves - protocol
}
public boolean getCommandBlockOverride(String command) {
@@ -1114,6 +1115,7 @@ public final class CraftServer implements Server {
io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleServerReload(); // Leaves - protocol
int pollCount = 0;
diff --git a/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocol.java
new file mode 100644
index 0000000000000000000000000000000000000000..64a1d25973b032e8cab64bbffa6824a131676773
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocol.java
@@ -0,0 +1,16 @@
+package top.leavesmc.leaves.protocol.core;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LeavesProtocol {
+
+ String namespace() default "minecraft";
+
+ String[] namespaces() default {};
+
+}
diff --git a/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocolManager.java b/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocolManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..055f044ce6cef4377f6f577efdbfad0ec9a2d57b
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocolManager.java
@@ -0,0 +1,340 @@
+package top.leavesmc.leaves.protocol.core;
+
+import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.level.ServerPlayer;
+import org.apache.commons.lang.ArrayUtils;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+public class LeavesProtocolManager {
+
+ private static final Map<LeavesProtocol, Map<ProtocolHandler.PayloadReceiver, Constructor<? extends CustomPacketPayload>>> KNOWN_TYPES = new HashMap<>();
+ private static final Map<LeavesProtocol, Map<ProtocolHandler.PayloadReceiver, Method>> KNOW_RECEIVERS = new HashMap<>();
+
+ private static final List<Method> TICKERS = new ArrayList<>();
+ private static final List<Method> PLAYER_JOIN = new ArrayList<>();
+ private static final List<Method> PLAYER_LEAVE = new ArrayList<>();
+ private static final List<Method> RELOAD_SERVER = new ArrayList<>();
+ private static final Map<LeavesProtocol, Map<ProtocolHandler.MinecraftRegister, Method>> MINECRAFT_REGISTER = new HashMap<>();
+
+ public static void init() {
+ for (Class<?> clazz : getClasses("top.leavesmc.leaves.protocol")) {
+ final LeavesProtocol protocol = clazz.getAnnotation(LeavesProtocol.class);
+ if (protocol != null) {
+ Set<Method> methods;
+ try {
+ Method[] publicMethods = clazz.getMethods();
+ Method[] privateMethods = clazz.getDeclaredMethods();
+ methods = new HashSet<>(publicMethods.length + privateMethods.length, 1.0f);
+ Collections.addAll(methods, publicMethods);
+ Collections.addAll(methods, privateMethods);
+ } catch (NoClassDefFoundError e) {
+ e.printStackTrace();
+ return;
+ }
+
+ Map<ProtocolHandler.PayloadReceiver, Constructor<? extends CustomPacketPayload>> map = new HashMap<>();
+ for (final Method method : methods) {
+ if (method.isBridge() || method.isSynthetic() || !Modifier.isStatic(method.getModifiers())) {
+ continue;
+ }
+
+ method.setAccessible(true);
+
+ final ProtocolHandler.Init init = method.getAnnotation(ProtocolHandler.Init.class);
+ if (init != null) {
+ try {
+ method.invoke(null);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ continue;
+ }
+
+ final ProtocolHandler.PayloadReceiver receiver = method.getAnnotation(ProtocolHandler.PayloadReceiver.class);
+ if (receiver != null) {
+ try {
+ map.put(receiver, receiver.payload().getConstructor(ResourceLocation.class, FriendlyByteBuf.class));
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ continue;
+ }
+
+ if (!KNOW_RECEIVERS.containsKey(protocol)) {
+ KNOW_RECEIVERS.put(protocol, new HashMap<>());
+ }
+
+ KNOW_RECEIVERS.get(protocol).put(receiver, method);
+ continue;
+ }
+
+ final ProtocolHandler.Ticker ticker = method.getAnnotation(ProtocolHandler.Ticker.class);
+ if (ticker != null) {
+ TICKERS.add(method);
+ continue;
+ }
+
+ final ProtocolHandler.PlayerJoin playerJoin = method.getAnnotation(ProtocolHandler.PlayerJoin.class);
+ if (playerJoin != null) {
+ PLAYER_JOIN.add(method);
+ continue;
+ }
+
+ final ProtocolHandler.PlayerLeave playerLeave = method.getAnnotation(ProtocolHandler.PlayerLeave.class);
+ if (playerLeave != null) {
+ PLAYER_LEAVE.add(method);
+ continue;
+ }
+
+ final ProtocolHandler.ReloadServer reloadServer = method.getAnnotation(ProtocolHandler.ReloadServer.class);
+ if (reloadServer != null) {
+ RELOAD_SERVER.add(method);
+ continue;
+ }
+
+ final ProtocolHandler.MinecraftRegister minecraftRegister = method.getAnnotation(ProtocolHandler.MinecraftRegister.class);
+ if (minecraftRegister != null) {
+ if (!MINECRAFT_REGISTER.containsKey(protocol)) {
+ MINECRAFT_REGISTER.put(protocol, new HashMap<>());
+ }
+
+ MINECRAFT_REGISTER.get(protocol).put(minecraftRegister, method);
+ }
+ }
+ KNOWN_TYPES.put(protocol, map);
+ }
+ }
+ }
+
+ public static CustomPacketPayload getPayload(ResourceLocation id, FriendlyByteBuf buf) {
+ for (LeavesProtocol protocol : KNOWN_TYPES.keySet()) {
+ if (!protocol.namespace().equals(id.getNamespace()) && !ArrayUtils.contains(protocol.namespaces(), id.getNamespace())) {
+ continue;
+ }
+
+ Map<ProtocolHandler.PayloadReceiver, Constructor<? extends CustomPacketPayload>> map = KNOWN_TYPES.get(protocol);
+ for (ProtocolHandler.PayloadReceiver receiver : map.keySet()) {
+ if (receiver.ignoreId() || receiver.payloadId().equals(id.getPath()) || ArrayUtils.contains(receiver.payloadIds(), id.getPath())) {
+ try {
+ return map.get(receiver).newInstance(id, buf);
+ } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public static void handlePayload(ServerPlayer player, CustomPacketPayload payload) {
+ for (LeavesProtocol protocol : KNOW_RECEIVERS.keySet()) {
+ if (!protocol.namespace().equals(payload.id().getNamespace()) && !ArrayUtils.contains(protocol.namespaces(), payload.id().getNamespace())) {
+ continue;
+ }
+
+ Map<ProtocolHandler.PayloadReceiver, Method> map = KNOW_RECEIVERS.get(protocol);
+ for (ProtocolHandler.PayloadReceiver receiver : map.keySet()) {
+ if (payload.getClass() == receiver.payload()) {
+ if (receiver.ignoreId() || receiver.payloadId().equals(payload.id().getPath()) ||
+ ArrayUtils.contains(receiver.payloadIds(), payload.id().getPath())) {
+ try {
+ map.get(receiver).invoke(null, player, payload);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static void handleTick() {
+ if (!TICKERS.isEmpty()) {
+ try {
+ for (Method method : TICKERS) {
+ method.invoke(null);
+ }
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void handlePlayerJoin(ServerPlayer player) {
+ if (!PLAYER_JOIN.isEmpty()) {
+ try {
+ for (Method method : PLAYER_JOIN) {
+ method.invoke(null, player);
+ }
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void handlePlayerLeave(ServerPlayer player) {
+ if (!PLAYER_LEAVE.isEmpty()) {
+ try {
+ for (Method method : PLAYER_LEAVE) {
+ method.invoke(null, player);
+ }
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void handleServerReload() {
+ if (!RELOAD_SERVER.isEmpty()) {
+ try {
+ for (Method method : RELOAD_SERVER) {
+ method.invoke(null);
+ }
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void handleMinecraftRegister(String channelId, ServerPlayer player) {
+ for (LeavesProtocol protocol : MINECRAFT_REGISTER.keySet()) {
+ String[] channel = channelId.split(":");
+ if (!protocol.namespace().equals(channel[0]) && !ArrayUtils.contains(protocol.namespaces(), channel[0])) {
+ continue;
+ }
+
+ Map<ProtocolHandler.MinecraftRegister, Method> map = MINECRAFT_REGISTER.get(protocol);
+ for (ProtocolHandler.MinecraftRegister register : map.keySet()) {
+ if (register.ignoreId() || register.channelId().equals(channel[1]) ||
+ ArrayUtils.contains(register.channelIds(), channel[1])) {
+ try {
+ map.get(register).invoke(null, player);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ public static Set<Class<?>> getClasses(String pack) {
+ Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
+ String packageDirName = pack.replace('.', '/');
+ Enumeration<URL> dirs;
+ try {
+ dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
+ while (dirs.hasMoreElements()) {
+ URL url = dirs.nextElement();
+ String protocol = url.getProtocol();
+ if ("file".equals(protocol)) {
+ String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8);
+ findClassesInPackageByFile(pack, filePath, classes);
+ } else if ("jar".equals(protocol)) {
+ JarFile jar;
+ try {
+ jar = ((JarURLConnection) url.openConnection()).getJarFile();
+ Enumeration<JarEntry> entries = jar.entries();
+ findClassesInPackageByJar(pack, entries, packageDirName, classes);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return classes;
+ }
+
+ private static void findClassesInPackageByFile(String packageName, String packagePath, Set<Class<?>> classes) {
+ File dir = new File(packagePath);
+ if (!dir.exists() || !dir.isDirectory()) {
+ return;
+ }
+ File[] dirfiles = dir.listFiles((file) -> file.isDirectory() || file.getName().endsWith(".class"));
+ if (dirfiles != null) {
+ for (File file : dirfiles) {
+ if (file.isDirectory()) {
+ findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), classes);
+ } else {
+ String className = file.getName().substring(0, file.getName().length() - 6);
+ try {
+ classes.add(Class.forName(packageName + '.' + className));
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ private static void findClassesInPackageByJar(String packageName, Enumeration<JarEntry> entries, String packageDirName, Set<Class<?>> classes) {
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ String name = entry.getName();
+ if (name.charAt(0) == '/') {
+ name = name.substring(1);
+ }
+ if (name.startsWith(packageDirName)) {
+ int idx = name.lastIndexOf('/');
+ if (idx != -1) {
+ packageName = name.substring(0, idx).replace('/', '.');
+ }
+ if (name.endsWith(".class") && !entry.isDirectory()) {
+ String className = name.substring(packageName.length() + 1, name.length() - 6);
+ try {
+ classes.add(Class.forName(packageName + '.' + className));
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ public record EmptyPayload(ResourceLocation id) implements CustomPacketPayload {
+
+ public EmptyPayload(ResourceLocation location, FriendlyByteBuf buf) {
+ this(location);
+ }
+
+ @Override
+ public void write(@NotNull FriendlyByteBuf buf) {
+ }
+ }
+
+ public record LeavesPayload(FriendlyByteBuf data, ResourceLocation id) implements CustomPacketPayload {
+
+ public LeavesPayload(ResourceLocation location, FriendlyByteBuf buf) {
+ this(new FriendlyByteBuf(buf.readBytes(buf.readableBytes())), location);
+ }
+
+ @Override
+ public void write(FriendlyByteBuf buf) {
+ buf.writeBytes(data);
+ }
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolHandler.java b/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..d696f001d2576d1b61cc732c81f22eb52205072b
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolHandler.java
@@ -0,0 +1,65 @@
+package top.leavesmc.leaves.protocol.core;
+
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+public class ProtocolHandler {
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Init {
+
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface PayloadReceiver {
+
+ Class<? extends CustomPacketPayload> payload();
+
+ String[] payloadIds() default {};
+
+ String payloadId() default "";
+
+ boolean ignoreId() default false;
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Ticker {
+ int delay() default 0;
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface PlayerJoin {
+
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface PlayerLeave {
+
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface ReloadServer {
+
+ }
+
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface MinecraftRegister {
+
+ String channelId() default "";
+
+ String[] channelIds() default {};
+
+ boolean ignoreId() default false;
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolUtils.java b/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..5282c5ad3d26d06ab685ddaaf6fd9a4d49559717
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolUtils.java
@@ -0,0 +1,36 @@
+package top.leavesmc.leaves.protocol.core;
+
+import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.level.ServerPlayer;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.function.Consumer;
+
+public class ProtocolUtils {
+
+ public static void sendEmptyPayloadPacket(ServerPlayer player, ResourceLocation id) {
+ player.connection.send(new ClientboundCustomPayloadPacket(new LeavesProtocolManager.EmptyPayload(id)));
+ }
+
+ public static void sendPayloadPacket(ServerPlayer player, ResourceLocation id, Consumer<FriendlyByteBuf> consumer) {
+ player.connection.send(new ClientboundCustomPayloadPacket(new CustomPacketPayload() {
+ @Override
+ public void write(@NotNull FriendlyByteBuf buf) {
+ consumer.accept(buf);
+ }
+
+ @Override
+ @NotNull
+ public ResourceLocation id() {
+ return id;
+ }
+ }));
+ }
+
+ public static void sendPayloadPacket(ServerPlayer player, CustomPacketPayload payload) {
+ player.connection.send(new ClientboundCustomPayloadPacket(payload));
+ }
+}

View File

@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 16:08:46 +0800
From: MrHua269 <novau233@163.com>
Date: Thu, 20 Jun 2024 04:46:56 +0000
Subject: [PATCH] Pufferfish Improve container checking with a bitset
@@ -160,7 +160,7 @@ index 241fec02e6869c638d3a160819b32173a081467b..6a8f9e8f5bf108674c47018def28906e
public int getContainerSize() {
return this.container1.getContainerSize() + this.container2.getContainerSize();
diff --git a/src/main/java/net/minecraft/world/Container.java b/src/main/java/net/minecraft/world/Container.java
index d6cbe98e67fdbf8db46338a88ab1356dd63b50a3..20dd3a63b2f955b05a75eb240e33ae4cf6aef28f 100644
index f402dbbfe3a443e6bc51f88b85abe937852b52f0..541cb29a10e2c87a8214ff5beadb71bc1922d353 100644
--- a/src/main/java/net/minecraft/world/Container.java
+++ b/src/main/java/net/minecraft/world/Container.java
@@ -3,6 +3,8 @@ package net.minecraft.world;
@@ -234,13 +234,13 @@ index d6cbe98e67fdbf8db46338a88ab1356dd63b50a3..20dd3a63b2f955b05a75eb240e33ae4c
+ }
+ // Pufferfish end
int LARGE_MAX_STACK_SIZE = 64;
int DEFAULT_DISTANCE_LIMIT = 8;
float DEFAULT_DISTANCE_BUFFER = 4.0F;
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
index 00187fbbeddfc17e1b6887f8bf0f50da23938470..f64edfdb03f99624daf1e05b5dc86d845c3018b6 100644
index 9549eee0d92f322bd5232abd7e695213660c2e22..2cd8ac8840c2c0346fbf209c5ae3bb67eb3905e8 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
@@ -27,7 +27,10 @@ import org.bukkit.inventory.InventoryHolder;
@@ -30,7 +30,10 @@ import org.bukkit.inventory.InventoryHolder;
public abstract class AbstractMinecartContainer extends AbstractMinecart implements ContainerEntity {
@@ -249,9 +249,9 @@ index 00187fbbeddfc17e1b6887f8bf0f50da23938470..f64edfdb03f99624daf1e05b5dc86d84
+ private gg.airplane.structs.ItemListWithBitset itemStacksOptimized;
+ // Pufferfish end
@Nullable
public ResourceLocation lootTable;
public ResourceKey<LootTable> lootTable;
public long lootTableSeed;
@@ -89,12 +92,18 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
@@ -86,12 +89,18 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
protected AbstractMinecartContainer(EntityType<?> type, Level world) {
super(type, world);
@@ -272,22 +272,47 @@ index 00187fbbeddfc17e1b6887f8bf0f50da23938470..f64edfdb03f99624daf1e05b5dc86d84
}
@Override
@@ -156,6 +165,10 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
@@ -158,6 +167,10 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
@Override
protected void readAdditionalSaveData(CompoundTag nbt) {
super.readAdditionalSaveData(nbt);
this.lootableData.loadNbt(nbt); // Paper
+ // Pufferfish start
+ this.itemStacksOptimized = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize());
+ this.itemStacks = this.itemStacksOptimized.nonNullList;
+ // Pufferfish end
this.readChestVehicleSaveData(nbt);
this.readChestVehicleSaveData(nbt, this.registryAccess());
}
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
index 2ddf349fde5b310ec3f74baee1f3d33e09d5286c..b87a4781a4b567e939057ba7528a54868562ee33 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
@@ -119,19 +119,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
@Override
public boolean isEmpty() {
- Iterator iterator = this.getItems().iterator();
-
- ItemStack itemstack;
-
- do {
- if (!iterator.hasNext()) {
- return true;
- }
-
- itemstack = (ItemStack) iterator.next();
- } while (itemstack.isEmpty());
-
- return false;
+ return this.isCompletelyEmpty(null); // Pufferfish - use super
}
@Override
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
index a71414397bd45ee7bcacfeef0041d80dfa25f114..d66806565770cb03a21794f99e5c4b0f3040b26a 100644
index b88aa184cd06a0485146f58a5b61a56a50911209..7b64c57795fe27d8397500bfa41f71f9d2103b20 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
@@ -31,7 +31,10 @@ import org.bukkit.entity.HumanEntity;
@@ -32,7 +32,10 @@ import org.bukkit.entity.HumanEntity;
public class ChestBlockEntity extends RandomizableContainerBlockEntity implements LidBlockEntity {
private static final int EVENT_SET_OPEN_COUNT = 1;
@@ -298,7 +323,7 @@ index a71414397bd45ee7bcacfeef0041d80dfa25f114..d66806565770cb03a21794f99e5c4b0f
public final ContainerOpenersCounter openersCounter;
private final ChestLidController chestLidController;
@@ -65,9 +68,13 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
@@ -66,9 +69,13 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
}
// CraftBukkit end
@@ -313,7 +338,7 @@ index a71414397bd45ee7bcacfeef0041d80dfa25f114..d66806565770cb03a21794f99e5c4b0f
this.openersCounter = new ContainerOpenersCounter() {
@Override
protected void onOpen(Level world, BlockPos pos, BlockState state) {
@@ -98,6 +105,23 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
@@ -99,6 +106,23 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
this.chestLidController = new ChestLidController();
}
@@ -337,46 +362,46 @@ index a71414397bd45ee7bcacfeef0041d80dfa25f114..d66806565770cb03a21794f99e5c4b0f
public ChestBlockEntity(BlockPos pos, BlockState state) {
this(BlockEntityType.CHEST, pos, state);
}
@@ -115,7 +139,10 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
@@ -116,7 +140,10 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registryLookup) {
super.loadAdditional(nbt, registryLookup);
- this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY);
+ // Pufferfish start
+ this.optimizedItems = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize());
+ this.items = this.optimizedItems.nonNullList;
+ // Pufferfish end
if (!this.tryLoadLootTable(nbt)) {
ContainerHelper.loadAllItems(nbt, this.items);
ContainerHelper.loadAllItems(nbt, this.items, registryLookup);
}
@@ -187,7 +214,10 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
@@ -188,7 +215,10 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
@Override
protected void setItems(NonNullList<ItemStack> list) {
- this.items = list;
protected void setItems(NonNullList<ItemStack> inventory) {
- this.items = inventory;
+ // Pufferfish start
+ this.optimizedItems = gg.airplane.structs.ItemListWithBitset.fromList(list);
+ this.optimizedItems = gg.airplane.structs.ItemListWithBitset.fromList(inventory);
+ this.items = this.optimizedItems.nonNullList;
+ // Pufferfish end
}
@Override
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index 72779080969fe9f058c19533ffc9dad5f9c47086..c90d578643490709936545ee9cbd41c8671eeb7a 100644
index 779ffcf390d1ebdf37653454063d3c7d1fc35875..e56034e6dd674637321382e23e05ce41f6ab1d05 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -47,7 +47,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
public static final int MOVE_ITEM_SPEED = 8;
public static final int HOPPER_CONTAINER_SIZE = 5;
private static final int[][] CACHED_SLOTS = new int[54][];
+ // Pufferfish start
private NonNullList<ItemStack> items;
+ private gg.airplane.structs.ItemListWithBitset optimizedItems; // Pufferfish
+ // Pufferfish end
private int cooldownTime;
private long tickedGameTime;
@@ -83,14 +86,37 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
public int cooldownTime;
private long tickedGameTime = Long.MIN_VALUE; // Folia - region threading
private Direction facing;
@@ -94,15 +97,38 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
public HopperBlockEntity(BlockPos pos, BlockState state) {
super(BlockEntityType.HOPPER, pos, state);
@@ -386,6 +411,7 @@ index 72779080969fe9f058c19533ffc9dad5f9c47086..c90d578643490709936545ee9cbd41c8
+ this.items = this.optimizedItems.nonNullList;
+ // Pufferfish end
this.cooldownTime = -1;
this.facing = (Direction) state.getValue(HopperBlock.FACING);
}
+ // Pufferfish start
@@ -406,38 +432,25 @@ index 72779080969fe9f058c19533ffc9dad5f9c47086..c90d578643490709936545ee9cbd41c8
+ // Pufferfish end
+
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registryLookup) {
super.loadAdditional(nbt, registryLookup);
- this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY);
+ // Pufferfish start
+ this.optimizedItems = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize());
+ this.items = this.optimizedItems.nonNullList;
+ // Pufferfish end
if (!this.tryLoadLootTable(nbt)) {
ContainerHelper.loadAllItems(nbt, this.items);
ContainerHelper.loadAllItems(nbt, this.items, registryLookup);
}
@@ -493,6 +519,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -542,6 +568,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
private static boolean isFullContainer(Container inventory, Direction direction) {
+ if (true) return inventory.isCompletelyFull(direction); // Pufferfish - use bitsets
// Paper start - optimize hoppers
if (inventory instanceof WorldlyContainer worldlyContainer) {
for (final int slot : worldlyContainer.getSlotsForFace(direction)) {
@@ -515,7 +542,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
private static boolean isEmptyContainer(Container inv, Direction facing) {
- return allMatch(inv, facing, IS_EMPTY_TEST);
+ // Paper start
+ // Pufferfish start - use bitsets
+ //return allMatch(inv, facing, IS_EMPTY_TEST);
+ return inv.isCompletelyEmpty(facing);
+ // Pufferfish end
}
public static boolean suckInItems(Level world, Hopper hopper) {
@@ -716,7 +747,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
int[] aint = HopperBlockEntity.getSlots(inventory, direction);
int[] aint1 = aint;
int i = aint.length;
@@ -745,7 +772,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (HopperBlockEntity.canPlaceItemInContainer(to, stack, slot, side)) {
boolean flag = false;
@@ -446,33 +459,15 @@ index 72779080969fe9f058c19533ffc9dad5f9c47086..c90d578643490709936545ee9cbd41c8
if (itemstack1.isEmpty()) {
// Spigot start - SPIGOT-6693, InventorySubcontainer#setItem
@@ -911,7 +942,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -933,7 +960,10 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@Override
protected void setItems(NonNullList<ItemStack> list) {
- this.items = list;
protected void setItems(NonNullList<ItemStack> inventory) {
- this.items = inventory;
+ // Pufferfish start
+ this.optimizedItems = gg.airplane.structs.ItemListWithBitset.fromList(list);
+ this.optimizedItems = gg.airplane.structs.ItemListWithBitset.fromList(inventory);
+ this.items = this.optimizedItems.nonNullList;
+ // Pufferfish end
}
public static void entityInside(Level world, BlockPos pos, BlockState state, Entity entity, HopperBlockEntity blockEntity) {
diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
index 3e638f12956e57548f76c7e2403ba370f7baa249..02364a148b347e3669275553004391e31d77c0b5 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
@@ -96,12 +96,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
public boolean isEmpty() {
this.unpackLootTable((Player)null);
// Paper start
- for (final ItemStack itemStack : this.getItems()) {
- if (!itemStack.isEmpty()) {
- return false;
- }
- }
- return true;
+ return this.isCompletelyEmpty(null); // Pufferfish - use super
// Paper end
}

View File

@@ -1,709 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 17 Dec 2023 21:01:59 +0800
Subject: [PATCH] Leaves PCA sync protocol
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index a62680768068b611fe723fedeb617d42c643e59e..cfe9a8eb705039ee7e2dc9262e1355c4b0f664bb 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -66,6 +66,10 @@ public class LuminolConfig {
public static boolean enableAsyncMobSpawning = false;
public static boolean useAlternateKeepAlive = false;
+ public static boolean pcaSyncProtocol = false;
+ public static String pcaSyncPlayerEntity = "NOBODY";
+
+
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -194,6 +198,9 @@ public class LuminolConfig {
enableAsyncMobSpawning = get("optimizations.enable_async_mob_spawning",enableAsyncMobSpawning);
RegionizedWorldData.initMobSpawningExecutor();
useAlternateKeepAlive = get("optimizations.enable_alternative_keep_alive_handling",useAlternateKeepAlive,"Enabling this sends a keepalive packet once per second to a player, and only kicks for timeout if none of them were responded to in 30 seconds. Responding to any of them in any order will keep the player connected. AKA, it won't kick your players because one packet gets dropped somewhere along the lines(From purpur)");
+
+ pcaSyncProtocol = get("gameplay.enable_pca_sync_protocol",pcaSyncProtocol);
+ pcaSyncPlayerEntity = get("gameplay.pca_sync_player_entity",pcaSyncPlayerEntity,"Available values: NOBODY,EVERYBODY,OPS,OPS_AND_SELF");
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
index a0628b9d74c29d02bfba583edf7ee6f2cde2cff6..698c7bfddb0d45d088c30fd26eccb86b924fd60a 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
@@ -373,6 +373,11 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
@Override
public void containerChanged(Container sender) {
+ // Leaves start - pca
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
+ }
+ // Leaves end - pca
boolean flag = this.isSaddled();
this.updateContainerEquipment();
diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
index ce728f062794e239d1dfdf842d7d0c725f77fba7..a3200593788525c7f18420036044bfdccfaf40fc 100644
--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
@@ -64,6 +64,15 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa
super(type, world);
this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 16.0F);
this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, -1.0F);
+ // Leaves start - pca
+ if (!this.level().isClientSide()) {
+ this.inventory.addListener(inventory -> {
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
+ }
+ });
+ }
+ // Leaves end - pca
}
@Override
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
index f64edfdb03f99624daf1e05b5dc86d845c3018b6..e98ea5f93a829e232a61eee4564209d1831f8b8d 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
@@ -138,7 +138,13 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
}
@Override
- public void setChanged() {}
+ public void setChanged() {
+ // Leaves start - pca
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
+ }
+ // Leaves end - pca
+ }
@Override
public boolean stillValid(Player player) {
diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
index a18aadbf7ae83713e1f2b21553185d8000bc7699..4b174bed02fb98f798f9444e03fc866baf1e1a07 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
@@ -569,6 +569,16 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
}
+ // Leaves start - pca
+ @Override
+ public void setChanged() {
+ super.setChanged();
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
+ }
+ }
+ // Leaves end - pca
+
@Override
public boolean stillValid(net.minecraft.world.entity.player.Player player) {
return Container.stillValidBlockEntity(this, player);
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
index 416aa989ebb18a8741cc9d605a1180ab830f6643..b73c3dc28a95279285e911bfed3bc3d3f038e6db 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
@@ -131,6 +131,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
this.items = list;
}
+ // Leaves start - pca
+ @Override
+ public void setChanged() {
+ super.setChanged();
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
+ }
+ }
+ // Leaves end - pca
+
@Override
protected Component getDefaultName() {
return Component.translatable("container.barrel");
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
index cf09525efd2d53bf884cd6ec3b0b9229715895eb..9c7b5fbec4ec1eb6b39f139a9b16483208249b6f 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
@@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -127,6 +128,11 @@ public class BeehiveBlockEntity extends BlockEntity {
super.setChanged();
}
+ // Leaves start - pca
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
+ }
+ // Leaves end - pca
return list;
}
@@ -188,6 +194,12 @@ public class BeehiveBlockEntity extends BlockEntity {
this.level.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entity, this.getBlockState()));
}
+ // Leaves start - pca
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
+ }
+ // Leaves end - pca
+
entity.discard();
super.setChanged();
}
@@ -334,6 +346,11 @@ public class BeehiveBlockEntity extends BlockEntity {
if (BeehiveBlockEntity.releaseOccupant(world, pos, state, tileentitybeehive_hivebee, (List) null, tileentitybeehive_releasestatus, flowerPos)) {
flag = true;
iterator.remove();
+ // Leaves start - pca
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(Objects.requireNonNull(world.getBlockEntity(pos)));
+ }
+ // Leaves end - pca
// CraftBukkit start
} else {
tileentitybeehive_hivebee.exitTickCounter = tileentitybeehive_hivebee.minOccupationTicks / 2; // Not strictly Vanilla behaviour in cases where bees cannot spawn but still reasonable // Paper - use exitTickCounter to keep actual bee life
@@ -385,6 +402,11 @@ public class BeehiveBlockEntity extends BlockEntity {
this.maxBees = nbt.getInt("Bukkit.MaxEntities");
}
// CraftBukkit end
+ // Leaves start - pca
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
+ }
+ // Leaves end - pca
}
@Override
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
index 526d1bfd5ad0de7bcfd0c2da902515f3dec94c54..66758af67aca2c726b2f5b451f3f7197102af22f 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
@@ -333,6 +333,16 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements
}
+ // Leaves start - pca
+ @Override
+ public void setChanged() {
+ super.setChanged();
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
+ }
+ }
+ // Leaves end - pca
+
@Override
public boolean stillValid(Player player) {
return Container.stillValidBlockEntity(this, player);
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
index d66806565770cb03a21794f99e5c4b0f3040b26a..034bc37a8b50a3c9904f4f53c8758b1b02b458b1 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
@@ -220,6 +220,16 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
// Pufferfish end
}
+ // Leaves start - pca
+ @Override
+ public void setChanged() {
+ super.setChanged();
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
+ }
+ }
+ // Leaves end - pca
+
@Override
public float getOpenNess(float tickDelta) {
return this.chestLidController.getOpenness(tickDelta);
diff --git a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
index 881379681c39230a00b3a1f11cd87498984396c7..51fae4d72eed9e4224a8abe1a0b6520835857ba5 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
@@ -92,6 +92,16 @@ public class DispenserBlockEntity extends RandomizableContainerBlockEntity {
return -1;
}
+ // Leaves start - pca
+ @Override
+ public void setChanged() {
+ super.setChanged();
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
+ }
+ }
+ // Leaves end - pca
+
@Override
protected Component getDefaultName() {
return Component.translatable("container.dispenser");
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index c90d578643490709936545ee9cbd41c8671eeb7a..3527a3cc76d3b1ad1319f1eebe31fd4d9e8aa039 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -155,6 +155,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
+ // Leaves start - pca
+ @Override
+ public void setChanged() {
+ super.setChanged();
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
+ }
+ }
+ // Leaves end - pca
+
@Override
protected Component getDefaultName() {
return Component.translatable("container.hopper");
@@ -234,6 +244,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (flag) {
blockEntity.setCooldown(world.spigotConfig.hopperTransfer); // Spigot
setChanged(world, pos, state);
+ // Leaves start - pca
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(blockEntity);
+ }
+ // Leaves end - pca
return true;
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
index 1fa22445a4ecc8c08dbcf0cc6bd39dc5003604c4..c1492fce06cdc00a8e82977f0c474a541efa39e8 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
@@ -269,6 +269,16 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl
this.itemStacks = list;
}
+ // Leaves start - pca
+ @Override
+ public void setChanged() {
+ super.setChanged();
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
+ }
+ }
+ // Leaves end - pca
+
@Override
public int[] getSlotsForFace(Direction side) {
return ShulkerBoxBlockEntity.SLOTS;
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index b23e43f7ac22bc106a0bcde4a8bca9ecba1a9ae4..08bf4f13e0ee6698b18a6946cb78adb4ae65c852 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -45,7 +45,7 @@ import org.bukkit.scheduler.BukkitWorker;
*/
public class CraftScheduler implements BukkitScheduler {
- static Plugin MINECRAFT = new MinecraftInternalPlugin();
+ public static Plugin MINECRAFT = new MinecraftInternalPlugin();
/**
* The start ID for the counter.
*/
diff --git a/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
new file mode 100644
index 0000000000000000000000000000000000000000..ebd28033ddf0fe6a354585dc2818a9b481d90ed4
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
@@ -0,0 +1,384 @@
+package top.leavesmc.leaves.protocol;
+
+import net.minecraft.core.BlockPos;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.ChestBlock;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.block.state.properties.ChestType;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.logging.log4j.LogManager;
+import org.bukkit.craftbukkit.scheduler.CraftScheduler;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import top.leavesmc.leaves.protocol.core.LeavesProtocol;
+import top.leavesmc.leaves.protocol.core.ProtocolHandler;
+import top.leavesmc.leaves.protocol.core.ProtocolUtils;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
+
+import static org.bukkit.craftbukkit.scheduler.CraftScheduler.MINECRAFT;
+import static top.leavesmc.leaves.protocol.core.LeavesProtocolManager.EmptyPayload;
+
+@LeavesProtocol(namespace = "pca")
+public class PcaSyncProtocol {
+
+ public static final String PROTOCOL_ID = "pca";
+
+ public static final ReentrantLock lock = new ReentrantLock(true);
+ public static final ReentrantLock pairLock = new ReentrantLock(true);
+
+ // send
+ private static final ResourceLocation ENABLE_PCA_SYNC_PROTOCOL = id("enable_pca_sync_protocol");
+ private static final ResourceLocation DISABLE_PCA_SYNC_PROTOCOL = id("disable_pca_sync_protocol");
+ private static final ResourceLocation UPDATE_ENTITY = id("update_entity");
+ private static final ResourceLocation UPDATE_BLOCK_ENTITY = id("update_block_entity");
+
+ private static final Map<ServerPlayer, Pair<ResourceLocation, BlockPos>> playerWatchBlockPos = new HashMap<>();
+ private static final Map<ServerPlayer, Pair<ResourceLocation, Entity>> playerWatchEntity = new HashMap<>();
+ private static final Map<Pair<ResourceLocation, BlockPos>, Set<ServerPlayer>> blockPosWatchPlayerSet = new HashMap<>();
+ private static final Map<Pair<ResourceLocation, Entity>, Set<ServerPlayer>> entityWatchPlayerSet = new HashMap<>();
+ private static final MutablePair<ResourceLocation, Entity> ResourceLocationEntityPair = new MutablePair<>();
+ private static final MutablePair<ResourceLocation, BlockPos> ResourceLocationBlockPosPair = new MutablePair<>();
+
+ @Contract("_ -> new")
+ public static @NotNull ResourceLocation id(String path) {
+ return new ResourceLocation(PROTOCOL_ID, path);
+ }
+
+ @ProtocolHandler.PlayerJoin
+ private static void onJoin(ServerPlayer player) {
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ enablePcaSyncProtocol(player);
+ }
+ }
+
+ @ProtocolHandler.ReloadServer
+ private static void onServerReload() {
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ enablePcaSyncProtocolGlobal();
+ } else {
+ disablePcaSyncProtocolGlobal();
+ }
+ }
+
+ @ProtocolHandler.PayloadReceiver(payload = EmptyPayload.class, payloadId = "cancel_sync_block_entity")
+ private static void cancelSyncBlockEntityHandler(ServerPlayer player, EmptyPayload payload) {
+ if (!me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ return;
+ }
+ PcaSyncProtocol.clearPlayerWatchBlock(player);
+ }
+
+ @ProtocolHandler.PayloadReceiver(payload = EmptyPayload.class, payloadId = "cancel_sync_entity")
+ private static void cancelSyncEntityHandler(ServerPlayer player, EmptyPayload payload) {
+ if (!me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ return;
+ }
+ PcaSyncProtocol.clearPlayerWatchEntity(player);
+ }
+
+ @ProtocolHandler.PayloadReceiver(payload = SyncBlockEntityPayload.class, payloadId = "sync_block_entity")
+ private static void syncBlockEntityHandler(ServerPlayer player, SyncBlockEntityPayload payload) {
+ if (!me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ return;
+ }
+ MinecraftServer server = MinecraftServer.getServer();
+ BlockPos pos = payload.pos;
+ ServerLevel world = player.serverLevel();
+
+ player.getBukkitEntity().getScheduler().execute(MINECRAFT,() -> {
+ BlockState blockState = world.getBlockState(pos);
+ clearPlayerWatchData(player);
+
+ BlockEntity blockEntityAdj = null;
+ if (blockState.getBlock() instanceof ChestBlock) {
+ if (blockState.getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
+ BlockPos posAdj = pos.offset(ChestBlock.getConnectedDirection(blockState).getNormal());
+ // The method in World now checks that the caller is from the same thread...
+ blockEntityAdj = world.getChunk(posAdj).getBlockEntity(posAdj);
+ }
+ }
+
+ if (blockEntityAdj != null) {
+ updateBlockEntity(player, blockEntityAdj);
+ }
+
+ // The method in World now checks that the caller is from the same thread...
+ BlockEntity blockEntity = world.getChunk(pos).getBlockEntity(pos);
+ if (blockEntity != null) {
+ updateBlockEntity(player, blockEntity);
+ }
+
+ Pair<ResourceLocation, BlockPos> pair = new ImmutablePair<>(player.level().dimension().location(), pos);
+ lock.lock();
+ playerWatchBlockPos.put(player, pair);
+ if (!blockPosWatchPlayerSet.containsKey(pair)) {
+ blockPosWatchPlayerSet.put(pair, new HashSet<>());
+ }
+ blockPosWatchPlayerSet.get(pair).add(player);
+ lock.unlock();
+ },null,1);
+ }
+
+ @ProtocolHandler.PayloadReceiver(payload = SyncEntityPayload.class, payloadId = "sync_entity")
+ private static void syncEntityHandler(ServerPlayer player, SyncEntityPayload payload) {
+ if (!me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
+ return;
+ }
+ MinecraftServer server = MinecraftServer.getServer();
+ int entityId = payload.entityId;
+ ServerLevel world = player.serverLevel();
+ player.getBukkitEntity().getScheduler().execute(MINECRAFT,() -> {
+ Entity entity = world.getEntity(entityId);
+ if (entity != null) {
+ clearPlayerWatchData(player);
+ if (entity instanceof Player) {
+ if (me.earthme.luminol.LuminolConfig.pcaSyncPlayerEntity.equals("NOBODY")) {
+ return;
+ }else if (me.earthme.luminol.LuminolConfig.pcaSyncPlayerEntity.equals("OPS")) {
+ if (server.getProfilePermissions(player.getGameProfile()) < 2) {
+ return;
+ }
+ } else if (me.earthme.luminol.LuminolConfig.pcaSyncPlayerEntity.equals("OPS_AND_SELF")) {
+ if (server.getProfilePermissions(player.getGameProfile()) < 2 &&
+ entity != player) {
+ return;
+ }
+ } else if (!me.earthme.luminol.LuminolConfig.pcaSyncPlayerEntity.equals("EVERYONE")) {
+ // wtf????
+ LogManager.getLogger().warn("pcaSyncPlayerEntity wtf???");
+ return;
+ }
+ }
+ updateEntity(player, entity);
+
+ Pair<ResourceLocation, Entity> pair = new ImmutablePair<>(entity.level().dimension().location(), entity);
+ lock.lock();
+ playerWatchEntity.put(player, pair);
+ if (!entityWatchPlayerSet.containsKey(pair)) {
+ entityWatchPlayerSet.put(pair, new HashSet<>());
+ }
+ entityWatchPlayerSet.get(pair).add(player);
+ lock.unlock();
+ }
+ },null,1);
+ }
+
+ public static void enablePcaSyncProtocol(@NotNull ServerPlayer player) {
+ ProtocolUtils.sendEmptyPayloadPacket(player, ENABLE_PCA_SYNC_PROTOCOL);
+ }
+
+ public static void disablePcaSyncProtocol(@NotNull ServerPlayer player) {
+ ProtocolUtils.sendEmptyPayloadPacket(player, DISABLE_PCA_SYNC_PROTOCOL);
+ }
+
+ public static void updateEntity(@NotNull ServerPlayer player, @NotNull Entity entity) {
+ CompoundTag nbt = entity.saveWithoutId(new CompoundTag());
+ ProtocolUtils.sendPayloadPacket(player, UPDATE_ENTITY, buf -> {
+ buf.writeResourceLocation(entity.level().dimension().location());
+ buf.writeInt(entity.getId());
+ buf.writeNbt(nbt);
+ });
+ }
+
+ public static void updateBlockEntity(@NotNull ServerPlayer player, @NotNull BlockEntity blockEntity) {
+ Level world = blockEntity.getLevel();
+
+ if (world == null) {
+ return;
+ }
+
+ ProtocolUtils.sendPayloadPacket(player, UPDATE_BLOCK_ENTITY, buf -> {
+ buf.writeResourceLocation(world.dimension().location());
+ buf.writeBlockPos(blockEntity.getBlockPos());
+ buf.writeNbt(blockEntity.saveWithId());
+ });
+ }
+
+ private static MutablePair<ResourceLocation, Entity> getResourceLocationEntityPair(ResourceLocation ResourceLocation, Entity entity) {
+ pairLock.lock();
+ ResourceLocationEntityPair.setLeft(ResourceLocation);
+ ResourceLocationEntityPair.setRight(entity);
+ pairLock.unlock();
+ return ResourceLocationEntityPair;
+ }
+
+ private static MutablePair<ResourceLocation, BlockPos> getResourceLocationBlockPosPair(ResourceLocation ResourceLocation, BlockPos pos) {
+ pairLock.lock();
+ ResourceLocationBlockPosPair.setLeft(ResourceLocation);
+ ResourceLocationBlockPosPair.setRight(pos);
+ pairLock.unlock();
+ return ResourceLocationBlockPosPair;
+ }
+
+ private static @Nullable Set<ServerPlayer> getWatchPlayerList(@NotNull Entity entity) {
+ return entityWatchPlayerSet.get(getResourceLocationEntityPair(entity.level().dimension().location(), entity));
+ }
+
+ private static @Nullable Set<ServerPlayer> getWatchPlayerList(@NotNull Level world, @NotNull BlockPos blockPos) {
+ return blockPosWatchPlayerSet.get(getResourceLocationBlockPosPair(world.dimension().location(), blockPos));
+ }
+
+ public static boolean syncEntityToClient(@NotNull Entity entity) {
+ if (entity.level().isClientSide()) {
+ return false;
+ }
+ lock.lock();
+ Set<ServerPlayer> playerList = getWatchPlayerList(entity);
+ boolean ret = false;
+ if (playerList != null) {
+ for (ServerPlayer player : playerList) {
+ updateEntity(player, entity);
+ ret = true;
+ }
+ }
+ lock.unlock();
+ return ret;
+ }
+
+ public static boolean syncBlockEntityToClient(@NotNull BlockEntity blockEntity) {
+ boolean ret = false;
+ Level world = blockEntity.getLevel();
+ BlockPos pos = blockEntity.getBlockPos();
+ if (world != null) {
+ if (world.isClientSide()) {
+ return false;
+ }
+ BlockState blockState = world.getBlockState(pos);
+ lock.lock();
+ Set<ServerPlayer> playerList = getWatchPlayerList(world, blockEntity.getBlockPos());
+
+ Set<ServerPlayer> playerListAdj = null;
+
+ if (blockState.getBlock() instanceof ChestBlock) {
+ if (blockState.getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
+ BlockPos posAdj = pos.offset(ChestBlock.getConnectedDirection(blockState).getNormal());
+ playerListAdj = getWatchPlayerList(world, posAdj);
+ }
+ }
+ if (playerListAdj != null) {
+ if (playerList == null) {
+ playerList = playerListAdj;
+ } else {
+ playerList.addAll(playerListAdj);
+ }
+ }
+
+ if (playerList != null) {
+ for (ServerPlayer player : playerList) {
+ updateBlockEntity(player, blockEntity);
+ ret = true;
+ }
+ }
+ lock.unlock();
+ }
+ return ret;
+ }
+
+ private static void clearPlayerWatchEntity(ServerPlayer player) {
+ lock.lock();
+ Pair<ResourceLocation, Entity> pair = playerWatchEntity.get(player);
+ if (pair != null) {
+ Set<ServerPlayer> playerSet = entityWatchPlayerSet.get(pair);
+ playerSet.remove(player);
+ if (playerSet.isEmpty()) {
+ entityWatchPlayerSet.remove(pair);
+ }
+ playerWatchEntity.remove(player);
+ }
+ lock.unlock();
+ }
+
+ private static void clearPlayerWatchBlock(ServerPlayer player) {
+ lock.lock();
+ Pair<ResourceLocation, BlockPos> pair = playerWatchBlockPos.get(player);
+ if (pair != null) {
+ Set<ServerPlayer> playerSet = blockPosWatchPlayerSet.get(pair);
+ playerSet.remove(player);
+ if (playerSet.isEmpty()) {
+ blockPosWatchPlayerSet.remove(pair);
+ }
+ playerWatchBlockPos.remove(player);
+ }
+ lock.unlock();
+ }
+
+ public static void disablePcaSyncProtocolGlobal() {
+ lock.lock();
+ playerWatchBlockPos.clear();
+ playerWatchEntity.clear();
+ blockPosWatchPlayerSet.clear();
+ entityWatchPlayerSet.clear();
+ lock.unlock();
+ for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) {
+ disablePcaSyncProtocol(player);
+ }
+ }
+
+ public static void enablePcaSyncProtocolGlobal() {
+ for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) {
+ enablePcaSyncProtocol(player);
+ }
+ }
+
+
+ public static void clearPlayerWatchData(ServerPlayer player) {
+ PcaSyncProtocol.clearPlayerWatchBlock(player);
+ PcaSyncProtocol.clearPlayerWatchEntity(player);
+ }
+
+ public record SyncBlockEntityPayload(BlockPos pos) implements CustomPacketPayload {
+
+ public static final ResourceLocation SYNC_BLOCK_ENTITY = PcaSyncProtocol.id("sync_block_entity");
+
+ public SyncBlockEntityPayload(ResourceLocation id, FriendlyByteBuf buf) {
+ this(buf.readBlockPos());
+ }
+
+ @Override
+ public void write(FriendlyByteBuf buf) {
+ buf.writeBlockPos(pos);
+ }
+
+ @Override
+ public @NotNull ResourceLocation id() {
+ return SYNC_BLOCK_ENTITY;
+ }
+ }
+
+ public record SyncEntityPayload(int entityId) implements CustomPacketPayload {
+
+ public static final ResourceLocation SYNC_ENTITY = PcaSyncProtocol.id("sync_entity");
+
+ public SyncEntityPayload(ResourceLocation id, FriendlyByteBuf buf) {
+ this(buf.readInt());
+ }
+
+ @Override
+ public void write(FriendlyByteBuf buf) {
+ buf.writeInt(entityId);
+ }
+
+ @Override
+ public @NotNull ResourceLocation id() {
+ return SYNC_ENTITY;
+ }
+ }
+}

View File

@@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Mon, 29 Jul 2024 19:53:42 +0800
Subject: [PATCH] Pufferfish Simpler ShapelessRecipes comparison for Vanilla
diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
index 3554109bcc4651ca93b6275c914e57e007e2204e..60c7a9520335de8e2638572100affcfdd776c5a3 100644
--- a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
+++ b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
@@ -27,8 +27,13 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo
final CraftingBookCategory category;
final ItemStack result;
final NonNullList<Ingredient> ingredients;
+ private final boolean isBukkit; // Pufferfish
+ // Pufferfish start
public ShapelessRecipe(String group, CraftingBookCategory category, ItemStack result, NonNullList<Ingredient> ingredients) {
+ this(group, category, result, ingredients, false);
+ }
+ public ShapelessRecipe(String group, CraftingBookCategory category, ItemStack result, NonNullList<Ingredient> ingredients, boolean isBukkit) { this.isBukkit = isBukkit; // Pufferfish end
this.group = group;
this.category = category;
this.result = result;
@@ -78,6 +83,28 @@ public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBoo
}
public boolean matches(CraftingContainer inventory, Level world) {
+ // Pufferfish start
+ if (!this.isBukkit) {
+ java.util.List<Ingredient> ingredients = com.google.common.collect.Lists.newArrayList(this.ingredients.toArray(new Ingredient[0]));
+
+ inventory: for (int index = 0; index < inventory.getContainerSize(); index++) {
+ ItemStack itemStack = inventory.getItem(index);
+
+ if (!itemStack.isEmpty()) {
+ for (int i = 0; i < ingredients.size(); i++) {
+ if (ingredients.get(i).test(itemStack)) {
+ ingredients.remove(i);
+ continue inventory;
+ }
+ }
+ return false;
+ }
+ }
+
+ return ingredients.isEmpty();
+ }
+ // Pufferfish end
+
StackedContents autorecipestackmanager = new StackedContents();
autorecipestackmanager.initialize(this); // Paper - better exact choice recipes
int i = 0;
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java
index 96d772eb02f79f8c478f5e6f065e387aa7665b18..c5ce412f321b8b4f31cc042893659e213b081f29 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java
@@ -45,6 +45,6 @@ public class CraftShapelessRecipe extends ShapelessRecipe implements CraftRecipe
data.set(i, this.toNMS(ingred.get(i), true));
}
- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.ShapelessRecipe(this.getGroup(), CraftRecipe.getCategory(this.getCategory()), CraftItemStack.asNMSCopy(this.getResult()), data)));
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.ShapelessRecipe(this.getGroup(), CraftRecipe.getCategory(this.getCategory()), CraftItemStack.asNMSCopy(this.getResult()), data, true))); // Pufferfish
}
}

View File

@@ -1,34 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 17:08:22 +0800
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 06:00:22 +0000
Subject: [PATCH] Gale Variable entity wake-up duration
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 4f6af1fa55047e7be9e57c1dd1c60e9d96d12187..793dc5b35e9a0665d486a74ce5b776b43b941ee2 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -56,6 +56,7 @@ public class LuminolConfig {
public static int startDistanceSquared;
public static int maximumActivationPrio;
public static int activationDistanceMod;
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/GaleVariableEntityWakeupConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/GaleVariableEntityWakeupConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa30e8dc39a2d4bd1399e41230b307b19eeb716a
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/GaleVariableEntityWakeupConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class GaleVariableEntityWakeupConfig implements IConfigModule {
+ @ConfigInfo(baseName = "entity_wakeup_duration_ratio_standard_deviation")
+ public static double entityWakeUpDurationRatioStandardDeviation = 0.2;
public static void init() throws IOException {
@@ -167,6 +168,7 @@ public class LuminolConfig {
maxProjectileLoadsPerTick = get("optimizations.projectile.max-loads-per-tick", maxProjectileLoadsPerTick, "Controls how many chunks are allowed \nto be sync loaded by projectiles in a tick.");
maxProjectileLoadsPerProjectile = get("optimizations.projectile.max-loads-per-projectile", maxProjectileLoadsPerProjectile, "Controls how many chunks a projectile \n can load in its lifetime before it gets \nautomatically removed.");
initDAB();
+ entityWakeUpDurationRatioStandardDeviation = get("optimizations.entity_wakeup_duration_ratio_standard_deviation",entityWakeUpDurationRatioStandardDeviation);
}
public static <T> T get(String key,T def){
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.OPTIMIZATIONS;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "variable_entity_waking_up";
+ }
+}
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
index e77e1c60a611c49489c65d66e54236a86c3093e3..51adf24b9274b6bc78ef94e77a0b2d73b1f2bbbb 100644
index 9628cc2b7f200e0bab4fed48997dde3e266200ee..3a6ae320891f1e3202c59b63a5f2c96c18727314 100644
--- a/src/main/java/org/spigotmc/ActivationRange.java
+++ b/src/main/java/org/spigotmc/ActivationRange.java
@@ -76,28 +76,40 @@ public class ActivationRange
@@ -75,28 +75,41 @@ public class ActivationRange
if (entity.activationType == ActivationType.VILLAGER) {
if (inactiveFor > config.wakeUpInactiveVillagersEvery && worldData.wakeupInactiveRemainingVillagers > 0) { // Folia - threaded regions
worldData.wakeupInactiveRemainingVillagers--; // Folia - threaded regions
@@ -59,10 +65,10 @@ index e77e1c60a611c49489c65d66e54236a86c3093e3..51adf24b9274b6bc78ef94e77a0b2d73
// Paper end
+ // Gale start - variable entity wake-up duration
+ private static final java.util.Random wakeUpDurationRandom = new java.util.Random();
+ private static final java.util.concurrent.ThreadLocalRandom wakeUpDurationRandom = java.util.concurrent.ThreadLocalRandom.current();
+
+ private static int getWakeUpDurationWithVariance(Entity entity, int wakeUpDuration) {
+ double deviation = LuminolConfig.entityWakeUpDurationRatioStandardDeviation;
+ double deviation = me.earthme.luminol.config.modules.optimizations.GaleVariableEntityWakeupConfig.entityWakeUpDurationRatioStandardDeviation;
+ if (deviation <= 0) {
+ return wakeUpDuration;
+ }
@@ -70,6 +76,7 @@ index e77e1c60a611c49489c65d66e54236a86c3093e3..51adf24b9274b6bc78ef94e77a0b2d73
+ }
+ // Gale end - variable entity wake-up duration
+
static AABB maxBB = new AABB( 0, 0, 0, 0, 0, 0 );
+
// Folia - threaded regions - replaced by local variable
/**

View File

@@ -1,183 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Thu, 21 Dec 2023 19:50:41 +0800
Subject: [PATCH] Leaves Bladeren protocol
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index cfe9a8eb705039ee7e2dc9262e1355c4b0f664bb..a0fd4fec133617893487586fd52e3a3a864871b4 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -68,6 +68,7 @@ public class LuminolConfig {
public static boolean pcaSyncProtocol = false;
public static String pcaSyncPlayerEntity = "NOBODY";
+ public static boolean bladerenLeavesProtocol = false;
public static void init() throws IOException {
@@ -201,6 +202,7 @@ public class LuminolConfig {
pcaSyncProtocol = get("gameplay.enable_pca_sync_protocol",pcaSyncProtocol);
pcaSyncPlayerEntity = get("gameplay.pca_sync_player_entity",pcaSyncPlayerEntity,"Available values: NOBODY,EVERYBODY,OPS,OPS_AND_SELF");
+ bladerenLeavesProtocol = get("gameplay.bladeren_leaves_protocol",bladerenLeavesProtocol);
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/top/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf344ad5e928f1bf23953d7b25c4636734da69e6
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java
@@ -0,0 +1,151 @@
+package top.leavesmc.leaves.protocol.bladeren;
+
+import com.google.common.collect.Maps;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.level.ServerPlayer;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import me.earthme.luminol.LuminolConfig;
+import top.leavesmc.leaves.protocol.core.LeavesProtocol;
+import top.leavesmc.leaves.protocol.core.ProtocolHandler;
+import top.leavesmc.leaves.protocol.core.ProtocolUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
+
+@LeavesProtocol(namespace = "bladeren")
+public class BladerenProtocol {
+
+ public static final String PROTOCOL_ID = "bladeren";
+ public static final String PROTOCOL_VERSION = "1.0.0";
+
+ private static final ResourceLocation HELLO_ID = id("hello");
+ private static final ResourceLocation FEATURE_MODIFY_ID = id("feature_modify");
+
+ private static final Map<String, BiConsumer<ServerPlayer, CompoundTag>> registeredFeatures = Maps.newConcurrentMap();
+
+ @Contract("_ -> new")
+ public static @NotNull ResourceLocation id(String path) {
+ return new ResourceLocation(PROTOCOL_ID, path);
+ }
+
+ @ProtocolHandler.PayloadReceiver(payload = BladerenHelloPayload.class, payloadId = "hello")
+ private static void handleHello(@NotNull ServerPlayer player, @NotNull BladerenHelloPayload payload) {
+ if (LuminolConfig.bladerenLeavesProtocol) {
+ String clientVersion = payload.version;
+ CompoundTag tag = payload.nbt;
+
+ if (tag != null) {
+ CompoundTag featureNbt = tag.getCompound("Features");
+ for (String name : featureNbt.getAllKeys()) {
+
+ final BiConsumer<ServerPlayer,CompoundTag> target = registeredFeatures.get(name);
+
+ if (target != null){
+ target.accept(player, featureNbt.getCompound(name));
+ }
+ }
+ }
+ }
+ }
+
+ @ProtocolHandler.PayloadReceiver(payload = BladerenFeatureModifyPayload.class, payloadId = "feature_modify")
+ private static void handleModify(@NotNull ServerPlayer player, @NotNull BladerenFeatureModifyPayload payload) {
+ if (LuminolConfig.bladerenLeavesProtocol) {
+ String name = payload.name;
+ CompoundTag tag = payload.nbt;
+
+ final BiConsumer<ServerPlayer,CompoundTag> target = registeredFeatures.get(name);
+
+ if (target != null){
+ target.accept(player, tag);
+ }
+ }
+ }
+
+ @ProtocolHandler.PlayerJoin
+ public static void onPlayerJoin(@NotNull ServerPlayer player) {
+ if (LuminolConfig.bladerenLeavesProtocol) {
+ CompoundTag tag = new CompoundTag();
+ LeavesFeatureSet.writeNBT(tag);
+ ProtocolUtils.sendPayloadPacket(player, new BladerenHelloPayload(PROTOCOL_VERSION, tag));
+ }
+ }
+
+ public static void registerFeature(String name, BiConsumer<ServerPlayer, CompoundTag> consumer) {
+ registeredFeatures.put(name, consumer);
+ }
+
+ public static class LeavesFeatureSet {
+
+ private static final Map<String, LeavesFeature> features = new HashMap<>();
+
+ public static void writeNBT(@NotNull CompoundTag tag) {
+ CompoundTag featureNbt = new CompoundTag();
+ features.values().forEach(feature -> feature.writeNBT(featureNbt));
+ tag.put("Features", featureNbt);
+ }
+
+ public static void register(LeavesFeature feature) {
+ features.put(feature.name, feature);
+ }
+ }
+
+ public record LeavesFeature(String name, String value) {
+
+ @NotNull
+ @Contract("_, _ -> new")
+ public static LeavesFeature of(String name, boolean value) {
+ return new LeavesFeature(name, Boolean.toString(value));
+ }
+
+ public void writeNBT(@NotNull CompoundTag rules) {
+ CompoundTag rule = new CompoundTag();
+ rule.putString("Feature", name);
+ rule.putString("Value", value);
+ rules.put(name, rule);
+ }
+ }
+
+ public record BladerenFeatureModifyPayload(String name, CompoundTag nbt) implements CustomPacketPayload {
+
+ public BladerenFeatureModifyPayload(ResourceLocation location, FriendlyByteBuf buf) {
+ this(buf.readUtf(), buf.readNbt());
+ }
+
+ @Override
+ public void write(@NotNull FriendlyByteBuf buf) {
+ buf.writeUtf(name);
+ buf.writeNbt(nbt);
+ }
+
+ @Override
+ @NotNull
+ public ResourceLocation id() {
+ return FEATURE_MODIFY_ID;
+ }
+ }
+
+ public record BladerenHelloPayload(String version, CompoundTag nbt) implements CustomPacketPayload {
+
+ public BladerenHelloPayload(ResourceLocation location, @NotNull FriendlyByteBuf buf) {
+ this(buf.readUtf(64), buf.readNbt());
+ }
+
+ @Override
+ public void write(@NotNull FriendlyByteBuf buf) {
+ buf.writeUtf(version);
+ buf.writeNbt(nbt);
+ }
+
+ @Override
+ @NotNull
+ public ResourceLocation id() {
+ return HELLO_ID;
+ }
+ }
+}

View File

@@ -1,44 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 17:21:11 +0800
From: MrHua269 <novau233@163.com>
Date: Wed, 7 Feb 2024 06:03:02 +0000
Subject: [PATCH] Gale Don't load chunks to activate climbing entities
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 793dc5b35e9a0665d486a74ce5b776b43b941ee2..fcd532898e099a809969603941b90fdd415b03c3 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -57,6 +57,7 @@ public class LuminolConfig {
public static int maximumActivationPrio;
public static int activationDistanceMod;
public static double entityWakeUpDurationRatioStandardDeviation = 0.2;
+ public static boolean loadChunksToActiveClimbingEntities = false;
public static void init() throws IOException {
@@ -169,6 +170,7 @@ public class LuminolConfig {
maxProjectileLoadsPerProjectile = get("optimizations.projectile.max-loads-per-projectile", maxProjectileLoadsPerProjectile, "Controls how many chunks a projectile \n can load in its lifetime before it gets \nautomatically removed.");
initDAB();
entityWakeUpDurationRatioStandardDeviation = get("optimizations.entity_wakeup_duration_ratio_standard_deviation",entityWakeUpDurationRatioStandardDeviation);
+ loadChunksToActiveClimbingEntities = get("optimizations.load_chunks_to_active_climbing_entities",loadChunksToActiveClimbingEntities);
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/LoadChunksToActiveClimbingEntitiesConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/LoadChunksToActiveClimbingEntitiesConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed62d25d6cd6dfcf8c5db20ced36eb3d3c79dafd
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/LoadChunksToActiveClimbingEntitiesConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class LoadChunksToActiveClimbingEntitiesConfig implements IConfigModule {
+ @ConfigInfo(baseName = "allow")
+ public static boolean allow = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.OPTIMIZATIONS;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "load_chunks_to_active_climbing_entities";
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 56efbcc29adca0239ef09a269f0899a3a6e2801b..54daa1744c89e98136d0f594a35119d5fd3d6bc8 100644
index a999e3204d89ce2107026940cec7399360739ef0..cb531ab68cee6bc1a24309290771eb39de2dc276 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -5330,6 +5330,16 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
return this.feetBlockState;
@@ -5600,6 +5600,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return this.inBlockState;
}
+ // Gale start - don't load chunks to activate climbing entities
+ public @Nullable BlockState getFeetBlockStateIfLoaded() {
+ if (this.feetBlockState == null) {
+ this.feetBlockState = this.level.getBlockStateIfLoaded(this.blockPosition());
+ if (this.inBlockState == null) {
+ this.inBlockState = this.level.getBlockStateIfLoaded(this.blockPosition());
+ }
+
+ return this.feetBlockState;
+ return this.inBlockState;
+ }
+ // Gale end - don't load chunks to activate climbing entities
+
@@ -46,17 +52,17 @@ index 56efbcc29adca0239ef09a269f0899a3a6e2801b..54daa1744c89e98136d0f594a35119d5
return this.chunkPosition;
}
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index f13d26b280f095d006ffccb36af66bb7487cb8da..ecbacbed29af51d949122b21c3ae9fc95885c6d8 100644
index 216af15f706f777bd6350cdd2187a8e7c98dfa21..76758de966bba1eab9e10ecf6063303e01e80e49 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -2027,19 +2027,43 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -2073,19 +2073,43 @@ public abstract class LivingEntity extends Entity implements Attackable {
public boolean onClimableCached() {
if (!this.blockPosition().equals(this.lastClimbingPosition)) {
- this.cachedOnClimable = this.onClimbable();
- this.lastClimbingPosition = this.blockPosition();
+ // Gale start - don't load chunks to activate climbing entities
+ Boolean onClimbableIfLoaded = this.onClimbable(LuminolConfig.loadChunksToActiveClimbingEntities);
+ Boolean onClimbableIfLoaded = this.onClimbable(me.earthme.luminol.config.modules.optimizations.LoadChunksToActiveClimbingEntitiesConfig.allow);
+ if (onClimbableIfLoaded != null) {
+ this.cachedOnClimable = onClimbableIfLoaded;
+ this.lastClimbingPosition = this.blockPosition();
@@ -81,11 +87,11 @@ index f13d26b280f095d006ffccb36af66bb7487cb8da..ecbacbed29af51d949122b21c3ae9fc9
return false;
} else {
BlockPos blockposition = this.blockPosition();
- BlockState iblockdata = this.getFeetBlockState();
- BlockState iblockdata = this.getInBlockState();
+ // Gale start - don't load chunks to activate climbing entities
+ BlockState iblockdata;
+ if (loadChunk) {
+ iblockdata = this.getFeetBlockState();
+ iblockdata = this.getInBlockState();
+ } else {
+ iblockdata = this.getFeetBlockStateIfLoaded();
+ if (iblockdata == null) {

View File

@@ -1,126 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Thu, 21 Dec 2023 20:06:50 +0800
Subject: [PATCH] Leaves Bladeren mspt sync protocol
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index a0fd4fec133617893487586fd52e3a3a864871b4..d19f423debbeaedf955977c02aaf5f8e0016bea3 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -69,6 +69,9 @@ public class LuminolConfig {
public static boolean pcaSyncProtocol = false;
public static String pcaSyncPlayerEntity = "NOBODY";
public static boolean bladerenLeavesProtocol = false;
+ public static boolean msptSyncProtocol = false;
+ public static int msptSyncTickInterval = 20;
+
public static void init() throws IOException {
@@ -203,6 +206,8 @@ public class LuminolConfig {
pcaSyncProtocol = get("gameplay.enable_pca_sync_protocol",pcaSyncProtocol);
pcaSyncPlayerEntity = get("gameplay.pca_sync_player_entity",pcaSyncPlayerEntity,"Available values: NOBODY,EVERYBODY,OPS,OPS_AND_SELF");
bladerenLeavesProtocol = get("gameplay.bladeren_leaves_protocol",bladerenLeavesProtocol);
+ msptSyncProtocol = get("gameplay.bladeren_mspt_sync_protocol",bladerenLeavesProtocol);
+ msptSyncTickInterval = get("gameplay.bladeren_mspt_sync_interval",msptSyncTickInterval);
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java
new file mode 100644
index 0000000000000000000000000000000000000000..de92ebdf9d51a4f9a58a7650b09f070e51710ef0
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java
@@ -0,0 +1,91 @@
+package top.leavesmc.leaves.protocol.bladeren;
+
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
+import io.papermc.paper.threadedregions.TickData;
+import io.papermc.paper.threadedregions.TickRegions;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
+import it.unimi.dsi.fastutil.objects.ObjectLists;
+import me.earthme.luminol.LuminolConfig;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import top.leavesmc.leaves.protocol.core.LeavesProtocol;
+import top.leavesmc.leaves.protocol.core.ProtocolHandler;
+import top.leavesmc.leaves.protocol.core.ProtocolUtils;
+
+import java.util.List;
+
+@LeavesProtocol(namespace = "bladeren")
+public class MsptSyncProtocol {
+
+ public static final String PROTOCOL_ID = "bladeren";
+
+ private static final ResourceLocation MSPT_SYNC = id("mspt_sync");
+
+ private static final List<ServerPlayer> players = ObjectLists.synchronize(new ObjectArrayList<>());
+
+ private static int tickCounter = 0;
+
+ @Contract("_ -> new")
+ public static @NotNull ResourceLocation id(String path) {
+ return new ResourceLocation(PROTOCOL_ID, path);
+ }
+
+ @ProtocolHandler.Init
+ public static void init() {
+ BladerenProtocol.registerFeature("mspt_sync", (player, compoundTag) -> {
+ if (compoundTag.getString("Value").equals("true")) {
+ onPlayerSubmit(player);
+ } else {
+ onPlayerLoggedOut(player);
+ }
+ });
+ }
+
+ @ProtocolHandler.PlayerLeave
+ public static void onPlayerLoggedOut(@NotNull ServerPlayer player) {
+ if (LuminolConfig.msptSyncProtocol) {
+ players.remove(player);
+ }
+ }
+
+ @ProtocolHandler.Ticker
+ public static void tick() {
+ if (LuminolConfig.msptSyncProtocol) {
+ if (players.isEmpty()) {
+ return;
+ }
+
+ if (tickCounter++ % LuminolConfig.msptSyncTickInterval == 0) {
+ for (ServerPlayer player : players){
+ final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> region = ((ServerLevel) player.level()).regioniser.getRegionAtUnsynchronised(player.sectionX,player.sectionZ);
+
+ if (region == null){
+ continue;
+ }
+
+ final TickData.TickReportData reportData = region.getData().getRegionSchedulingHandle().getTickReport5s(System.nanoTime());
+
+ if (reportData != null){
+ final TickData.SegmentData tpsData = reportData.tpsData().segmentAll();
+ final double mspt = reportData.timePerTickData().segmentAll().average() / 1.0E6;
+ final double tps = tpsData.average();
+
+ ProtocolUtils.sendPayloadPacket(player, MSPT_SYNC, buf -> {
+ buf.writeDouble(mspt);
+ buf.writeDouble(tps);
+ });
+ }
+ }
+ }
+ }
+ }
+
+ public static void onPlayerSubmit(@NotNull ServerPlayer player) {
+ if (LuminolConfig.msptSyncProtocol) {
+ players.add(player);
+ }
+ }
+}

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Gale Optimize sun burn tick
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 54daa1744c89e98136d0f594a35119d5fd3d6bc8..6f3e87661c3181b6537e4d6d96e50d8d5680c040 100644
index cb531ab68cee6bc1a24309290771eb39de2dc276..bc16167dccaf865b831885a1b32f42ab60229fe4 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -307,7 +307,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -310,7 +310,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
public double xo;
public double yo;
public double zo;
@@ -17,7 +17,7 @@ index 54daa1744c89e98136d0f594a35119d5fd3d6bc8..6f3e87661c3181b6537e4d6d96e50d8d
public BlockPos blockPosition; // Pufferfish - private->public
private ChunkPos chunkPosition;
private Vec3 deltaMovement;
@@ -2026,9 +2026,17 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -2120,9 +2120,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
/** @deprecated */
@Deprecated
public float getLightLevelDependentMagicValue() {
@@ -37,11 +37,11 @@ index 54daa1744c89e98136d0f594a35119d5fd3d6bc8..6f3e87661c3181b6537e4d6d96e50d8d
this.absMoveTo(x, y, z);
this.setYRot(yaw % 360.0F);
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 54e821351e46d25e8b0ead52d2c8dfecd1957544..394913950ac8fbcfcdbce817bac95f3b6604beb7 100644
index 03cf4ef6fd09de13709400dc508266c2b3d99330..4e0335d683334b0c6ee4dbf16d93f4e0392cf8d4 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -1736,13 +1736,29 @@ public abstract class Mob extends LivingEntity implements Targeting {
@@ -1869,13 +1869,29 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
return flag;
}
+ // Gale start - JettPack - optimize sun burn tick - cache eye blockpos

File diff suppressed because it is too large Load Diff

View File

@@ -1,74 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Mon, 8 Jan 2024 12:19:29 +0000
Subject: [PATCH] Do not process any packet if the leaves protocol supports are
disabled
diff --git a/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
index ebd28033ddf0fe6a354585dc2818a9b481d90ed4..33c7221a1f33cdb81dfac92fc3332f92cf3cd2d9 100644
--- a/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
+++ b/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
@@ -1,5 +1,6 @@
package top.leavesmc.leaves.protocol;
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
diff --git a/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java
index de92ebdf9d51a4f9a58a7650b09f070e51710ef0..b309963dcf41f16a7b53e4cc2816975523ccba55 100644
--- a/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java
+++ b/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java
@@ -35,6 +35,9 @@ public class MsptSyncProtocol {
@ProtocolHandler.Init
public static void init() {
+ if (!LuminolConfig.msptSyncProtocol){
+ return;
+ }
BladerenProtocol.registerFeature("mspt_sync", (player, compoundTag) -> {
if (compoundTag.getString("Value").equals("true")) {
onPlayerSubmit(player);
diff --git a/src/main/java/top/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java b/src/main/java/top/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java
index fc229f23076147304754a267bcc345cc836b648b..6325f6441e28d915514e6b0ee9b450610e99b2c2 100644
--- a/src/main/java/top/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java
+++ b/src/main/java/top/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java
@@ -2,6 +2,7 @@ package top.leavesmc.leaves.protocol.syncmatica;
import com.mojang.authlib.GameProfile;
import io.netty.buffer.Unpooled;
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
@@ -68,6 +69,9 @@ public class CommunicationManager {
@ProtocolHandler.PlayerJoin
public static void onPlayerJoin(ServerPlayer player) {
+ if (!LuminolConfig.syncmaticaProtocol){
+ return;
+ }
final ExchangeTarget newPlayer = player.connection.exchangeTarget;
final VersionHandshakeServer hi = new VersionHandshakeServer(newPlayer);
playerMap.put(newPlayer, player);
@@ -78,6 +82,9 @@ public class CommunicationManager {
@ProtocolHandler.PlayerLeave
public static void onPlayerLeave(ServerPlayer player) {
+ if (!LuminolConfig.syncmaticaProtocol){
+ return;
+ }
final ExchangeTarget oldPlayer = player.connection.exchangeTarget;
final Collection<Exchange> potentialMessageTarget = oldPlayer.getExchanges();
if (potentialMessageTarget != null) {
@@ -92,6 +99,9 @@ public class CommunicationManager {
@ProtocolHandler.PayloadReceiver(payload = LeavesProtocolManager.LeavesPayload.class, ignoreId = true)
public static void onPacketGet(ServerPlayer player, LeavesProtocolManager.LeavesPayload payload) {
+ if (!LuminolConfig.syncmaticaProtocol){
+ return;
+ }
onPacket(player.connection.exchangeTarget, payload.id(), payload.data());
}

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