/* * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion * Copyright (C) 2016-2024 ViaVersion and contributors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.viaversion.viaversion; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.command.ViaCommandSender; import com.viaversion.viaversion.api.platform.PlatformTask; import com.viaversion.viaversion.api.platform.ViaPlatform; import com.viaversion.viaversion.dump.PluginInfo; import com.viaversion.viaversion.sponge.commands.SpongeCommandHandler; import com.viaversion.viaversion.sponge.commands.SpongePlayer; import com.viaversion.viaversion.sponge.platform.SpongeViaAPI; import com.viaversion.viaversion.sponge.platform.SpongeViaConfig; import com.viaversion.viaversion.sponge.platform.SpongeViaInjector; import com.viaversion.viaversion.sponge.platform.SpongeViaLoader; import com.viaversion.viaversion.sponge.platform.SpongeViaTask; import com.viaversion.viaversion.sponge.util.LoggerWrapper; import com.viaversion.viaversion.util.GsonUtil; import java.io.File; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.UUID; import java.util.logging.Logger; import java.util.stream.Collectors; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.spongepowered.api.Game; import org.spongepowered.api.Platform; import org.spongepowered.api.Server; import org.spongepowered.api.Sponge; import org.spongepowered.api.command.Command; import org.spongepowered.api.config.ConfigDir; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.entity.living.player.server.ServerPlayer; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.lifecycle.ConstructPluginEvent; import org.spongepowered.api.event.lifecycle.StartedEngineEvent; import org.spongepowered.api.event.lifecycle.StartingEngineEvent; import org.spongepowered.api.event.lifecycle.StoppingEngineEvent; import org.spongepowered.api.scheduler.Task; import org.spongepowered.api.util.Ticks; import org.spongepowered.plugin.PluginContainer; import org.spongepowered.plugin.builtin.jvm.Plugin; import org.spongepowered.plugin.metadata.PluginMetadata; import org.spongepowered.plugin.metadata.model.PluginContributor; @Plugin("viaversion") public class SpongePlugin implements ViaPlatform { public static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.builder().extractUrls().build(); private final SpongeViaAPI api = new SpongeViaAPI(); private final PluginContainer container; private final Game game; @SuppressWarnings("SpongeLogging") private final Logger logger; private SpongeViaConfig conf; @Inject @ConfigDir(sharedRoot = false) private Path configDir; @Inject SpongePlugin(final PluginContainer container, final Game game, final org.apache.logging.log4j.Logger logger) { this.container = container; this.game = game; this.logger = new LoggerWrapper(logger); } @Listener public void constructPlugin(ConstructPluginEvent event) { // Setup Plugin conf = new SpongeViaConfig(configDir.toFile()); // Init platform Via.init(ViaManagerImpl.builder() .platform(this) .commandHandler(new SpongeCommandHandler()) .injector(new SpongeViaInjector()) .loader(new SpongeViaLoader(this)) .build()); } @Listener public void onServerStart(StartingEngineEvent event) { // Can't use the command register event for raw commands... Sponge.server().commandManager().registrar(Command.Raw.class).get().register(container, (Command.Raw) Via.getManager().getCommandHandler(), "viaversion", "viaver", "vvsponge"); final ViaManagerImpl manager = (ViaManagerImpl) Via.getManager(); manager.init(); } @Listener public void onServerStarted(StartedEngineEvent event) { final ViaManagerImpl manager = (ViaManagerImpl) Via.getManager(); manager.onServerLoaded(); } @Listener public void onServerStop(StoppingEngineEvent event) { ((ViaManagerImpl) Via.getManager()).destroy(); } @Override public String getPlatformName() { return game.platform().container(Platform.Component.IMPLEMENTATION).metadata().name().orElse("unknown"); } @Override public String getPlatformVersion() { return game.platform().container(Platform.Component.IMPLEMENTATION).metadata().version().toString(); } @Override public String getPluginVersion() { return container.metadata().version().toString(); } @Override public PlatformTask runAsync(Runnable runnable) { final Task task = Task.builder().plugin(container).execute(runnable).build(); return new SpongeViaTask(game.asyncScheduler().submit(task)); } @Override public PlatformTask runRepeatingAsync(final Runnable runnable, final long ticks) { final Task task = Task.builder().plugin(container).execute(runnable).interval(Ticks.of(ticks)).build(); return new SpongeViaTask(game.asyncScheduler().submit(task)); } @Override public PlatformTask runSync(Runnable runnable) { final Task task = Task.builder().plugin(container).execute(runnable).build(); return new SpongeViaTask(game.server().scheduler().submit(task)); } @Override public PlatformTask runSync(Runnable runnable, long delay) { final Task task = Task.builder().plugin(container).execute(runnable).delay(Ticks.of(delay)).build(); return new SpongeViaTask(game.server().scheduler().submit(task)); } @Override public PlatformTask runRepeatingSync(Runnable runnable, long period) { final Task task = Task.builder().plugin(container).execute(runnable).interval(Ticks.of(period)).build(); return new SpongeViaTask(game.server().scheduler().submit(task)); } @Override public ViaCommandSender[] getOnlinePlayers() { Collection players = game.server().onlinePlayers(); ViaCommandSender[] array = new ViaCommandSender[players.size()]; int i = 0; for (ServerPlayer player : players) { array[i++] = new SpongePlayer(player); } return array; } @Override public void sendMessage(UUID uuid, String message) { game.server().player(uuid).ifPresent(player -> player.sendMessage(LEGACY_SERIALIZER.deserialize(message))); } @Override public boolean kickPlayer(UUID uuid, String message) { return game.server().player(uuid).map(player -> { player.kick(LegacyComponentSerializer.legacySection().deserialize(message)); return true; }).orElse(false); } @Override public boolean isPluginEnabled() { return true; } @Override public File getDataFolder() { return configDir.toFile(); } @Override public void onReload() { logger.severe("ViaVersion is already loaded, this should work fine. If you get any console errors, try rebooting."); } @Override public JsonObject getDump() { JsonObject platformSpecific = new JsonObject(); List plugins = new ArrayList<>(); for (PluginContainer plugin : game.pluginManager().plugins()) { PluginMetadata metadata = plugin.metadata(); plugins.add(new PluginInfo( true, metadata.name().orElse("Unknown"), metadata.version().toString(), plugin.instance().getClass().getCanonicalName(), metadata.contributors().stream().map(PluginContributor::name).collect(Collectors.toList()) )); } platformSpecific.add("plugins", GsonUtil.getGson().toJsonTree(plugins)); return platformSpecific; } @Override public boolean hasPlugin(final String name) { return game.pluginManager().plugin(name).isPresent(); } @Override public SpongeViaAPI getApi() { return api; } @Override public SpongeViaConfig getConf() { return conf; } @Override public Logger getLogger() { return logger; } public PluginContainer container() { return container; } }