Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c246a0e
Add some map marker stuff
ShaneBeee Mar 1, 2026
a6b002d
Add some map marker stuff - test
ShaneBeee Mar 1, 2026
ba8ebc8
Merge pull request #19 from SkriptDev/dev/addon-loader
ShaneBeee Mar 2, 2026
7ec8217
Skript - make shutdown inaccessible outside
ShaneBeee Mar 2, 2026
b42bc08
BstatsMetrics - make inaccessible
ShaneBeee Mar 2, 2026
6246fca
Block/Direction - move to objects package
ShaneBeee Mar 2, 2026
f52d1f2
Add some inventory events
ShaneBeee Mar 3, 2026
2c42dee
EffEntityAttitude - fix NPE
ShaneBeee Mar 3, 2026
d3488dd
Window/Page stuff
ShaneBeee Mar 3, 2026
79dceb3
SecSpawnNPC - fix multiple issues:
ShaneBeee Mar 3, 2026
c0703a3
EffAttackOverrides - add
ShaneBeee Mar 3, 2026
0ac0228
Sections - reorganize
ShaneBeee Mar 3, 2026
bf36243
ExprEntityHealth - fix setting for a list of entities
ShaneBeee Mar 3, 2026
c9b7e72
EvtEntityDamage - fix event not being cancellable
ShaneBeee Mar 3, 2026
6d02779
EvtEntityDeath - fix priority
ShaneBeee Mar 3, 2026
e1b6ca5
ExprHeldItem - fix deleting
ShaneBeee Mar 3, 2026
6cd7921
EvtEntityDeath - checkstyle
ShaneBeee Mar 3, 2026
e6b8b2d
EvtEntityDeath - some fixes/cleanup
ShaneBeee Mar 3, 2026
72cf52a
EvtEntityDeath - checkstyle
ShaneBeee Mar 3, 2026
ce6be32
SecSpawnNPC - fix again
ShaneBeee Mar 4, 2026
b437a91
test fixes
ShaneBeee Mar 4, 2026
45f7342
TestRunner - force load our starting chunk
ShaneBeee Mar 4, 2026
5a923e5
SecPlaySound - fixes + examples
ShaneBeee Mar 4, 2026
e959c27
SecSpawnNPC - fix... AGAIN
ShaneBeee Mar 4, 2026
a72f62e
EvtTest - add event-location
ShaneBeee Mar 4, 2026
04a01f7
Add converters/comps to fix NPCRole - ModelAsset issues
ShaneBeee Mar 4, 2026
74ffe48
ExprMutableList.sk - fix comparing in test
ShaneBeee Mar 4, 2026
e5f202f
build.gradle.kts - update parser
ShaneBeee Mar 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ dependencies {
implementation("org.bstats:bstats-hytale:3.2.1")

// Skript-Parser
implementation("com.github.SkriptDev:skript-parser:1.0.11") {
implementation("com.github.SkriptDev:skript-parser:1.0.12") {
isTransitive = false
}
implementation("com.github.Zoltus:TinyMessage:2.0.1") {
Expand Down Expand Up @@ -141,3 +141,9 @@ publishing {
}
}
}

tasks.withType<GenerateModuleMetadata>().configureEach {
// This resolves the "implicit dependency" failure by forcing
// metadata generation to wait for the JAR task.
mustRunAfter(tasks.named("jar"))
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.github.skriptdev.skript.api.hytale;
package com.github.skriptdev.skript.api.hytale.objects;

import com.github.skriptdev.skript.api.hytale.utils.StoreUtils;
import com.hypixel.hytale.component.CommandBuffer;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.github.skriptdev.skript.api.hytale;
package com.github.skriptdev.skript.api.hytale.objects;

import com.github.skriptdev.skript.api.hytale.utils.LocationUtils;
import com.hypixel.hytale.math.vector.Location;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.github.skriptdev.skript.api.hytale.objects;

import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.protocol.packets.worldmap.ContextMenuItem;
import com.hypixel.hytale.protocol.packets.worldmap.MapMarker;
import com.hypixel.hytale.server.core.universe.world.worldmap.markers.user.UserMapMarker;

import java.util.ArrayList;
import java.util.List;

/**
* Override of {@link UserMapMarker}.
* <br>Hytale lacks y-coordinates in map markers, so this class adds them.
* <br>This class also adds context menu items.
*/
public class UserMapMarkerOverride extends UserMapMarker {

private float blockY;
private MapMarker cachedMarker;
private final List<ContextMenuItem> contextMenuItems = new ArrayList<>();

public void setPosition(Vector3d pos) {
this.blockY = (float) pos.getY();
super.setPosition((float) pos.getX(), (float) pos.getZ());
}

public void addContextMenuItem(ContextMenuItem contextMenuItem) {
this.contextMenuItems.add(contextMenuItem);
}

@Override
public MapMarker toProtocolMarker() {
if (this.cachedMarker == null) {
this.cachedMarker = super.toProtocolMarker();

assert this.cachedMarker.transform.position != null;
this.cachedMarker.transform.position.y = this.blockY;
if (!this.contextMenuItems.isEmpty()) {
this.cachedMarker.contextMenuItems = this.contextMenuItems.toArray(new ContextMenuItem[0]);
}
}

return this.cachedMarker;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import com.github.skriptdev.skript.plugin.HySk;
import com.hypixel.hytale.codec.ExtraInfo;
import com.hypixel.hytale.codec.util.RawJsonReader;
import com.hypixel.hytale.common.plugin.AuthorInfo;
import com.hypixel.hytale.common.plugin.PluginManifest;
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import io.github.syst3ms.skriptparser.log.ErrorType;
import io.github.syst3ms.skriptparser.log.LogEntry;
import io.github.syst3ms.skriptparser.registration.SkriptAddon;

import java.io.File;
import java.io.IOException;
Expand All @@ -16,14 +18,24 @@
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class AddonLoader {

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

public void loadAddons() {
loadAddonsFromFolder();
startAddons();
}

public void loadAddonsFromFolder() {
Utils.log("Loading addons...");
Path resolve = HySk.getInstance().getDataDirectory().resolve("addons");
Expand All @@ -47,13 +59,14 @@ public void loadAddonsFromFolder() {
.filter(File::isFile)
.filter(f -> f.getName().endsWith(".jar"))
.toList()) {
loadAddon(file);
loadAddonFromFile(file);
}
String plural = this.addonCount == 1 ? "" : "s";
Utils.log("Finished loading %s addon%s!", this.addonCount, plural);
}

private void loadAddon(File file) {
@SuppressWarnings("unchecked")
private void loadAddonFromFile(File file) {
try (JarFile jarFile = new JarFile(file)) {
JarEntry jarEntry = jarFile.getJarEntry("manifest.json");
if (jarEntry == null) {
Expand Down Expand Up @@ -81,33 +94,64 @@ private void loadAddon(File file) {
Utils.error("Main class not found in addon " + file.getName());
return;
}
Object mainClassIntance;
try {
mainClassIntance = externalClass.getDeclaredConstructor(String.class).newInstance(manifest.getName());
} catch (ReflectiveOperationException e) {
Utils.error("Failed to create instance of addon " + file.getName(), ErrorType.EXCEPTION);
if (!HySkriptAddon.class.isAssignableFrom(externalClass)) {
Utils.error("Main class is not an instance of HySkriptAddon in addon " + file.getName());
return;
}
if (mainClassIntance instanceof HySkriptAddon addon) {
addon.setManifest(manifest);
addon.start();
this.addonCount++;
// Finalize registration and logging
for (LogEntry logEntry : addon.getSkriptRegistration().register()) {
Utils.log(null, logEntry);
}
}
initializeAddon((Class<HySkriptAddon>) externalClass, manifest);

} catch (IOException e) {
Utils.error("Failed to load addon " + file.getName(), ErrorType.EXCEPTION);
}
}

public void shutdownAddons() {
for (SkriptAddon addon : SkriptAddon.getAddons()) {
if (addon instanceof HySkriptAddon hySkriptAddon) {
hySkriptAddon.shutdown();
private void startAddons() {
this.loadedAddons.forEach((_, addon) -> {
addon.start();
// Finalize registration and logging
for (LogEntry logEntry : addon.getSkriptRegistration().register()) {
Utils.log(null, logEntry);
}
});
}

public <T extends HySkriptAddon> T registerAddon(JavaPlugin plugin, Class<T> addonClass) {
PluginManifest pluginManifest = plugin.getManifest();
String name = pluginManifest.getName();
List<String> authors = new ArrayList<>();
for (AuthorInfo author : pluginManifest.getAuthors()) {
authors.add(author.getName());
}
Manifest addonManifest = new Manifest(null,
name,
pluginManifest.getVersion().toString(),
pluginManifest.getDescription(),
authors.toArray(new String[0]),
pluginManifest.getWebsite());

return initializeAddon(addonClass, addonManifest);
}

@SuppressWarnings("unchecked")
private <T extends HySkriptAddon> T initializeAddon(Class<T> externalClass, Manifest manifest) {
HySkriptAddon mainClassIntance;
String name = manifest.getName();
try {
mainClassIntance = externalClass.getDeclaredConstructor(String.class).newInstance(name);
} catch (ReflectiveOperationException e) {
Utils.error("Failed to create instance of addon " + name, ErrorType.EXCEPTION);
return null;
}
HySkriptAddon addon = mainClassIntance;
addon.setManifest(manifest);
this.loadedAddons.put(name, addon);
this.addonCount++;
return (T) addon;
}

public void shutdownAddons() {
this.loadedAddons.forEach((name, addon) -> addon.shutdown());
this.loadedAddons.clear();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ public class Manifest {
private String[] authors;
private String website;

private Manifest() {
}

public Manifest(String mainClass, String name, String version, String description, String[] authors, String website) {
this.mainClass = mainClass;
this.name = name;
this.version = version;
this.description = description;
this.authors = authors;
this.website = website;
}

@ApiStatus.Internal
public String getMainClass() {
return this.mainClass;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.github.skriptdev.skript.api.skript.event;

import com.github.skriptdev.skript.api.hytale.Block;
import com.github.skriptdev.skript.api.hytale.objects.Block;
import io.github.syst3ms.skriptparser.lang.TriggerContext;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.github.skriptdev.skript.api.skript.event;

import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
import com.hypixel.hytale.server.core.inventory.transaction.ActionType;
import com.hypixel.hytale.server.core.inventory.transaction.SlotTransaction;

public abstract class SlotTransactionContext implements PlayerContext {

private final LivingEntityInventoryChangeEvent event;
private final SlotTransaction slotTransaction;
private final Player player;

public SlotTransactionContext(LivingEntityInventoryChangeEvent event,
SlotTransaction slotTransaction, Player player) {
this.event = event;
this.slotTransaction = slotTransaction;
this.player = player;
}

public ItemContainer getContainer() {
return this.event.getItemContainer();
}

public ActionType getActionType() {
return this.slotTransaction.getAction();
}

public int getSlot() {
return this.slotTransaction.getSlot();
}

public ItemStack getSlotBefore() {
return this.slotTransaction.getSlotBefore();
}

public ItemStack getSlotAfter() {
return this.slotTransaction.getSlotAfter();
}

public ItemStack getOutput() {
return this.slotTransaction.getOutput();
}

@Override
public Player getPlayer() {
return this.player;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

import com.github.skriptdev.skript.api.skript.testing.elements.EvtTest.TestContext;
import com.github.skriptdev.skript.api.utils.Utils;
import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.math.vector.Transform;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.universe.Universe;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.server.core.universe.world.spawn.ISpawnProvider;
import com.hypixel.hytale.server.core.util.MessageUtil;
import fi.sulku.hytale.TinyMsg;
import io.github.syst3ms.skriptparser.lang.Statement;
Expand All @@ -23,6 +28,7 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

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

@SuppressWarnings("DataFlowIssue")
public void start() {
Runnable runTestsRunnable = () -> {
Utils.log("Running tests in world 'default'...");
runTests();
};
Runnable loadTestsRunnable = () -> {
Utils.log("Testing has started!");
Utils.log("Loading test scripts...");
Expand All @@ -51,7 +53,22 @@ public void start() {
if (this.world.isPaused()) this.world.setPaused(false);

// Run our tests in the world to make sure we have access to blocks/entities
this.world.execute(runTestsRunnable);
this.world.execute(() -> {
ISpawnProvider spawnProvider = this.world.getWorldConfig().getSpawnProvider();
Transform spawnPoint = spawnProvider.getSpawnPoint(this.world, UUID.randomUUID());
Vector3i pos = spawnPoint.getPosition().toVector3i();


for (int x = pos.getX() - 64; x < pos.getX() + 64; x += 32) {
for (int z = pos.getZ() - 64; z < pos.getZ() + 64; z += 32) {
long index = ChunkUtil.indexChunkFromBlock(x, z);
WorldChunk chunk = this.world.getChunk(index);
chunk.addKeepLoaded();
}
}
Utils.log("Running tests in world 'default'...");
runTests(this.world, pos);
});
};

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

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

// Run all the test triggers
for (Trigger allTrigger : TriggerMap.getAllTriggers()) {
TestContext context = new TestContext(this.testResults, this.world);
TestContext context = new TestContext(this.testResults, world, pos);
Statement.runAll(allTrigger, context);
Variables.clearLocalVariables(context);
}
Expand Down
Loading
Loading