├── .github
├── images
│ └── banner.png
└── workflows
│ └── release.yml
├── LICENSE
├── README.md
├── pom.xml
└── src
└── main
├── java
└── de
│ └── kcodeyt
│ └── vanilla
│ ├── VanillaGeneratorPlugin.java
│ ├── behavior
│ ├── LootTable.java
│ ├── LootTableBuilder.java
│ ├── LootTableManager.java
│ ├── LootTableNumber.java
│ ├── Pool.java
│ ├── PoolEntry.java
│ └── function
│ │ ├── EnchantRandomlyFunction.java
│ │ ├── EnchantWithLevelsFunction.java
│ │ ├── FunctionRegistry.java
│ │ ├── LootTableFunction.java
│ │ ├── RandomAuxValueFunction.java
│ │ ├── SetCountFunction.java
│ │ ├── SetDamageFunction.java
│ │ ├── SetDataFunction.java
│ │ └── SpecificEnchantsFunction.java
│ ├── command
│ ├── LocateCommand.java
│ ├── SudoCommand.java
│ └── WorldCommand.java
│ ├── enchantment
│ ├── EnchantmentHelper.java
│ ├── EnchantmentHolder.java
│ ├── EnchantmentRarity.java
│ ├── EnchantmentType.java
│ ├── Enchantments.java
│ ├── ItemEnchantment.java
│ ├── VanillaEnchantment.java
│ └── defaults
│ │ ├── AquaAffinityEnchantment.java
│ │ ├── BindingCurseEnchantment.java
│ │ ├── ChannelingEnchantment.java
│ │ ├── DamageEnchantment.java
│ │ ├── DepthStriderEnchantment.java
│ │ ├── EfficiencyEnchantment.java
│ │ ├── FireAspectEnchantment.java
│ │ ├── FlameEnchantment.java
│ │ ├── FrostWalkerEnchantment.java
│ │ ├── ImpalingEnchantment.java
│ │ ├── InfinityEnchantment.java
│ │ ├── KnockbackEnchantment.java
│ │ ├── LootBonusEnchantment.java
│ │ ├── LoyaltyEnchantment.java
│ │ ├── LureEnchantment.java
│ │ ├── MendingEnchantment.java
│ │ ├── MultishotEnchantment.java
│ │ ├── PiercingEnchantment.java
│ │ ├── PowerEnchantment.java
│ │ ├── ProtectionEnchantment.java
│ │ ├── PunchEnchantment.java
│ │ ├── QuickChargeEnchantment.java
│ │ ├── RespirationEnchantment.java
│ │ ├── RiptideEnchantment.java
│ │ ├── SilkTouchEnchantment.java
│ │ ├── SoulSpeedEnchantment.java
│ │ ├── SwiftSneakEnchantment.java
│ │ ├── ThornsEnchantment.java
│ │ ├── UnbreakingEnchantment.java
│ │ └── VanishingCurseEnchantment.java
│ ├── generator
│ ├── Vanilla.java
│ ├── VanillaNether.java
│ ├── VanillaOverworld.java
│ ├── VanillaTheEnd.java
│ ├── chunk
│ │ ├── ChunkData.java
│ │ ├── ChunkRequest.java
│ │ └── ChunkWaiter.java
│ ├── client
│ │ ├── Client.java
│ │ ├── ConnectionState.java
│ │ ├── MojangLoginForger.java
│ │ ├── Network.java
│ │ ├── clientdata
│ │ │ ├── DeviceOS.java
│ │ │ ├── LoginData.java
│ │ │ ├── Skin.java
│ │ │ └── UIProfile.java
│ │ └── handler
│ │ │ ├── LoginHandler.java
│ │ │ ├── NetworkHandler.java
│ │ │ ├── PlayingHandler.java
│ │ │ └── ResourcePackHandler.java
│ └── server
│ │ ├── BedrockDedicatedServer.java
│ │ ├── ProcessWrapper.java
│ │ └── VanillaServer.java
│ ├── util
│ ├── GameVersion.java
│ ├── ItemIdentifier.java
│ ├── NbtConverter.java
│ ├── Palette.java
│ ├── SimpleMath.java
│ ├── WebRequest.java
│ ├── WeightedRandom.java
│ └── ZipHelper.java
│ └── world
│ ├── BlockEntityData.java
│ ├── World.java
│ └── blockentity
│ ├── BasicCreator.java
│ ├── BasicFurnaceCreator.java
│ ├── BeehiveCreator.java
│ ├── BlockEntityCreator.java
│ ├── BrewingStandCreator.java
│ ├── ChestCreator.java
│ ├── ItemFrameCreator.java
│ ├── LecternCreator.java
│ └── MobSpawnerCreator.java
└── resources
├── config.yml
└── plugin.yml
/.github/images/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KCodeYT/VanillaGenerator/10254c70a678c13bce9e9fa66faf570673ad3bca/.github/images/banner.png
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release this plugin
2 |
3 | on:
4 | push:
5 | branches: [ release ]
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Checkout github repository
12 | uses: actions/checkout@v3
13 |
14 | - name: Set up JDK 17
15 | uses: actions/setup-java@v3
16 | with:
17 | java-version: '17'
18 | distribution: 'temurin'
19 | cache: maven
20 |
21 | - name: Get name and version from pom.xml
22 | run: |
23 | VER=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
24 | echo "VER=$VER" >> $GITHUB_ENV
25 | NAME=$(mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout)
26 | echo "NAME=$NAME" >> $GITHUB_ENV
27 |
28 | - name: Build plugin
29 | run: mvn package
30 |
31 | - name: Delete old release
32 | uses: dev-drprasad/delete-tag-and-release@v0.2.0
33 | with:
34 | delete_release: true
35 | tag_name: ${{env.VER}}
36 | env:
37 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
38 |
39 | - name: Create Release
40 | id: create_release
41 | uses: actions/create-release@v1
42 | env:
43 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
44 | with:
45 | tag_name: ${{env.VER}}
46 | release_name: VanillaGenerator v${{env.VER}}
47 |
48 | - name: Upload plugin as release
49 | uses: actions/upload-release-asset@v1
50 | env:
51 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
52 | with:
53 | upload_url: ${{steps.create_release.outputs.upload_url}}
54 | asset_path: target/${{env.NAME}}-${{env.VER}}.jar
55 | asset_name: VanillaGenerator.jar
56 | asset_content_type: application/java-archive
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | What is this?
4 | ------------------------------
5 |
6 | This project is currently only a proof-of-concept work to present that a vanilla generator based on a background server
7 | would theoretically and practically work.
8 | This project adds a vanilla generator to the [powernukkitx](https://github.com/PowerNukkitX/PowerNukkitX/) server
9 | software.
10 |
11 | ⚠️ This plugin only works with powernukkitx for minecraft bedrock edition 1.19.60 (protocol 567) ⚠️
12 |
13 | How can I download this plugin?
14 | ------------------------------
15 |
16 | You can find the downloads on the [releases section](https://github.com/KCodeYT/VanillaGenerator/releases) of this
17 | github
18 | page.
19 | There you can find the LATEST jar file of this plugin.
20 |
21 | How can I access the generator?
22 | ------------------------------
23 |
24 | 0. ⚠️ DO NOT RUN THIS PLUGIN ON A PRODUCTION SERVER ⚠️
25 | (its not stable and uses much resources)
26 | 1. Add this plugin to your server.
27 | 2. Open the nukkit.yml file of your server.
28 | You need to add a new world to the worlds config in the nukkit.yml file.
29 | This world needs the generator "vanilla" for the overworld.
30 | If you want the world to be nether, then the generator needs to be "vanilla_nether".
31 | If you want the world to be the end, then the generator needs to be "vanilla_the_end".
32 | 3. Save the file and start your server.
33 |
34 | Example nukkit.yml world config (with all 3 world types):
35 |
36 | ```xml
37 | worlds:
38 | world:
39 | seed: 0123456789
40 | generator: vanilla
41 | nether:
42 | seed: 0123456789
43 | generator: vanilla_nether
44 | the_end:
45 | seed: 0123456789
46 | generator: vanilla_the_end
47 | ```
48 |
49 | How does this plugin work?
50 | ------------------------------
51 |
52 | This plugin works by adding 3 new generators to the server (vanilla, vanilla_nether, vanilla_the_end).
53 | Those generators start a bedrock dedicated server in the background. After they started bots join those servers and
54 | generate chunks continuously and clone them to the powernukkitx server when they are needed.
55 | As its well known that a bedrock dedicated server uses a lot of resources, with this plugin your server needs those
56 | resources too.
57 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | de.kcodeyt
8 | VanillaGenerator
9 | 0.0.14-SNAPSHOT
10 |
11 |
12 |
13 | opencollab-dev-repo
14 | https://repo.opencollab.dev/snapshot/
15 |
16 |
17 |
18 |
19 |
20 | cn.powernukkitx
21 | powernukkitx
22 | 1.19.60-r1
23 | provided
24 |
25 |
26 | org.projectlombok
27 | lombok
28 | 1.18.24
29 |
30 |
31 | com.google.code.gson
32 | gson
33 | 2.10
34 |
35 |
36 | commons-io
37 | commons-io
38 | 2.11.0
39 |
40 |
41 | org.apache.commons
42 | commons-lang3
43 | 3.12.0
44 |
45 |
46 | it.unimi.dsi
47 | fastutil
48 | 8.5.9
49 | provided
50 |
51 |
52 | com.nukkitx.protocol
53 | bedrock-v567
54 | 2.9.16-SNAPSHOT
55 | compile
56 |
57 |
58 | com.nukkitx.fastutil
59 | *
60 |
61 |
62 | io.netty
63 | *
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | org.apache.maven.plugins
73 | maven-compiler-plugin
74 | 3.8.1
75 |
76 | 17
77 | 17
78 |
79 |
80 |
81 | org.apache.maven.plugins
82 | maven-shade-plugin
83 | 3.3.0
84 |
85 |
86 | package
87 |
88 | shade
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/src/main/java/de/kcodeyt/vanilla/behavior/LootTable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 KCodeYT
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package de.kcodeyt.vanilla.behavior;
18 |
19 | import cn.nukkit.inventory.Inventory;
20 | import cn.nukkit.item.Item;
21 | import de.kcodeyt.vanilla.VanillaGeneratorPlugin;
22 | import de.kcodeyt.vanilla.behavior.function.LootTableFunction;
23 | import de.kcodeyt.vanilla.util.ItemIdentifier;
24 |
25 | import java.util.ArrayList;
26 | import java.util.Collections;
27 | import java.util.List;
28 | import java.util.Random;
29 | import java.util.stream.Collectors;
30 | import java.util.stream.IntStream;
31 |
32 | /**
33 | * @author Kevims KCodeYT
34 | * @version 1.0-SNAPSHOT
35 | */
36 | public record LootTable(String path, String name, List pools) {
37 |
38 | public void fillInventory(Inventory inventory, Long randomSeed) {
39 | final List freeSlots = IntStream.range(0, inventory.getSize()).filter(slot -> inventory.getItem(slot).isNull()).boxed().collect(Collectors.toList());
40 | if(freeSlots.size() < inventory.getSize()) {
41 | VanillaGeneratorPlugin.getInstance().getLogger().warning("Tried to overfill inventory!");
42 | return;
43 | }
44 |
45 | final Random random = randomSeed != null ? new Random(randomSeed) : new Random();
46 |
47 | for(Pool pool : this.pools) {
48 | final List entries = new ArrayList<>(pool.entries());
49 | final int rolls = pool.rolls().getAsInt();
50 | for(int i = 0; i < rolls; i++) {
51 | Collections.shuffle(entries, random);
52 |
53 | final int fullWeight = entries.stream().mapToInt(PoolEntry::weight).sum();
54 | int randomWeight = random.nextInt(fullWeight + 1);
55 | for(PoolEntry poolEntry : entries) {
56 | if((randomWeight -= poolEntry.weight()) <= 0) {
57 | final Integer slot;
58 | if(!poolEntry.type().equals("item") || poolEntry.name() == null) continue;
59 |
60 | Item item = Item.get(ItemIdentifier.getItemId(poolEntry.name()));
61 | if(item.getId() == Item.AIR) continue;
62 |
63 | for(LootTableFunction- function : poolEntry.functions())
64 | item = function.invoke(item, random);
65 |
66 | inventory.setItem(slot = freeSlots.get(random.nextInt(freeSlots.size())), item);
67 | freeSlots.remove(slot);
68 | if(freeSlots.isEmpty()) return;
69 |
70 | break;
71 | }
72 | }
73 | }
74 | }
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/de/kcodeyt/vanilla/behavior/LootTableBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 KCodeYT
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package de.kcodeyt.vanilla.behavior;
18 |
19 | import cn.nukkit.item.Item;
20 | import de.kcodeyt.vanilla.behavior.function.FunctionRegistry;
21 | import de.kcodeyt.vanilla.behavior.function.LootTableFunction;
22 |
23 | import java.util.ArrayList;
24 | import java.util.Collections;
25 | import java.util.List;
26 | import java.util.Map;
27 |
28 | /**
29 | * @author Kevims KCodeYT
30 | * @version 1.0-SNAPSHOT
31 | */
32 | public class LootTableBuilder {
33 |
34 | public static LootTable build(String path, String name, Map lootTableMap) {
35 | if(!lootTableMap.containsKey("pools"))
36 | return new LootTable(path, name, Collections.emptyList());
37 |
38 | try {
39 | final List pools = new ArrayList<>();
40 | for(Object poolObject : ((List>) lootTableMap.get("pools"))) {
41 | final Map, ?> poolMap = (Map, ?>) poolObject;
42 | final LootTableNumber rolls = LootTableNumber.of(poolMap.get("rolls"));
43 |
44 | final List entries = new ArrayList<>();
45 | final List> entriesList = (List>) poolMap.get("entries");
46 | for(Object entryObject : entriesList) {
47 | final Map, ?> entryMap = (Map, ?>) entryObject;
48 | final String entryType = (String) entryMap.get("type");
49 | if(entryType == null) continue;
50 |
51 | final String entryName = (String) entryMap.get("name");
52 | final int entryWeight = entryMap.containsKey("weight") ? (int) (double) (Object) entryMap.get("weight") : 1;
53 | if(!entryMap.containsKey("functions")) {
54 | entries.add(new PoolEntry(entryType, entryName, entryWeight, Collections.emptyList()));
55 | continue;
56 | }
57 |
58 | final List> functions = new ArrayList<>();
59 | final List> functionsList = (List>) entryMap.get("functions");
60 | for(Object functionObject : functionsList) {
61 | final Map, ?> functionMap = (Map, ?>) functionObject;
62 | final LootTableFunction
- function = FunctionRegistry.get((String) functionMap.get("function"), functionMap);
63 |
64 | if(function != null) functions.add(function);
65 | }
66 |
67 | entries.add(new PoolEntry(entryType, entryName, entryWeight, Collections.unmodifiableList(functions)));
68 | }
69 |
70 | pools.add(new Pool(rolls, Collections.unmodifiableList(entries)));
71 | }
72 |
73 | return new LootTable(path, name, Collections.unmodifiableList(pools));
74 | } catch(NullPointerException e) {
75 | e.printStackTrace();
76 | return null;
77 | }
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/de/kcodeyt/vanilla/behavior/LootTableManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 KCodeYT
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package de.kcodeyt.vanilla.behavior;
18 |
19 | import com.google.gson.Gson;
20 | import lombok.Getter;
21 | import lombok.NoArgsConstructor;
22 |
23 | import java.io.BufferedReader;
24 | import java.io.File;
25 | import java.io.FileReader;
26 | import java.io.IOException;
27 | import java.util.HashSet;
28 | import java.util.Map;
29 | import java.util.Objects;
30 | import java.util.Set;
31 |
32 | /**
33 | * @author Kevims KCodeYT
34 | * @version 1.0-SNAPSHOT
35 | */
36 | @NoArgsConstructor
37 | public class LootTableManager {
38 |
39 | private static final Gson GSON = new Gson();
40 |
41 | @Getter
42 | private final Set lootTables = new HashSet<>();
43 |
44 | public LootTable getLootTable(String name) {
45 | for(LootTable lootTable : this.lootTables)
46 | if(lootTable.path().equalsIgnoreCase(name) || lootTable.name().equalsIgnoreCase(name))
47 | return lootTable;
48 |
49 | return null;
50 | }
51 |
52 | public void loadPacks(File packsDir) {
53 | if(!packsDir.isDirectory()) return;
54 |
55 | for(File file : Objects.requireNonNull(packsDir.listFiles()))
56 | if(file.isDirectory())
57 | this.loadPack(file);
58 | }
59 |
60 | private void loadPack(File packFile) {
61 | final File manifestFile = new File(packFile, "manifest.json");
62 | final File lootTablesDir = new File(packFile, "loot_tables");
63 | if(manifestFile.exists() && lootTablesDir.exists())
64 | for(File lootTableFile : Objects.requireNonNull(lootTablesDir.listFiles()))
65 | this.loadLootTable(lootTableFile, "loot_tables");
66 | }
67 |
68 | private void loadLootTable(File lootTableFile, String currentPath) {
69 | if(lootTableFile.isDirectory()) {
70 | for(File nextLootTableFile : Objects.requireNonNull(lootTableFile.listFiles()))
71 | this.loadLootTable(nextLootTableFile, currentPath + "/" + lootTableFile.getName());
72 | return;
73 | }
74 |
75 | final String lootTablePath = currentPath + "/" + lootTableFile.getName();
76 | final String lootTableName = lootTableFile.getName().split("\\.")[0];
77 | if(!lootTablePath.contains("chest")) return;
78 |
79 | try(final FileReader fileReader = new FileReader(lootTableFile);
80 | final BufferedReader bufferedReader = new BufferedReader(fileReader)) {
81 | this.lootTables.add(LootTableBuilder.build(lootTablePath, lootTableName, GSON.