Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
19ec942
build.gradle.kts - set parser to dev branch
ShaneBeee Feb 3, 2026
4f0b485
ExprEntityHealth - use built in health int
ShaneBeee Feb 3, 2026
2425f75
Initial addon support (#6)
ShaneBeee Feb 4, 2026
8963ee1
ExprMessageProperties - fix pattern
ShaneBeee Feb 4, 2026
c146af0
MouseEvents - temp remove unused context
ShaneBeee Feb 4, 2026
696c7d3
Change some logging
ShaneBeee Feb 4, 2026
f49844b
JsonVariableStorage - fix some saving issues
ShaneBeee Feb 4, 2026
0e14a43
Add some relative position stuff
ShaneBeee Feb 4, 2026
de24dc2
ArgUtils - add more command args
ShaneBeee Feb 4, 2026
068a610
EntityEffects - add some effect stuff
ShaneBeee Feb 4, 2026
955153a
Types - added some suppliers
ShaneBeee Feb 4, 2026
678c8a6
Permission expressions - added
ShaneBeee Feb 4, 2026
6a1d52e
NPCRegistry - use NAME MAP so the supplier is sorted
ShaneBeee Feb 4, 2026
00cbe07
Switch over remaining context values
ShaneBeee Feb 4, 2026
99da120
SecDropItem - fix variables and incorrect context value after section
ShaneBeee Feb 4, 2026
8f44564
ExprCurrentContext - add debugging expression
ShaneBeee Feb 4, 2026
a978a54
ExprCurrentContext - add thread name too
ShaneBeee Feb 4, 2026
5dbb644
Utils - add method to log messages to admins
ShaneBeee Feb 4, 2026
ac55714
Skript - better handling of IllegalStateExceptions regarding threads
ShaneBeee Feb 4, 2026
fa1b731
DefaultConverters - add more converters
ShaneBeee Feb 4, 2026
45ec6ed
DefaultConverters - add more converters
ShaneBeee Feb 4, 2026
b72e83a
Merge branch 'master' into dev/patch
ShaneBeee Feb 5, 2026
72c0d63
Merge branch 'master' into dev/patch
ShaneBeee Feb 5, 2026
465ab79
Code cleanup
ShaneBeee Feb 5, 2026
47ac6e0
Add checkstyle - wish me luck
ShaneBeee Feb 5, 2026
6019d85
build.gradle.kts - fix error!?!?
ShaneBeee Feb 5, 2026
3cba79f
build.gradle.kts - fix error!?!?
ShaneBeee Feb 5, 2026
9f49052
More checkstyle stuff
ShaneBeee Feb 5, 2026
cbe6f71
JsonVariableStorage - switch variables to save on their own named thread
ShaneBeee Feb 5, 2026
3587f86
Add message format wiki link to send message effect and message expre…
ShaneBeee Feb 5, 2026
1403faa
Add message format wiki link to send message effect and message expre…
ShaneBeee Feb 5, 2026
f00174b
Added GameMode support (#10)
libnexus Feb 5, 2026
3ecc68d
Gamemode - minor cleanup
ShaneBeee Feb 5, 2026
089f2aa
Cleanup more deprecation
ShaneBeee Feb 5, 2026
b026311
Checkstyle - getting that line count down
ShaneBeee Feb 5, 2026
6c6a557
PlayerRefContext - added a global player ref context
ShaneBeee Feb 5, 2026
afefb25
EvtPlayerJoin - add back the disconnect listener
ShaneBeee Feb 5, 2026
3aae359
build.gradle.kts - update parser
ShaneBeee Feb 5, 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
37 changes: 37 additions & 0 deletions .github/workflows/checkstyle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: checkstyle

on:
push:
branches:
- master
- 'dev/**'
pull_request:

jobs:
build:
if: "! contains(toJSON(github.event.commits.*.message), '[ci skip]')"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- name: validate gradle wrapper
uses: gradle/actions/wrapper-validation@v5
- name: Set up JDK 25
uses: actions/setup-java@v5
with:
java-version: '25'
distribution: 'adopt'
cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Run checkstyle
run: ./gradlew clean checkstyleMain
- name: Upload checkstyle report
uses: actions/upload-artifact@v6
if: success()
with:
name: checkstyle-report
path: |
build/reports/checkstyle/*.xml
build/reports/checkstyle/*.html
19 changes: 18 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id("java")
id("com.gradleup.shadow") version "9.2.0"
id("maven-publish")
id("checkstyle")
}

java.sourceCompatibility = JavaVersion.VERSION_25
Expand All @@ -25,7 +26,7 @@ repositories {
dependencies {
compileOnly("com.hypixel.hytale:Server:${hytaleVersion}")
compileOnly("org.jetbrains:annotations:26.0.2")
implementation("com.github.SkriptDev:skript-parser:1.0.3") {
implementation("com.github.SkriptDev:skript-parser:1.0.4") {
isTransitive = false
}
implementation("com.github.Zoltus:TinyMessage:2.0.1") {
Expand Down Expand Up @@ -78,6 +79,22 @@ tasks {
}
}

tasks.withType<Checkstyle> {
// This one class is causing an issue on like 37 (not sure why)
exclude("**/Block.java")
}

checkstyle {
// Specify the version of the Checkstyle tool to use
toolVersion = "10.21.0" // Use a recent version of Checkstyle

isIgnoreFailures = false

// Point to your custom Checkstyle configuration file
// The default location is config/checkstyle/checkstyleMain.xml
configFile = file("${rootProject.projectDir}/config/checkstyle/checkstyle.xml")
}

publishing {
publications {
create<MavenPublication>("mavenShadow") {
Expand Down
57 changes: 57 additions & 0 deletions config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">

<module name="Checker">
<module name="LineLength">
<property name="max" value="150"/>
</module>
<property name="charset" value="UTF-8"/>
<property name="severity" value="error"/>
<property name="fileExtensions" value="java, properties, xml"/>

<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>

<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>

<module name="TreeWalker">
<module name="AnnotationLocation">
<property name="id" value="AnnotationLocationMostCases"/>
<property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
</module>

<module name="LeftCurly"/>
<module name="RightCurly"/>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyMethods" value="true"/>
<property name="allowEmptyTypes" value="true"/>
<property name="allowEmptyLoops" value="true"/>
</module>

<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-z0-9]*)*$"/>
</module>
<module name="TypeName"/>
<module name="MemberName"/>
<module name="ParameterName"/>
<module name="LocalVariableName"/>
<module name="ClassTypeParameterName"/>

<module name="AvoidStarImport"/>
<module name="UnusedImports"/>
<module name="RedundantImport"/>

<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>

<property name="tabWidth" value="4"/>
</module>
</module>
12 changes: 10 additions & 2 deletions src/main/java/com/github/skriptdev/skript/api/hytale/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
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.ChunkColumn;
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.server.core.universe.world.chunk.section.FluidSection;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import org.jetbrains.annotations.NotNull;
Expand All @@ -22,7 +23,7 @@
* This class provides a wrapper around Hytale's block system, allowing for easy interaction with blocks in a world.
* This may be changed/removed in the future.
*/
@SuppressWarnings("unused")
@SuppressWarnings({"unused", "deprecation"})
public class Block {

private final @NotNull World world;
Expand Down Expand Up @@ -57,14 +58,21 @@ public void setType(@NotNull BlockType type, int settings) {

public byte getFluidLevel() {
long index = ChunkUtil.indexChunkFromBlock(this.pos.getX(), this.pos.getZ());
Ref<ChunkStore> columnRef = this.world.getChunk(index).getReference();
WorldChunk chunk = this.world.getChunk(index);
if (chunk == null) return 0;

Ref<ChunkStore> columnRef = chunk.getReference();
Store<ChunkStore> store = columnRef.getStore();
ChunkColumn column = store.getComponent(columnRef, ChunkColumn.getComponentType());
if (column == null) return 0;

Ref<ChunkStore> section = column.getSection(ChunkUtil.chunkCoordinate(this.pos.getY()));
if (section == null) {
return 0;
} else {
FluidSection fluidSection = store.getComponent(section, FluidSection.getComponentType());
if (fluidSection == null) return 0;

return fluidSection.getFluidLevel(this.pos.getX(), this.pos.getY(), this.pos.getZ());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,20 @@ public class EntityComponentUtils {
}

@SuppressWarnings({"DataFlowIssue", "deprecation"})
public static @NotNull Pair<Entity, ItemComponent> dropItem(Store<EntityStore> store, ItemStack itemStack, Location location, Vector3f velocity, float pickupDelay) {
public static @NotNull Pair<Entity, ItemComponent> dropItem(Store<EntityStore> store, ItemStack itemStack,
Location location, Vector3f velocity, float pickupDelay) {
if (itemStack.isEmpty() || !itemStack.isValid()) {
return new Pair<>(null, null);
}

Vector3d position = location.getPosition();
Vector3f rotation = location.getRotation();

Holder<EntityStore> itemEntityHolder = ItemComponent.generateItemDrop(store, itemStack, position, rotation, velocity.getX(), velocity.getY(), velocity.getZ());
Holder<EntityStore> itemEntityHolder = ItemComponent.generateItemDrop(store, itemStack, position, rotation,
velocity.getX(), velocity.getY(), velocity.getZ());
if (itemEntityHolder == null) {
return new Pair<>(null, null);
}
;

ItemComponent itemComponent = itemEntityHolder.getComponent(ItemComponent.getComponentType());
if (itemComponent != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.github.skriptdev.skript.api.skript.addon;

import com.github.skriptdev.skript.api.utils.Utils;
import com.github.skriptdev.skript.plugin.HySk;
import com.hypixel.hytale.codec.ExtraInfo;
import com.hypixel.hytale.codec.util.RawJsonReader;
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;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class AddonLoader {

private int addonCount = 0;

public void loadAddonsFromFolder() {
Utils.log("Loading addons...");
Path resolve = HySk.getInstance().getDataDirectory().resolve("addons");
File addonFolder = resolve.toFile();
if (!addonFolder.exists()) {
if (!addonFolder.mkdirs()) {
Utils.error("Failed to create addons folder");
return;
}
} else if (!addonFolder.isDirectory()) {
Utils.error("Addons folder is not a directory");
return;
}
File[] files = addonFolder.listFiles();
if (files == null) {
Utils.error("Failed to list files in addons folder");
return;
}

for (File file : Arrays.stream(files)
.filter(File::isFile)
.filter(f -> f.getName().endsWith(".jar"))
.toList()) {
loadAddon(file);
}
String plural = this.addonCount == 1 ? "" : "s";
Utils.log("Finished loading %s addon%s!", this.addonCount, plural);
}

private void loadAddon(File file) {
try (JarFile jarFile = new JarFile(file)) {
JarEntry jarEntry = jarFile.getJarEntry("manifest.json");
if (jarEntry == null) {
Utils.error("Manifest.json not found in addon " + file.getName());
return;
}

InputStream inputStream = jarFile.getInputStream(jarEntry);
InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
char[] buffer = RawJsonReader.READ_BUFFER.get();
RawJsonReader rawJsonReader = new RawJsonReader(reader, buffer);

Manifest manifest = Manifest.CODEC.decodeJson(rawJsonReader, new ExtraInfo());
if (manifest == null) {
Utils.error("Failed to decode manifest.json in addon " + file.getName());
return;
}

URL[] urls = {file.toURI().toURL()};
URLClassLoader classLoader = new URLClassLoader(urls, HySk.getInstance().getClassLoader());
Class<?> externalClass;
try {
externalClass = classLoader.loadClass(manifest.getMainClass());
} catch (ClassNotFoundException e) {
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);
return;
}
if (mainClassIntance instanceof HySkriptAddon addon) {
addon.setManifest(manifest);
addon.setup();
this.addonCount++;
// Finalize registration and logging
for (LogEntry logEntry : addon.getSkriptRegistration().register()) {
Utils.log(null, logEntry);
}
}
} 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();
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.github.skriptdev.skript.api.skript.addon;

import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.core.Message;
import io.github.syst3ms.skriptparser.registration.SkriptAddon;
import org.jetbrains.annotations.Nullable;

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

/**
* Base class for addons for HySkript.
*/
public abstract class HySkriptAddon extends SkriptAddon {

private Manifest manifest;
private final HytaleLogger hytaleLogger;

public HySkriptAddon(String name) {
super(name);
this.hytaleLogger = HytaleLogger.get("HySkript|" + name + "|A");
}

/**
* Called when the addon starts to load.
* This is a good time to set up your syntaxes.
*/
abstract public void setup();

/**
* Called when the addon is shutting down.
* This is a good time to clean up resources.
*/
abstract public void shutdown();

public HytaleLogger getHytaleLogger() {
return this.hytaleLogger;
}

final void setManifest(Manifest manifest) {
this.manifest = manifest;
}

public final Manifest getManifest() {
return manifest;
}

public final Message[] getInfo() {
List<Message> info = new ArrayList<>();
info.add(Message.raw("Version: " + this.manifest.getVersion()));

String description = this.manifest.getDescription();
if (description != null) info.add(Message.raw("Description: " + description));

@Nullable String[] authors = this.manifest.getAuthors();
if (authors != null) info.add(Message.raw("Authors: " + String.join(", ", authors)));

String website = this.manifest.getWebsite();
if (website != null) info.add(Message.raw("Website: ").insert(Message.raw(website).link(website)));

return info.toArray(Message[]::new);
}

}
Loading
Loading