Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions hytale/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
repositories {
maven ("https://nexus.lucko.me/repository/maven-hytale/")
}

dependencies {
implementation(project(":common"))
// hytale
compileOnly("com.hypixel.hytale:HytaleServer:2026.01.13-dcad8778f-SNAPSHOT")
}
202 changes: 202 additions & 0 deletions hytale/src/main/java/dev/neovoxel/neobot/NeoBotHytale.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package dev.neovoxel.neobot;

import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.NameMatching;
import com.hypixel.hytale.server.core.event.events.player.PlayerChatEvent;
import com.hypixel.hytale.server.core.event.events.player.PlayerDisconnectEvent;
import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
import com.hypixel.hytale.server.core.event.events.player.PlayerSetupConnectEvent;
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import com.hypixel.hytale.server.core.plugin.PluginBase;
import com.hypixel.hytale.server.core.plugin.PluginManager;
import com.hypixel.hytale.server.core.universe.Universe;
import dev.neovoxel.neobot.adapter.*;
import dev.neovoxel.neobot.bot.BotProvider;
import dev.neovoxel.neobot.command.CommandProvider;
import dev.neovoxel.neobot.config.EnhancedConfig;
import dev.neovoxel.neobot.config.ScriptConfig;
import dev.neovoxel.neobot.event.HytaleEventManager;
import dev.neovoxel.neobot.game.GameEventListener;
import dev.neovoxel.neobot.scheduler.ScheduledTask;
import dev.neovoxel.neobot.script.ScriptProvider;
import dev.neovoxel.neobot.script.ScriptScheduler;
import dev.neovoxel.neobot.storage.StorageProvider;
import lombok.Getter;
import lombok.Setter;
import org.graalvm.polyglot.HostAccess;

import java.io.File;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

