diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java index a40c2a5cf..82888e308 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java @@ -30,6 +30,8 @@ import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.MultiUserPlatform; import com.sk89q.worldedit.extension.platform.Preference; +import com.sk89q.worldedit.extension.platform.Watchdog; +import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.registry.Registries; import java.util.ArrayList; @@ -51,6 +53,14 @@ public class BukkitServerInterface implements MultiUserPlatform { public WorldEditPlugin plugin; private CommandRegistration dynamicCommands; private boolean hookingEvents; + private final LazyReference watchdog = LazyReference.from(() -> { + if (plugin.getBukkitImplAdapter() != null) { + return plugin.getBukkitImplAdapter().supportsWatchdog() + ? new BukkitWatchdog(plugin.getBukkitImplAdapter()) + : null; + } + return null; + }); public BukkitServerInterface(WorldEditPlugin plugin, Server server) { this.plugin = plugin; @@ -102,6 +112,11 @@ public class BukkitServerInterface implements MultiUserPlatform { return Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, task, delay, period); } + @Override + public Watchdog getWatchdog() { + return watchdog.getValue(); + } + @Override public List getWorlds() { List worlds = server.getWorlds(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWatchdog.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWatchdog.java new file mode 100644 index 000000000..1e37852a6 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWatchdog.java @@ -0,0 +1,38 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit; + +import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; +import com.sk89q.worldedit.extension.platform.Watchdog; + +class BukkitWatchdog implements Watchdog { + + private final BukkitImplAdapter adapter; + + BukkitWatchdog(BukkitImplAdapter adapter) { + this.adapter = adapter; + } + + @Override + public void tick() { + adapter.tickWatchdog(); + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index eef58ec76..0e249e316 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -19,14 +19,7 @@ package com.sk89q.worldedit; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.sk89q.worldedit.regions.Regions.asFlatRegion; -import static com.sk89q.worldedit.regions.Regions.maximumBlockY; -import static com.sk89q.worldedit.regions.Regions.minimumBlockY; - import com.boydti.fawe.FaweCache; -import com.boydti.fawe.beta.Filter; import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.FaweLimit; @@ -36,7 +29,6 @@ import com.boydti.fawe.object.changeset.BlockBagChangeSet; import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.collection.LocalBlockVectorSet; import com.boydti.fawe.object.extent.FaweRegionExtent; -import com.boydti.fawe.object.extent.NullExtent; import com.boydti.fawe.object.extent.ProcessedWEExtent; import com.boydti.fawe.object.extent.ResettableExtent; import com.boydti.fawe.object.extent.SourceMaskExtent; @@ -129,6 +121,10 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.ArrayList; @@ -141,10 +137,12 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.sk89q.worldedit.regions.Regions.asFlatRegion; +import static com.sk89q.worldedit.regions.Regions.maximumBlockY; +import static com.sk89q.worldedit.regions.Regions.minimumBlockY; /** * An {@link Extent} that handles history, {@link BlockBag}s, change limits, diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java index fcbd6ff29..d82ed52c1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java @@ -83,6 +83,15 @@ public interface Platform { */ int schedule(long delay, long period, Runnable task); + /** + * Get the watchdog service. + * + * @return the watchdog service, or {@code null} if none + */ + default @Nullable Watchdog getWatchdog() { + return null; + } + /** * Get a list of available or loaded worlds. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Watchdog.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Watchdog.java new file mode 100644 index 000000000..1f822f90f --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Watchdog.java @@ -0,0 +1,29 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extension.platform; + +/** + * Interface to a {@link Platform}'s watchdog service. + */ +public interface Watchdog { + + void tick(); + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/WatchdogTickingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/WatchdogTickingExtent.java new file mode 100644 index 000000000..bb06fb29f --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/WatchdogTickingExtent.java @@ -0,0 +1,72 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.world; + +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extension.platform.Watchdog; +import com.sk89q.worldedit.extent.AbstractDelegateExtent; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BlockStateHolder; + +import javax.annotation.Nullable; + +/** + * Extent that ticks the watchdog before every world-affecting action. + */ +public class WatchdogTickingExtent extends AbstractDelegateExtent { + + private final Watchdog watchdog; + + /** + * Create a new instance. + * + * @param extent the extent + * @param watchdog the watchdog to reset + */ + public WatchdogTickingExtent(Extent extent, Watchdog watchdog) { + super(extent); + this.watchdog = watchdog; + } + + @Override + public > boolean setBlock(BlockVector3 location, T block) throws WorldEditException { + watchdog.tick(); + return super.setBlock(location, block); + } + + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity) { + watchdog.tick(); + return super.createEntity(location, entity); + } + + @Override + public boolean setBiome(BlockVector2 position, BiomeType biome) { + watchdog.tick(); + return super.setBiome(position, biome); + } +} diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java new file mode 100644 index 000000000..00c63f4e4 --- /dev/null +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java @@ -0,0 +1,213 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.fabric; + +import com.sk89q.worldedit.command.util.PermissionCondition; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extension.platform.AbstractPlatform; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.MultiUserPlatform; +import com.sk89q.worldedit.extension.platform.Preference; +import com.sk89q.worldedit.fabric.mixin.MixinMinecraftServer; +import com.sk89q.worldedit.world.DataFixer; +import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.registry.Registries; +import net.minecraft.SharedConstants; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.PlayerManager; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import org.enginehub.piston.Command; +import org.enginehub.piston.CommandManager; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static java.util.stream.Collectors.toList; + +class FabricPlatform extends AbstractPlatform implements MultiUserPlatform { + + private final FabricWorldEdit mod; + private final MinecraftServer server; + private final FabricDataFixer dataFixer; + private final @Nullable FabricWatchdog watchdog; + private boolean hookingEvents = false; + + FabricPlatform(FabricWorldEdit mod, MinecraftServer server) { + this.mod = mod; + this.server = server; + this.dataFixer = new FabricDataFixer(getDataVersion()); + this.watchdog = server instanceof DedicatedServer + ? new FabricWatchdog((MixinMinecraftServer) (Object) server) : null; + } + + boolean isHookingEvents() { + return hookingEvents; + } + + @Override + public Registries getRegistries() { + return FabricRegistries.getInstance(); + } + + @Override + public int getDataVersion() { + return SharedConstants.getGameVersion().getWorldVersion(); + } + + @Override + public DataFixer getDataFixer() { + return dataFixer; + } + + @Override + public boolean isValidMobType(String type) { + return Registry.ENTITY_TYPE.containsId(new Identifier(type)); + } + + @Override + public void reload() { + getConfiguration().load(); + } + + @Override + public int schedule(long delay, long period, Runnable task) { + return -1; + } + + @Override + @Nullable + public FabricWatchdog getWatchdog() { + return watchdog; + } + + @Override + public List getWorlds() { + Iterable worlds = server.getWorlds(); + List ret = new ArrayList<>(); + for (ServerWorld world : worlds) { + ret.add(new FabricWorld(world)); + } + return ret; + } + + @Nullable + @Override + public Player matchPlayer(Player player) { + if (player instanceof FabricPlayer) { + return player; + } else { + ServerPlayerEntity entity = server.getPlayerManager().getPlayer(player.getName()); + return entity != null ? new FabricPlayer(entity) : null; + } + } + + @Nullable + @Override + public World matchWorld(World world) { + if (world instanceof FabricWorld) { + return world; + } else { + for (ServerWorld ws : server.getWorlds()) { + if (ws.getLevelProperties().getLevelName().equals(world.getName())) { + return new FabricWorld(ws); + } + } + + return null; + } + } + + @Override + public void registerCommands(CommandManager manager) { + if (server == null) return; + net.minecraft.server.command.CommandManager mcMan = server.getCommandManager(); + + for (Command command : manager.getAllCommands().collect(toList())) { + CommandWrapper.register(mcMan.getDispatcher(), command); + Set perms = command.getCondition().as(PermissionCondition.class) + .map(PermissionCondition::getPermissions) + .orElseGet(Collections::emptySet); + if (!perms.isEmpty()) { + perms.forEach(FabricWorldEdit.inst.getPermissionsProvider()::registerPermission); + } + } + } + + @Override + public void registerGameHooks() { + // We registered the events already anyway, so we just 'turn them on' + hookingEvents = true; + } + + @Override + public FabricConfiguration getConfiguration() { + return mod.getConfig(); + } + + @Override + public String getVersion() { + return mod.getInternalVersion(); + } + + @Override + public String getPlatformName() { + return "Fabric-Official"; + } + + @Override + public String getPlatformVersion() { + return mod.getInternalVersion(); + } + + @Override + public Map getCapabilities() { + Map capabilities = new EnumMap<>(Capability.class); + capabilities.put(Capability.CONFIGURATION, Preference.PREFER_OTHERS); + capabilities.put(Capability.WORLDEDIT_CUI, Preference.NORMAL); + capabilities.put(Capability.GAME_HOOKS, Preference.NORMAL); + capabilities.put(Capability.PERMISSIONS, Preference.NORMAL); + capabilities.put(Capability.USER_COMMANDS, Preference.NORMAL); + capabilities.put(Capability.WORLD_EDITING, Preference.PREFERRED); + return capabilities; + } + + @Override + public Collection getConnectedUsers() { + List users = new ArrayList<>(); + PlayerManager scm = server.getPlayerManager(); + for (ServerPlayerEntity entity : scm.getPlayerList()) { + if (entity != null) { + users.add(new FabricPlayer(entity)); + } + } + return users; + } +} diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWatchdog.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWatchdog.java new file mode 100644 index 000000000..554e14b9d --- /dev/null +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWatchdog.java @@ -0,0 +1,19 @@ +package com.sk89q.worldedit.fabric; + +import com.sk89q.worldedit.extension.platform.Watchdog; +import com.sk89q.worldedit.fabric.mixin.MixinMinecraftServer; +import net.minecraft.util.SystemUtil; + +class FabricWatchdog implements Watchdog { + + private final MixinMinecraftServer server; + + FabricWatchdog(MixinMinecraftServer server) { + this.server = server; + } + + @Override + public void tick() { + server.timeReference = SystemUtil.getMeasuringTimeMs(); + } +} diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinMinecraftServer.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinMinecraftServer.java new file mode 100644 index 000000000..597871cea --- /dev/null +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinMinecraftServer.java @@ -0,0 +1,20 @@ +package com.sk89q.worldedit.fabric.mixin; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.ServerTask; +import net.minecraft.server.command.CommandOutput; +import net.minecraft.util.NonBlockingThreadExecutor; +import net.minecraft.util.snooper.SnooperListener; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(MinecraftServer.class) +public abstract class MixinMinecraftServer extends NonBlockingThreadExecutor implements SnooperListener, CommandOutput, AutoCloseable, Runnable { + + public MixinMinecraftServer(String string_1) { + super(string_1); + } + + @Shadow + public long timeReference; +} diff --git a/worldedit-fabric/src/main/resources/worldedit.mixins.json b/worldedit-fabric/src/main/resources/worldedit.mixins.json new file mode 100644 index 000000000..ecd0ffd49 --- /dev/null +++ b/worldedit-fabric/src/main/resources/worldedit.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "package": "com.sk89q.worldedit.fabric.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "MixinServerPlayerEntity", + "MixinMinecraftServer" + ], + "server": [ + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/worldedit-forge/build.gradle.kts b/worldedit-forge/build.gradle.kts new file mode 100644 index 000000000..b339aa62b --- /dev/null +++ b/worldedit-forge/build.gradle.kts @@ -0,0 +1,115 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import net.minecraftforge.gradle.common.util.RunConfig +import net.minecraftforge.gradle.userdev.UserDevExtension +import net.minecraftforge.gradle.userdev.tasks.GenerateSRG +import net.minecraftforge.gradle.userdev.tasks.RenameJarInPlace + +plugins { + id("net.minecraftforge.gradle") +} + +applyPlatformAndCoreConfiguration() +applyShadowConfiguration() + +val minecraftVersion = "1.14.4" +val mappingsMinecraftVersion = "1.14.3" +val forgeVersion = "28.1.0" + +configurations.all { + resolutionStrategy { + force("com.google.guava:guava:21.0") + } +} + +dependencies { + "compile"(project(":worldedit-core")) + "compile"("org.apache.logging.log4j:log4j-slf4j-impl:2.11.2") + + "minecraft"("net.minecraftforge:forge:$minecraftVersion-$forgeVersion") +} + +configure { + mappings(mapOf( + "channel" to "snapshot", + "version" to "20190913-$mappingsMinecraftVersion" + )) + + accessTransformer(file("src/main/resources/META-INF/accesstransformer.cfg")) + + runs { + val runConfig = Action { + properties(mapOf( + "forge.logging.markers" to "SCAN,REGISTRIES,REGISTRYDUMP", + "forge.logging.console.level" to "debug" + )) + workingDirectory = project.file("run").canonicalPath + source(sourceSets["main"]) + } + create("client", runConfig) + create("server", runConfig) + } + +} + +configure { + archivesBaseName = "$archivesBaseName-mc$minecraftVersion" +} + +tasks.named("processResources") { + // this will ensure that this task is redone when the versions change. + inputs.property("version", project.ext["internalVersion"]) + inputs.property("forgeVersion", forgeVersion) + + // replace stuff in mcmod.info, nothing else + from(sourceSets["main"].resources.srcDirs) { + include("META-INF/mods.toml") + + // replace version and mcversion + expand( + "version" to project.ext["internalVersion"], + "forgeVersion" to forgeVersion + ) + } + + // copy everything else except the mcmod.info + from(sourceSets["main"].resources.srcDirs) { + exclude("META-INF/mods.toml") + } +} + +tasks.named("jar") { + manifest { + attributes("WorldEdit-Version" to project.version) + } +} + +tasks.named("shadowJar") { + dependencies { + relocate("org.slf4j", "com.sk89q.worldedit.slf4j") + relocate("org.apache.logging.slf4j", "com.sk89q.worldedit.log4jbridge") + + include(dependency("org.slf4j:slf4j-api")) + include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) + include(dependency("de.schlichtherle:truezip")) + include(dependency("org.mozilla:rhino")) + } + minimize { + exclude(dependency("org.mozilla:rhino")) + } +} + +afterEvaluate { + val reobf = extensions.getByName>("reobf") + reobf.maybeCreate("shadowJar").run { + mappings = tasks.getByName("createMcpToSrg").output + } +} + +tasks.register("deobfJar") { + from(sourceSets["main"].output) + archiveClassifier.set("dev") +} + +artifacts { + add("archives", tasks.named("deobfJar")) +} diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java index 0530acc54..bee73aa69 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java @@ -32,6 +32,7 @@ import com.sk89q.worldedit.world.registry.Registries; import net.minecraft.command.Commands; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.management.PlayerList; import net.minecraft.util.ResourceLocation; import net.minecraft.world.WorldServer; @@ -48,11 +49,16 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform { private final ForgeWorldEdit mod; private final MinecraftServer server; + private final ForgeDataFixer dataFixer; + private final @Nullable ForgeWatchdog watchdog; private boolean hookingEvents = false; ForgePlatform(ForgeWorldEdit mod) { this.mod = mod; this.server = ServerLifecycleHooks.getCurrentServer(); + this.dataFixer = new ForgeDataFixer(getDataVersion()); + this.watchdog = server instanceof DedicatedServer + ? new ForgeWatchdog((DedicatedServer) server) : null; } boolean isHookingEvents() { @@ -84,6 +90,16 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform { Iterable worlds = server.getWorlds(); List ret = new ArrayList<>(); for (WorldServer world : worlds) { + @Nullable + public ForgeWatchdog getWatchdog() { + return watchdog; + } + + @Override + public List getWorlds() { + Iterable worlds = server.getWorlds(); + List ret = new ArrayList<>(); + for (ServerWorld world : worlds) { ret.add(new ForgeWorld(world)); } return ret; diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWatchdog.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWatchdog.java new file mode 100644 index 000000000..25f72c2c5 --- /dev/null +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWatchdog.java @@ -0,0 +1,38 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.forge; + +import com.sk89q.worldedit.extension.platform.Watchdog; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.util.Util; + +class ForgeWatchdog implements Watchdog { + + private final DedicatedServer server; + + ForgeWatchdog(DedicatedServer server) { + this.server = server; + } + + @Override + public void tick() { + server.serverTime = Util.milliTime(); + } +} diff --git a/worldedit-forge/src/main/resources/META-INF/accesstransformer.cfg b/worldedit-forge/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 000000000..9c1530b89 --- /dev/null +++ b/worldedit-forge/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1 @@ +public net.minecraft.server.MinecraftServer field_211151_aa # serverTime \ No newline at end of file