Plex-FAWE/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRepository.java
Byron Marohn c0fa1602ad Restore the formatting of many things to upstream WorldEdit - no code changes
This patch touches many files but changes absolutely no functionality.
The goal here is to make future merges with worldedit produce fewer
conflicts that have to be resolved.

This patch was made by painstakingly diff'ing files and copying changes
over from the last upstream merge commit (02c6f11b) into this codebase.

Signed-off-by: Byron Marohn <combustible@live.com>
2018-12-20 11:33:56 -08:00

242 lines
6.7 KiB
Java

/*
* 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/>.
*/
// $Id$
package com.sk89q.worldedit.world.snapshot;
import com.sk89q.worldedit.world.storage.MissingWorldException;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
/**
* A repository contains zero or more snapshots.
*/
public class SnapshotRepository {
protected File dir;
protected List<SnapshotDateParser> dateParsers = new ArrayList<>();
/**
* Create a new instance of a repository.
*
* @param dir the directory
*/
public SnapshotRepository(File dir) {
this.dir = dir;
// If folder doesn't exist, make it
dir.mkdirs();
dateParsers.add(new YYMMDDHHIISSParser());
dateParsers.add(new ModificationTimerParser());
}
/**
* Create a new instance of a repository.
*
* @param dir the directory
*/
public SnapshotRepository(String dir) {
this(new File(dir));
}
/**
* Get a list of snapshots in a directory. The newest snapshot is
* near the top of the array.
*
* @param newestFirst true to get the newest first
* @return a list of snapshots
*/
public List<Snapshot> getSnapshots(boolean newestFirst, String worldName) throws MissingWorldException {
FilenameFilter filter = (dir, name) -> {
File f = new File(dir, name);
return isValidSnapshot(f);
};
File[] snapshotFiles = dir.listFiles();
if (snapshotFiles == null) {
throw new MissingWorldException(worldName);
}
List<Snapshot> list = new ArrayList<>(snapshotFiles.length);
for (File file : snapshotFiles) {
if (isValidSnapshot(file)) {
Snapshot snapshot = new Snapshot(this, file.getName());
if (snapshot.containsWorld(worldName)) {
detectDate(snapshot);
list.add(snapshot);
}
} else if (file.isDirectory() && file.getName().equalsIgnoreCase(worldName)) {
for (String name : file.list(filter)) {
Snapshot snapshot = new Snapshot(this, file.getName() + "/" + name);
detectDate(snapshot);
list.add(snapshot);
}
}
}
if (newestFirst) {
list.sort(Collections.reverseOrder());
} else {
Collections.sort(list);
}
return list;
}
/**
* Get the first snapshot after a date.
*
* @param date a date
* @return a snapshot or null
*/
@Nullable
public Snapshot getSnapshotAfter(Calendar date, String world) throws MissingWorldException {
List<Snapshot> snapshots = getSnapshots(true, world);
Snapshot last = null;
for (Snapshot snapshot : snapshots) {
if (snapshot.getDate() != null && snapshot.getDate().before(date)) {
return last;
}
last = snapshot;
}
return last;
}
/**
* Get the first snapshot before a date.
*
* @param date a date
* @return a snapshot or null
*/
@Nullable
public Snapshot getSnapshotBefore(Calendar date, String world) throws MissingWorldException {
List<Snapshot> snapshots = getSnapshots(false, world);
Snapshot last = null;
for (Snapshot snapshot : snapshots) {
if (snapshot.getDate().after(date)) {
return last;
}
last = snapshot;
}
return last;
}
/**
* Attempt to detect a snapshot's date and assign it.
*
* @param snapshot the snapshot
*/
protected void detectDate(Snapshot snapshot) {
for (SnapshotDateParser parser : dateParsers) {
Calendar date = parser.detectDate(snapshot.getFile());
if (date != null) {
snapshot.setDate(date);
return;
}
}
snapshot.setDate(null);
}
/**
* Get the default snapshot.
*
* @param world the world name
* @return a snapshot or null
*/
@Nullable
public Snapshot getDefaultSnapshot(String world) throws MissingWorldException {
List<Snapshot> snapshots = getSnapshots(true, world);
if (snapshots.isEmpty()) {
return null;
}
return snapshots.get(0);
}
/**
* Check to see if a snapshot is valid.
*
* @param snapshot a snapshot name
* @return whether it is a valid snapshot
*/
public boolean isValidSnapshotName(String snapshot) {
return isValidSnapshot(new File(dir, snapshot));
}
/**
* Check to see if a snapshot is valid.
*
* @param file the file to the snapshot
* @return whether it is a valid snapshot
*/
protected boolean isValidSnapshot(File file) {
if (!file.getName().matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+$")) {
return false;
}
return (file.isDirectory() && (new File(file, "level.dat")).exists())
|| (file.isFile() && (file.getName().toLowerCase().endsWith(".zip")
|| file.getName().toLowerCase().endsWith(".tar.bz2")
|| file.getName().toLowerCase().endsWith(".tar.gz")
|| file.getName().toLowerCase().endsWith(".tar")));
}
/**
* Get a snapshot.
*
* @param name the name of the snapshot
* @return a snapshot
* @throws InvalidSnapshotException if the snapshot is invalid
*/
public Snapshot getSnapshot(String name) throws InvalidSnapshotException {
if (!isValidSnapshotName(name)) {
throw new InvalidSnapshotException();
}
return new Snapshot(this, name);
}
/**
* Get the snapshot directory.
*
* @return a path
*/
public File getDirectory() {
return dir;
}
}