public class NeoBotHytale extends JavaPlugin implements NeoBot {

@Getter
private GameEventListener gameEventListener;

@Getter
@Setter
private BotProvider botProvider;

@Getter
@Setter
private ScriptProvider scriptProvider;

@Getter(onMethod_ = {@HostAccess.Export})
@Setter
private StorageProvider storageProvider;

@Getter(onMethod_ = {@HostAccess.Export})
@Setter
private ScriptScheduler scriptScheduler;

@Getter(onMethod_ = {@HostAccess.Export})
@Setter
private EnhancedConfig messageConfig;

@Getter(onMethod_ = {@HostAccess.Export})
@Setter
private EnhancedConfig generalConfig;

@Getter(onMethod_ = {@HostAccess.Export})
@Setter
private ScriptConfig scriptConfig;

@Getter(onMethod_ = {@HostAccess.Export})
@Setter
private String storageType;

@Getter
@Setter
private CommandProvider commandProvider;

private HytaleScheduler scheduler;

public NeoBotHytale(JavaPluginInit init) {
super(init);
scheduler = new HytaleScheduler(this);
}

@Override
public void start() {
this.enable();
}

@HostAccess.Export
@Override
public NeoLogger getNeoLogger() {
return new NHytaleLogger(this);
}

@Override
public File getDataFolder() {
return getDataDirectory().toFile();
}

@Override
public void setGameEventListener(GameEventListener listener) {
HytaleEventManager manager = new HytaleEventManager(this);
getEventRegistry().registerGlobal(PlayerSetupConnectEvent.class, manager::onLogin);
getEventRegistry().registerGlobal(PlayerReadyEvent.class, manager::onJoin);
getEventRegistry().registerGlobal(PlayerDisconnectEvent.class, manager::onQuit);
getEventRegistry().registerGlobal(PlayerChatEvent.class, manager::onChat);
this.gameEventListener = listener;
}

@Override
public void registerCommands() {
HytaleCommandProvider commandProvider1 = new HytaleCommandProvider(this);
commandProvider1.registerCommand();
setCommandProvider(commandProvider1);
}

@HostAccess.Export
@Override
public String getPlatform() {
return "Hytale";
}

@Override
public boolean isPluginLoaded(String name) {
boolean has = false;
for (PluginBase plugin: PluginManager.get().getPlugins()) {
String plname = plugin.getManifest().getName();
if (plname.equals(name)) has = true;
}
return has;
}

@HostAccess.Export
@Override
public RemoteExecutor getExecutorByName(String name) {
return null;
}

@HostAccess.Export
@Override
public Player getOnlinePlayer(String name) {
return new HytalePlayer(Universe.get().getPlayer(name, NameMatching.EXACT));
}

@HostAccess.Export
@Override
public Player[] getOnlinePlayers() {
return Universe.get().getPlayers().stream().map(HytalePlayer::new).toArray(HytalePlayer[]::new);
}

@HostAccess.Export
@Override
public OfflinePlayer getOfflinePlayer(String name) {
UUID uuid = Universe.get().getPlayer(name, NameMatching.EXACT).getUuid();
return new HytaleOfflinePlayer(name, uuid);
}

@HostAccess.Export
@Override
public void broadcast(String message) {
Universe.get().sendMessage(Message.parse(message));
}

@HostAccess.Export
@Override
public String externalParsePlaceholder(String message, OfflinePlayer player) {
return message;
}


@Override
public ScheduledTask submit(Runnable task) {
return new HytaleSchedulerTask(scheduler.sync(task));
}

@Override
public ScheduledTask submitAsync(Runnable task) {
return new HytaleSchedulerTask(scheduler.async(task));
}

@Override
public ScheduledTask submit(Runnable task, long delay) {
return new HytaleSchedulerTask(scheduler.syncLater(task, delay, TimeUnit.SECONDS));
}

@Override
public ScheduledTask submitAsync(Runnable task, long delay) {
return new HytaleSchedulerTask(scheduler.asyncLater(task, delay, TimeUnit.SECONDS));
}

@Override
public ScheduledTask submit(Runnable task, long delay, long period) {
return new HytaleSchedulerTask(scheduler.syncRepeating(task, delay, period, TimeUnit.SECONDS));
}

@Override
public ScheduledTask submitAsync(Runnable task, long delay, long period) {
return new HytaleSchedulerTask(scheduler.asyncRepeating(task, delay, period, TimeUnit.SECONDS));
}

@Override
public void cancelAllTasks() {
HytaleSchedulerTask.cancelAllTasks();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package dev.neovoxel.neobot.adapter;

import com.hypixel.hytale.server.core.command.system.AbstractCommand;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import dev.neovoxel.neobot.command.CommandProvider;
import dev.neovoxel.neobot.NeoBotHytale;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

public class HytaleCommandProvider extends CommandProvider {
private final NeoBotHytale plugin;

public HytaleCommandProvider(NeoBotHytale plugin) {
super(plugin);
this.plugin = plugin;
}

@Override
public void registerCommand() {
plugin.getCommandRegistry().registerCommand(new NHytaleCommand(this));
}

public class NHytaleCommand extends AbstractCommand {
private HytaleCommandProvider provider;
protected NHytaleCommand(HytaleCommandProvider provider) {
super("neobot", "Commands for NeoBot");
setAllowsExtraArguments(true);
this.provider = provider;
}

@Override
protected @Nullable CompletableFuture<Void> execute(@NotNull CommandContext ctx) {
String input = ctx.getInputString();
List<String> args = Arrays.stream(input.split(" ")).collect(Collectors.toList());
if (!args.isEmpty()) {
String first = args.get(0);
if (first.equals("neobot") || first.equals("/neobot")) {
args.remove(0);
}
}
provider.onCommand(new HytaleCommandSender(ctx.sender()), args.toArray(new String[0]));
return null;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dev.neovoxel.neobot.adapter;

import com.hypixel.hytale.server.core.Message;
import org.graalvm.polyglot.HostAccess;
import com.hypixel.hytale.server.core.command.system.CommandSender;
public class HytaleCommandSender extends dev.neovoxel.neobot.adapter.CommandSender {
private final CommandSender sender;

public HytaleCommandSender(CommandSender sender) {
super(sender.getDisplayName());
this.sender = sender;
}

@HostAccess.Export
@Override
public void sendMessage(String message) {
sender.sendMessage(Message.parse(message));
}

@HostAccess.Export
@Override
public boolean hasPermission(String node) {
return sender.hasPermission(node);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package dev.neovoxel.neobot.adapter;

import com.hypixel.hytale.server.core.universe.Universe;
import org.graalvm.polyglot.HostAccess;

import java.util.UUID;

public class HytaleOfflinePlayer extends OfflinePlayer {
private UUID uuid;

public HytaleOfflinePlayer(String name, UUID uuid) {
super(name, uuid);
this.uuid = uuid;
}

@HostAccess.Export
@Override
public boolean isOnline() {
return Universe.get().getPlayer(uuid).isValid();
}
}
34 changes: 34 additions & 0 deletions hytale/src/main/java/dev/neovoxel/neobot/adapter/HytalePlayer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package dev.neovoxel.neobot.adapter;

import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.permissions.PermissionsModule;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import org.graalvm.polyglot.HostAccess;

public class HytalePlayer extends Player {

private final PlayerRef playerRef;

public HytalePlayer(PlayerRef playerRef) {
super(playerRef.getUsername(), playerRef.getUuid());
this.playerRef = playerRef;
}

@HostAccess.Export
@Override
public void sendMessage(String message) {
playerRef.sendMessage(Message.parse(message));
}

@HostAccess.Export
@Override
public void kick(String message) {
playerRef.getPacketHandler().disconnect(message);

}

@Override
public boolean hasPermission(String node) {
return PermissionsModule.get().hasPermission(playerRef.getUuid(), node);
}
}
Loading
Loading