mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-06-13 21:13:53 +00:00
Cherry-pick to fix EntryMaker issue
This commit is contained in:
committed by
IronApollo
parent
735a37ffd0
commit
ff47e6f717
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.world.snapshot.experimental.fs;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.sk89q.worldedit.world.storage.LegacyChunkStore;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import static com.sk89q.worldedit.world.snapshot.experimental.fs.FileSystemSnapshotDatabaseTest.CHUNK_DATA;
|
||||
import static com.sk89q.worldedit.world.snapshot.experimental.fs.FileSystemSnapshotDatabaseTest.CHUNK_POS;
|
||||
import static com.sk89q.worldedit.world.snapshot.experimental.fs.FileSystemSnapshotDatabaseTest.FORMATTER;
|
||||
import static com.sk89q.worldedit.world.snapshot.experimental.fs.FileSystemSnapshotDatabaseTest.REGION_DATA;
|
||||
|
||||
interface EntryMaker<T> {
|
||||
EntryMaker<ZonedDateTime> TIMESTAMPED_DIR = (directory, time) -> {
|
||||
Path timestampedDir = directory.resolve(time.format(FORMATTER));
|
||||
Files.createDirectories(timestampedDir);
|
||||
return timestampedDir;
|
||||
};
|
||||
EntryMaker<ZonedDateTime> TIMESTAMPED_ARCHIVE = (directory, time) -> {
|
||||
Path zipFile = directory.resolve(time.format(FORMATTER) + ".zip");
|
||||
try (FileSystem zipFs = FileSystems.newFileSystem(
|
||||
URI.create("jar:" + zipFile.toUri() + "!/"),
|
||||
ImmutableMap.of("create", "true")
|
||||
)) {
|
||||
TIMESTAMPED_DIR.createEntry(zipFs.getPath("/"), time);
|
||||
}
|
||||
return zipFile;
|
||||
};
|
||||
EntryMaker<String> WORLD_DIR = (directory, worldName) -> {
|
||||
Path worldDir = directory.resolve(worldName);
|
||||
Files.createDirectories(worldDir);
|
||||
Files.createFile(worldDir.resolve("level.dat"));
|
||||
Path regionFolder = worldDir.resolve("region");
|
||||
Files.createDirectory(regionFolder);
|
||||
Files.write(regionFolder.resolve("r.0.0.mca"), REGION_DATA);
|
||||
Files.write(regionFolder.resolve("r.1.1.mcr"), REGION_DATA);
|
||||
return worldDir;
|
||||
};
|
||||
|
||||
class DimInfo {
|
||||
final String worldName;
|
||||
final int dim;
|
||||
|
||||
DimInfo(String worldName, int dim) {
|
||||
this.worldName = worldName;
|
||||
this.dim = dim;
|
||||
}
|
||||
}
|
||||
|
||||
EntryMaker<DimInfo> WORLD_DIM_DIR = (directory, dimInfo) -> {
|
||||
Path worldDir = directory.resolve(dimInfo.worldName);
|
||||
Files.createDirectories(worldDir);
|
||||
Files.createFile(worldDir.resolve("level.dat"));
|
||||
Path dimFolder = worldDir.resolve("DIM" + dimInfo.dim).resolve("region");
|
||||
Files.createDirectories(dimFolder);
|
||||
Files.write(dimFolder.resolve("r.0.0.mca"), REGION_DATA);
|
||||
Files.write(dimFolder.resolve("r.1.1.mcr"), REGION_DATA);
|
||||
return worldDir;
|
||||
};
|
||||
EntryMaker<String> WORLD_NO_REGION_DIR = (directory, worldName) -> {
|
||||
Path worldDir = directory.resolve(worldName);
|
||||
Files.createDirectories(worldDir);
|
||||
Files.createFile(worldDir.resolve("level.dat"));
|
||||
Files.write(worldDir.resolve("r.0.0.mca"), REGION_DATA);
|
||||
Files.write(worldDir.resolve("r.1.1.mcr"), REGION_DATA);
|
||||
return worldDir;
|
||||
};
|
||||
EntryMaker<String> WORLD_LEGACY_DIR = (directory, worldName) -> {
|
||||
Path worldDir = directory.resolve(worldName);
|
||||
Files.createDirectories(worldDir);
|
||||
Files.createFile(worldDir.resolve("level.dat"));
|
||||
Path chunkFile = worldDir.resolve(LegacyChunkStore.getFilename(
|
||||
CHUNK_POS.toBlockVector2(), "/"
|
||||
));
|
||||
Files.createDirectories(chunkFile.getParent());
|
||||
Files.write(chunkFile, CHUNK_DATA);
|
||||
chunkFile = worldDir.resolve(LegacyChunkStore.getFilename(
|
||||
CHUNK_POS.add(32, 0, 32).toBlockVector2(), "/"
|
||||
));
|
||||
Files.createDirectories(chunkFile.getParent());
|
||||
Files.write(chunkFile, CHUNK_DATA);
|
||||
return worldDir;
|
||||
};
|
||||
EntryMaker<String> WORLD_ARCHIVE = (directory, worldName) -> {
|
||||
Path tempDir = Files.createTempDirectory("worldedit-fs-snap-db" + worldName);
|
||||
Path temp = tempDir.resolve(worldName + ".zip");
|
||||
try {
|
||||
Files.deleteIfExists(temp);
|
||||
try (FileSystem zipFs = FileSystems.newFileSystem(
|
||||
URI.create("jar:" + temp.toUri() + "!/"),
|
||||
ImmutableMap.of("create", "true")
|
||||
)) {
|
||||
WORLD_DIR.createEntry(zipFs.getPath("/"), worldName);
|
||||
}
|
||||
Path zipFile = directory.resolve(worldName + ".zip");
|
||||
Files.copy(temp, zipFile);
|
||||
return zipFile;
|
||||
} finally {
|
||||
Files.deleteIfExists(temp);
|
||||
Files.deleteIfExists(tempDir);
|
||||
}
|
||||
};
|
||||
|
||||
Path createEntry(Path directory, T name) throws IOException;
|
||||
|
||||
}
|
@ -19,8 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.world.snapshot.experimental.fs;
|
||||
|
||||
import com.sk89q.worldedit.util.io.Closer;
|
||||
import com.sk89q.worldedit.util.io.file.ArchiveDir;
|
||||
import com.sk89q.worldedit.util.io.file.ArchiveNioSupport;
|
||||
import com.sk89q.worldedit.world.snapshot.experimental.Snapshot;
|
||||
|
||||
@ -30,7 +28,6 @@ import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
@ -70,34 +67,19 @@ class FSSDContext {
|
||||
String worldName = Paths.get(name).getFileName().toString();
|
||||
// Without an extension
|
||||
worldName = worldName.split("\\.")[0];
|
||||
List<Snapshot> snapshots;
|
||||
try (Stream<Snapshot> snapshotStream = db.getSnapshots(worldName)) {
|
||||
snapshots = snapshotStream.collect(toList());
|
||||
}
|
||||
try {
|
||||
assertTrue(snapshots.size() <= 1,
|
||||
"Too many snapshots matched for " + worldName);
|
||||
return requireSnapshot(name, snapshots.stream().findAny().orElse(null));
|
||||
} catch (Throwable t) {
|
||||
Closer closer = Closer.create();
|
||||
snapshots.forEach(closer::register);
|
||||
throw closer.rethrowAndClose(t);
|
||||
}
|
||||
List<Snapshot> snapshots = db.getSnapshots(worldName).collect(toList());
|
||||
assertTrue(1 >= snapshots.size(),
|
||||
"Too many snapshots matched for " + worldName);
|
||||
return requireSnapshot(name, snapshots.stream().findAny().orElse(null));
|
||||
}
|
||||
|
||||
Snapshot requireSnapshot(String name, @Nullable Snapshot snapshot) throws IOException {
|
||||
Snapshot requireSnapshot(String name, @Nullable Snapshot snapshot) {
|
||||
assertNotNull(snapshot, "No snapshot for " + name);
|
||||
try {
|
||||
assertEquals(name, snapshot.getInfo().getDisplayName());
|
||||
} catch (Throwable t) {
|
||||
Closer closer = Closer.create();
|
||||
closer.register(snapshot);
|
||||
throw closer.rethrowAndClose(t);
|
||||
}
|
||||
assertEquals(name, snapshot.getInfo().getDisplayName());
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
ArchiveDir getRootOfArchive(Path archive) throws IOException {
|
||||
Path getRootOfArchive(Path archive) throws IOException {
|
||||
return archiveNioSupport.tryOpenAsDir(archive)
|
||||
.orElseThrow(() -> new AssertionError("No archive opener for " + archive));
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ package com.sk89q.worldedit.world.snapshot.experimental.fs;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.io.file.ArchiveDir;
|
||||
import com.sk89q.worldedit.world.DataException;
|
||||
import com.sk89q.worldedit.world.snapshot.experimental.Snapshot;
|
||||
import org.junit.jupiter.api.DynamicNode;
|
||||
@ -30,6 +29,7 @@ import org.junit.jupiter.api.DynamicTest;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
@ -38,8 +38,8 @@ import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.sk89q.worldedit.world.snapshot.experimental.fs.FileSystemSnapshotDatabaseTest.CHUNK_POS;
|
||||
import static com.sk89q.worldedit.world.snapshot.experimental.fs.FileSystemSnapshotDatabaseTest.CHUNK_TAG;
|
||||
import static com.sk89q.worldedit.world.snapshot.experimental.fs.FileSystemSnapshotDatabaseTest.CHUNK_POS;
|
||||
import static com.sk89q.worldedit.world.snapshot.experimental.fs.FileSystemSnapshotDatabaseTest.TIME_ONE;
|
||||
import static com.sk89q.worldedit.world.snapshot.experimental.fs.FileSystemSnapshotDatabaseTest.TIME_TWO;
|
||||
import static com.sk89q.worldedit.world.snapshot.experimental.fs.FileSystemSnapshotDatabaseTest.WORLD_ALPHA;
|
||||
@ -102,11 +102,16 @@ enum FSSDTestType {
|
||||
List<DynamicTest> getTests(FSSDContext context) throws IOException {
|
||||
Path worldArchive = EntryMaker.WORLD_ARCHIVE
|
||||
.createEntry(context.db.getRoot(), WORLD_ALPHA);
|
||||
try (ArchiveDir rootOfArchive = context.getRootOfArchive(worldArchive)) {
|
||||
Path rootOfArchive = context.getRootOfArchive(worldArchive);
|
||||
try {
|
||||
Files.setLastModifiedTime(
|
||||
rootOfArchive.getPath(),
|
||||
rootOfArchive,
|
||||
FileTime.from(TIME_ONE.toInstant())
|
||||
);
|
||||
} finally {
|
||||
if (rootOfArchive.getFileSystem() != FileSystems.getDefault()) {
|
||||
rootOfArchive.getFileSystem().close();
|
||||
}
|
||||
}
|
||||
return singleSnapTest(context, WORLD_ALPHA + ".zip", TIME_ONE);
|
||||
}
|
||||
@ -139,9 +144,14 @@ enum FSSDTestType {
|
||||
Path root = context.db.getRoot();
|
||||
Path timestampedArchive = EntryMaker.TIMESTAMPED_ARCHIVE
|
||||
.createEntry(root, TIME_ONE);
|
||||
try (ArchiveDir timestampedDir = context.getRootOfArchive(timestampedArchive)) {
|
||||
EntryMaker.WORLD_DIR.createEntry(timestampedDir.getPath(), WORLD_ALPHA);
|
||||
EntryMaker.WORLD_ARCHIVE.createEntry(timestampedDir.getPath(), WORLD_BETA);
|
||||
Path timestampedDir = context.getRootOfArchive(timestampedArchive);
|
||||
try {
|
||||
EntryMaker.WORLD_DIR.createEntry(timestampedDir, WORLD_ALPHA);
|
||||
EntryMaker.WORLD_ARCHIVE.createEntry(timestampedDir, WORLD_BETA);
|
||||
} finally {
|
||||
if (timestampedDir.getFileSystem() != FileSystems.getDefault()) {
|
||||
timestampedDir.getFileSystem().close();
|
||||
}
|
||||
}
|
||||
return ImmutableList.of(
|
||||
dynamicContainer("world dir",
|
||||
@ -251,18 +261,16 @@ enum FSSDTestType {
|
||||
}
|
||||
};
|
||||
|
||||
List<DynamicTest> singleSnapTest(FSSDContext context, String name,
|
||||
private static List<DynamicTest> singleSnapTest(FSSDContext context, String name,
|
||||
ZonedDateTime time) {
|
||||
return ImmutableList.of(
|
||||
dynamicTest("return a valid snapshot for " + name, () -> {
|
||||
try (Snapshot snapshot = context.requireSnapshot(name)) {
|
||||
assertValidSnapshot(time, snapshot);
|
||||
}
|
||||
Snapshot snapshot = context.requireSnapshot(name);
|
||||
assertValidSnapshot(time, snapshot);
|
||||
}),
|
||||
dynamicTest("list a valid snapshot for " + name, () -> {
|
||||
try (Snapshot snapshot = context.requireListsSnapshot(name)) {
|
||||
assertValidSnapshot(time, snapshot);
|
||||
}
|
||||
Snapshot snapshot = context.requireListsSnapshot(name);
|
||||
assertValidSnapshot(time, snapshot);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ import com.sk89q.worldedit.util.io.file.ZipArchiveNioSupport;
|
||||
import com.sk89q.worldedit.world.DataException;
|
||||
import com.sk89q.worldedit.world.storage.ChunkStoreHelper;
|
||||
import com.sk89q.worldedit.world.storage.McRegionReader;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.DynamicNode;
|
||||
@ -77,8 +76,6 @@ class FileSystemSnapshotDatabaseTest {
|
||||
.atZone(ZoneId.systemDefault());
|
||||
static final ZonedDateTime TIME_TWO = TIME_ONE.minusDays(1);
|
||||
|
||||
private static Path TEMP_DIR;
|
||||
|
||||
@BeforeAll
|
||||
static void setUpStatic() throws IOException, DataException {
|
||||
try (InputStream in = Resources.getResource("world_region.mca.gzip").openStream();
|
||||
@ -107,17 +104,10 @@ class FileSystemSnapshotDatabaseTest {
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
|
||||
TEMP_DIR = Files.createTempDirectory("worldedit-fs-snap-dbs");
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void afterAll() throws IOException {
|
||||
deleteTree(TEMP_DIR);
|
||||
}
|
||||
|
||||
private static Path newTempDb() throws IOException {
|
||||
return Files.createTempDirectory(TEMP_DIR, "db");
|
||||
return Files.createTempDirectory("worldedit-fs-snap-db");
|
||||
}
|
||||
|
||||
private static void deleteTree(Path root) throws IOException {
|
||||
@ -185,6 +175,7 @@ class FileSystemSnapshotDatabaseTest {
|
||||
try {
|
||||
Path dbRoot = root.resolve("snapshots");
|
||||
Files.createDirectories(dbRoot);
|
||||
// we leak `root` here, but I can't see a good way to clean it up.
|
||||
return type.getNamedTests(new FSSDContext(nioSupport, dbRoot));
|
||||
} catch (Throwable t) {
|
||||
deleteTree(root);
|
||||
|
BIN
worldedit-core/src/test/resources/world_region.mca.gzip
Normal file
BIN
worldedit-core/src/test/resources/world_region.mca.gzip
Normal file
Binary file not shown.
Reference in New Issue
Block a user