Skip to content

Commit adea1d7

Browse files
authored
Merge pull request #20 from SkriptDev/dev/feature
Dev/feature - Future Feature Release
2 parents 79983c4 + e5f202f commit adea1d7

75 files changed

Lines changed: 1651 additions & 209 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.gradle.kts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dependencies {
3737
implementation("org.bstats:bstats-hytale:3.2.1")
3838

3939
// Skript-Parser
40-
implementation("com.github.SkriptDev:skript-parser:1.0.11") {
40+
implementation("com.github.SkriptDev:skript-parser:1.0.12") {
4141
isTransitive = false
4242
}
4343
implementation("com.github.Zoltus:TinyMessage:2.0.1") {
@@ -141,3 +141,9 @@ publishing {
141141
}
142142
}
143143
}
144+
145+
tasks.withType<GenerateModuleMetadata>().configureEach {
146+
// This resolves the "implicit dependency" failure by forcing
147+
// metadata generation to wait for the JAR task.
148+
mustRunAfter(tasks.named("jar"))
149+
}

src/main/java/com/github/skriptdev/skript/api/hytale/Block.java renamed to src/main/java/com/github/skriptdev/skript/api/hytale/objects/Block.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.skriptdev.skript.api.hytale;
1+
package com.github.skriptdev.skript.api.hytale.objects;
22

33
import com.github.skriptdev.skript.api.hytale.utils.StoreUtils;
44
import com.hypixel.hytale.component.CommandBuffer;

src/main/java/com/github/skriptdev/skript/api/hytale/Direction.java renamed to src/main/java/com/github/skriptdev/skript/api/hytale/objects/Direction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.skriptdev.skript.api.hytale;
1+
package com.github.skriptdev.skript.api.hytale.objects;
22

33
import com.github.skriptdev.skript.api.hytale.utils.LocationUtils;
44
import com.hypixel.hytale.math.vector.Location;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.github.skriptdev.skript.api.hytale.objects;
2+
3+
import com.hypixel.hytale.math.vector.Vector3d;
4+
import com.hypixel.hytale.protocol.packets.worldmap.ContextMenuItem;
5+
import com.hypixel.hytale.protocol.packets.worldmap.MapMarker;
6+
import com.hypixel.hytale.server.core.universe.world.worldmap.markers.user.UserMapMarker;
7+
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
/**
12+
* Override of {@link UserMapMarker}.
13+
* <br>Hytale lacks y-coordinates in map markers, so this class adds them.
14+
* <br>This class also adds context menu items.
15+
*/
16+
public class UserMapMarkerOverride extends UserMapMarker {
17+
18+
private float blockY;
19+
private MapMarker cachedMarker;
20+
private final List<ContextMenuItem> contextMenuItems = new ArrayList<>();
21+
22+
public void setPosition(Vector3d pos) {
23+
this.blockY = (float) pos.getY();
24+
super.setPosition((float) pos.getX(), (float) pos.getZ());
25+
}
26+
27+
public void addContextMenuItem(ContextMenuItem contextMenuItem) {
28+
this.contextMenuItems.add(contextMenuItem);
29+
}
30+
31+
@Override
32+
public MapMarker toProtocolMarker() {
33+
if (this.cachedMarker == null) {
34+
this.cachedMarker = super.toProtocolMarker();
35+
36+
assert this.cachedMarker.transform.position != null;
37+
this.cachedMarker.transform.position.y = this.blockY;
38+
if (!this.contextMenuItems.isEmpty()) {
39+
this.cachedMarker.contextMenuItems = this.contextMenuItems.toArray(new ContextMenuItem[0]);
40+
}
41+
}
42+
43+
return this.cachedMarker;
44+
}
45+
46+
}

src/main/java/com/github/skriptdev/skript/api/skript/addon/AddonLoader.java

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
import com.github.skriptdev.skript.plugin.HySk;
55
import com.hypixel.hytale.codec.ExtraInfo;
66
import com.hypixel.hytale.codec.util.RawJsonReader;
7+
import com.hypixel.hytale.common.plugin.AuthorInfo;
8+
import com.hypixel.hytale.common.plugin.PluginManifest;
9+
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
710
import io.github.syst3ms.skriptparser.log.ErrorType;
811
import io.github.syst3ms.skriptparser.log.LogEntry;
9-
import io.github.syst3ms.skriptparser.registration.SkriptAddon;
1012

1113
import java.io.File;
1214
import java.io.IOException;
@@ -16,14 +18,24 @@
1618
import java.net.URLClassLoader;
1719
import java.nio.charset.StandardCharsets;
1820
import java.nio.file.Path;
21+
import java.util.ArrayList;
1922
import java.util.Arrays;
23+
import java.util.LinkedHashMap;
24+
import java.util.List;
25+
import java.util.Map;
2026
import java.util.jar.JarEntry;
2127
import java.util.jar.JarFile;
2228

2329
public class AddonLoader {
2430

31+
private final Map<String, HySkriptAddon> loadedAddons = new LinkedHashMap<>();
2532
private int addonCount = 0;
2633

34+
public void loadAddons() {
35+
loadAddonsFromFolder();
36+
startAddons();
37+
}
38+
2739
public void loadAddonsFromFolder() {
2840
Utils.log("Loading addons...");
2941
Path resolve = HySk.getInstance().getDataDirectory().resolve("addons");
@@ -47,13 +59,14 @@ public void loadAddonsFromFolder() {
4759
.filter(File::isFile)
4860
.filter(f -> f.getName().endsWith(".jar"))
4961
.toList()) {
50-
loadAddon(file);
62+
loadAddonFromFile(file);
5163
}
5264
String plural = this.addonCount == 1 ? "" : "s";
5365
Utils.log("Finished loading %s addon%s!", this.addonCount, plural);
5466
}
5567

56-
private void loadAddon(File file) {
68+
@SuppressWarnings("unchecked")
69+
private void loadAddonFromFile(File file) {
5770
try (JarFile jarFile = new JarFile(file)) {
5871
JarEntry jarEntry = jarFile.getJarEntry("manifest.json");
5972
if (jarEntry == null) {
@@ -81,33 +94,64 @@ private void loadAddon(File file) {
8194
Utils.error("Main class not found in addon " + file.getName());
8295
return;
8396
}
84-
Object mainClassIntance;
85-
try {
86-
mainClassIntance = externalClass.getDeclaredConstructor(String.class).newInstance(manifest.getName());
87-
} catch (ReflectiveOperationException e) {
88-
Utils.error("Failed to create instance of addon " + file.getName(), ErrorType.EXCEPTION);
97+
if (!HySkriptAddon.class.isAssignableFrom(externalClass)) {
98+
Utils.error("Main class is not an instance of HySkriptAddon in addon " + file.getName());
8999
return;
90100
}
91-
if (mainClassIntance instanceof HySkriptAddon addon) {
92-
addon.setManifest(manifest);
93-
addon.start();
94-
this.addonCount++;
95-
// Finalize registration and logging
96-
for (LogEntry logEntry : addon.getSkriptRegistration().register()) {
97-
Utils.log(null, logEntry);
98-
}
99-
}
101+
initializeAddon((Class<HySkriptAddon>) externalClass, manifest);
102+
100103
} catch (IOException e) {
101104
Utils.error("Failed to load addon " + file.getName(), ErrorType.EXCEPTION);
102105
}
103106
}
104107

105-
public void shutdownAddons() {
106-
for (SkriptAddon addon : SkriptAddon.getAddons()) {
107-
if (addon instanceof HySkriptAddon hySkriptAddon) {
108-
hySkriptAddon.shutdown();
108+
private void startAddons() {
109+
this.loadedAddons.forEach((_, addon) -> {
110+
addon.start();
111+
// Finalize registration and logging
112+
for (LogEntry logEntry : addon.getSkriptRegistration().register()) {
113+
Utils.log(null, logEntry);
109114
}
115+
});
116+
}
117+
118+
public <T extends HySkriptAddon> T registerAddon(JavaPlugin plugin, Class<T> addonClass) {
119+
PluginManifest pluginManifest = plugin.getManifest();
120+
String name = pluginManifest.getName();
121+
List<String> authors = new ArrayList<>();
122+
for (AuthorInfo author : pluginManifest.getAuthors()) {
123+
authors.add(author.getName());
110124
}
125+
Manifest addonManifest = new Manifest(null,
126+
name,
127+
pluginManifest.getVersion().toString(),
128+
pluginManifest.getDescription(),
129+
authors.toArray(new String[0]),
130+
pluginManifest.getWebsite());
131+
132+
return initializeAddon(addonClass, addonManifest);
133+
}
134+
135+
@SuppressWarnings("unchecked")
136+
private <T extends HySkriptAddon> T initializeAddon(Class<T> externalClass, Manifest manifest) {
137+
HySkriptAddon mainClassIntance;
138+
String name = manifest.getName();
139+
try {
140+
mainClassIntance = externalClass.getDeclaredConstructor(String.class).newInstance(name);
141+
} catch (ReflectiveOperationException e) {
142+
Utils.error("Failed to create instance of addon " + name, ErrorType.EXCEPTION);
143+
return null;
144+
}
145+
HySkriptAddon addon = mainClassIntance;
146+
addon.setManifest(manifest);
147+
this.loadedAddons.put(name, addon);
148+
this.addonCount++;
149+
return (T) addon;
150+
}
151+
152+
public void shutdownAddons() {
153+
this.loadedAddons.forEach((name, addon) -> addon.shutdown());
154+
this.loadedAddons.clear();
111155
}
112156

113157
}

src/main/java/com/github/skriptdev/skript/api/skript/addon/Manifest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ public class Manifest {
4040
private String[] authors;
4141
private String website;
4242

43+
private Manifest() {
44+
}
45+
46+
public Manifest(String mainClass, String name, String version, String description, String[] authors, String website) {
47+
this.mainClass = mainClass;
48+
this.name = name;
49+
this.version = version;
50+
this.description = description;
51+
this.authors = authors;
52+
this.website = website;
53+
}
54+
4355
@ApiStatus.Internal
4456
public String getMainClass() {
4557
return this.mainClass;

src/main/java/com/github/skriptdev/skript/api/skript/event/BlockContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.github.skriptdev.skript.api.skript.event;
22

3-
import com.github.skriptdev.skript.api.hytale.Block;
3+
import com.github.skriptdev.skript.api.hytale.objects.Block;
44
import io.github.syst3ms.skriptparser.lang.TriggerContext;
55

66
/**
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.github.skriptdev.skript.api.skript.event;
2+
3+
import com.hypixel.hytale.server.core.entity.entities.Player;
4+
import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent;
5+
import com.hypixel.hytale.server.core.inventory.ItemStack;
6+
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
7+
import com.hypixel.hytale.server.core.inventory.transaction.ActionType;
8+
import com.hypixel.hytale.server.core.inventory.transaction.SlotTransaction;
9+
10+
public abstract class SlotTransactionContext implements PlayerContext {
11+
12+
private final LivingEntityInventoryChangeEvent event;
13+
private final SlotTransaction slotTransaction;
14+
private final Player player;
15+
16+
public SlotTransactionContext(LivingEntityInventoryChangeEvent event,
17+
SlotTransaction slotTransaction, Player player) {
18+
this.event = event;
19+
this.slotTransaction = slotTransaction;
20+
this.player = player;
21+
}
22+
23+
public ItemContainer getContainer() {
24+
return this.event.getItemContainer();
25+
}
26+
27+
public ActionType getActionType() {
28+
return this.slotTransaction.getAction();
29+
}
30+
31+
public int getSlot() {
32+
return this.slotTransaction.getSlot();
33+
}
34+
35+
public ItemStack getSlotBefore() {
36+
return this.slotTransaction.getSlotBefore();
37+
}
38+
39+
public ItemStack getSlotAfter() {
40+
return this.slotTransaction.getSlotAfter();
41+
}
42+
43+
public ItemStack getOutput() {
44+
return this.slotTransaction.getOutput();
45+
}
46+
47+
@Override
48+
public Player getPlayer() {
49+
return this.player;
50+
}
51+
52+
}

src/main/java/com/github/skriptdev/skript/api/skript/testing/TestRunner.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22

33
import com.github.skriptdev.skript.api.skript.testing.elements.EvtTest.TestContext;
44
import com.github.skriptdev.skript.api.utils.Utils;
5+
import com.hypixel.hytale.math.util.ChunkUtil;
6+
import com.hypixel.hytale.math.vector.Transform;
7+
import com.hypixel.hytale.math.vector.Vector3i;
58
import com.hypixel.hytale.server.core.HytaleServer;
69
import com.hypixel.hytale.server.core.Message;
710
import com.hypixel.hytale.server.core.universe.Universe;
811
import com.hypixel.hytale.server.core.universe.world.World;
12+
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
13+
import com.hypixel.hytale.server.core.universe.world.spawn.ISpawnProvider;
914
import com.hypixel.hytale.server.core.util.MessageUtil;
1015
import fi.sulku.hytale.TinyMsg;
1116
import io.github.syst3ms.skriptparser.lang.Statement;
@@ -23,6 +28,7 @@
2328
import java.util.Arrays;
2429
import java.util.Comparator;
2530
import java.util.List;
31+
import java.util.UUID;
2632
import java.util.concurrent.ScheduledExecutorService;
2733
import java.util.concurrent.TimeUnit;
2834

@@ -37,10 +43,6 @@ public class TestRunner {
3743

3844
@SuppressWarnings("DataFlowIssue")
3945
public void start() {
40-
Runnable runTestsRunnable = () -> {
41-
Utils.log("Running tests in world 'default'...");
42-
runTests();
43-
};
4446
Runnable loadTestsRunnable = () -> {
4547
Utils.log("Testing has started!");
4648
Utils.log("Loading test scripts...");
@@ -51,7 +53,22 @@ public void start() {
5153
if (this.world.isPaused()) this.world.setPaused(false);
5254

5355
// Run our tests in the world to make sure we have access to blocks/entities
54-
this.world.execute(runTestsRunnable);
56+
this.world.execute(() -> {
57+
ISpawnProvider spawnProvider = this.world.getWorldConfig().getSpawnProvider();
58+
Transform spawnPoint = spawnProvider.getSpawnPoint(this.world, UUID.randomUUID());
59+
Vector3i pos = spawnPoint.getPosition().toVector3i();
60+
61+
62+
for (int x = pos.getX() - 64; x < pos.getX() + 64; x += 32) {
63+
for (int z = pos.getZ() - 64; z < pos.getZ() + 64; z += 32) {
64+
long index = ChunkUtil.indexChunkFromBlock(x, z);
65+
WorldChunk chunk = this.world.getChunk(index);
66+
chunk.addKeepLoaded();
67+
}
68+
}
69+
Utils.log("Running tests in world 'default'...");
70+
runTests(this.world, pos);
71+
});
5572
};
5673

5774
// Delay start to make sure the server has finished loading
@@ -63,15 +80,15 @@ private void loadTests() {
6380
loadScripts(path);
6481
}
6582

66-
private void runTests() {
83+
private void runTests(World world, Vector3i pos) {
6784
// Catch exceptions and treat them as failures
6885
Statement.setExceptionHandler(e ->
6986
this.testResults.addFailure("Exception",
7087
e.getClass().getSimpleName() + ": " + e.getMessage()));
7188

7289
// Run all the test triggers
7390
for (Trigger allTrigger : TriggerMap.getAllTriggers()) {
74-
TestContext context = new TestContext(this.testResults, this.world);
91+
TestContext context = new TestContext(this.testResults, world, pos);
7592
Statement.runAll(allTrigger, context);
7693
Variables.clearLocalVariables(context);
7794
}

0 commit comments

Comments
 (0)