Commit 608bcfc6 authored by Nico Eckes's avatar Nico Eckes

switched to burst query when loading playerdata

parent cccfb57b
Pipeline #797 passed with stage
in 3 minutes and 3 seconds
......@@ -27,22 +27,21 @@ import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public abstract class ExtendedList<T> extends VBox {
@FXML public Label title;
@FXML public HBox header;
@FXML public TextField searchField;
@FXML public TextField addField;
private static final Image removeImg = new Image(ExtendedList.class.getResourceAsStream("../img/remove.png"));
@FXML Label title;
@FXML private HBox header;
@FXML private TextField searchField;
@FXML TextField addField;
@FXML public ListView<T> list;
@FXML public HBox toolbar;
ObservableList<T> items;
public final ObjectProperty<T> selectedItem = new SimpleObjectProperty<>();
@FXML HBox toolbar;
private ObservableList<T> items;
private final ObjectProperty<T> selectedItem = new SimpleObjectProperty<>();
public ExtendedList() {
ExtendedList() {
FXMLLoader loader = new FXMLLoader(ExtendedList.class.getResource("ExtendedList.fxml"));
loader.setController(this);
try {
......@@ -53,7 +52,7 @@ public abstract class ExtendedList<T> extends VBox {
}
@FXML
public void initialize() {
void initialize() {
setSource(FXCollections.observableArrayList());
list.setCellFactory(param -> new RemoveableEntry());
......@@ -66,15 +65,11 @@ public abstract class ExtendedList<T> extends VBox {
for (T sel : new ArrayList<>(list.getSelectionModel().getSelectedItems())) {
items.remove(sel);
}
return;
}
if (event.getCode() == KeyCode.C && event.isControlDown()) {
} else if (event.getCode() == KeyCode.C && event.isControlDown()) {
String s = list.getSelectionModel().getSelectedItems().stream().map(Object::toString).collect(Collectors.joining("\n"));
if (!s.isEmpty())
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(s), null);
return;
}
if (event.getCode() == KeyCode.V && event.isControlDown()) {
} else if (event.getCode() == KeyCode.V && event.isControlDown()) {
try {
String paste = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
if (paste == null) return;
......@@ -84,7 +79,6 @@ public abstract class ExtendedList<T> extends VBox {
} catch (UnsupportedFlavorException | IOException ignored) {
}
return;
}
});
......@@ -151,7 +145,7 @@ public abstract class ExtendedList<T> extends VBox {
setMinWidth(0);
setPrefWidth(1);
ImageView removeBtn = new ImageView(new Image(getClass().getResourceAsStream("../img/remove.png")));
ImageView removeBtn = new ImageView(removeImg);
removeBtn.setOnMouseClicked(event -> items.remove(item));
Node node = provideNode(item);
setGraphic(new StackPane(node, removeBtn));
......
package com.unitedworldminers.permio.editor.component;
import com.unitedworldminers.permio.editor.data.Group;
import com.unitedworldminers.permio.editor.data.Player;
import com.unitedworldminers.permio.editor.screen.MainScreen;
import com.unitedworldminers.permio.editor.util.Utils;
import javafx.collections.ListChangeListener;
import javafx.scene.Node;
import javafx.scene.control.Label;
......
......@@ -50,7 +50,7 @@ public class PermissionList extends ExtendedList<String> {
}
private static class PermissionLabel extends TextFlow {
public static void reloadColors() {
static void reloadColors() {
colors.recolorAll();
}
......@@ -60,7 +60,7 @@ public class PermissionList extends ExtendedList<String> {
private final String text;
public PermissionLabel(@NotNull String text) {
PermissionLabel(@NotNull String text) {
this.text = text;
final ColorMap[] map = new ColorMap[]{colors};
String[] parts = text.split("\\.");
......@@ -83,7 +83,7 @@ public class PermissionList extends ExtendedList<String> {
}
private static class ColorMap extends HashMap<String, ColorMapEntry> {
public void recolorAll() {
void recolorAll() {
for (ColorMapEntry e: values()) {
e.color = nextColor();
e.map.recolorAll();
......@@ -92,8 +92,8 @@ public class PermissionList extends ExtendedList<String> {
}
private static class ColorMapEntry {
public Color color = nextColor();
public ColorMap map = new ColorMap();
Color color = nextColor();
final ColorMap map = new ColorMap();
}
@NotNull
......
......@@ -2,7 +2,6 @@ package com.unitedworldminers.permio.editor.component;
import com.unitedworldminers.permio.editor.data.Player;
import com.unitedworldminers.permio.editor.data.PlayerProfile;
import com.unitedworldminers.permio.editor.screen.GroupsScreen;
import com.unitedworldminers.permio.editor.screen.MainScreen;
import com.unitedworldminers.permio.editor.util.Utils;
import javafx.geometry.Insets;
......
......@@ -10,7 +10,6 @@ import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.scene.control.Alert;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.VFS;
......@@ -40,23 +39,18 @@ public class GroupData implements ObservableList<Group> {
});
}
public GroupData(FileObject file) throws LoadException {
public GroupData(FileObject file) throws LoadException, FileSystemException {
this();
this.file = file;
Map<String, Map<String, Object>> rawGroups;
try {
rawGroups = YamlUtil.loadYaml(file.getContent());
} catch (FileSystemException e) {
throw new LoadException("Could not load groups from " + file.getPublicURIString(), e);
}
Map<String, Map<String, Object>> rawGroups = YamlUtil.loadYaml(file.getContent());
if (rawGroups == null) throw new LoadException("Could not load groups from " + file.getPublicURIString());
rawGroups.keySet().forEach(gid -> provideGroup(gid, rawGroups));
}
public Group provideGroup(String gid, Map<String, Map<String, Object>> rawGroups) {
private Group provideGroup(String gid, Map<String, Map<String, Object>> rawGroups) {
Group result = byName(gid);
if (result == null) {
result = new Group(gid, rawGroups.get(gid), s -> provideGroup(s, rawGroups));
......@@ -65,12 +59,12 @@ public class GroupData implements ObservableList<Group> {
return result;
}
public Group byName(String name) {
Group byName(String name) {
for (Group g: this) if (g.name.equals(name)) return g;
return null;
}
public void save() {
public void save() throws FileSystemException {
if (file == null) {
try {
file = VFS.getManager().resolveFile(Objects.requireNonNull(Utils.fileChooser(Utils.ChooseType.SAVE, null, "Save groups", "groups.yml")).toUri());
......@@ -78,11 +72,7 @@ public class GroupData implements ObservableList<Group> {
return;
}
}
try {
YamlUtil.saveYaml(groups.stream().collect(Collectors.toMap(g->g.name, Group::save)), file.getContent());
} catch (FileSystemException e) {
new Alert(Alert.AlertType.ERROR, "Could not save group data: " + e.getMessage()).showAndWait();
}
YamlUtil.saveYaml(groups.stream().collect(Collectors.toMap(g->g.name, Group::save)), file.getContent());
}
// delegated methods
......
......@@ -9,7 +9,6 @@ import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.scene.control.Alert;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.VFS;
......@@ -20,34 +19,28 @@ import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class PlayerData implements ObservableList<Player> {
public FileObject file;
public final ObservableList<Player> players;
private final ObservableList<Player> players;
public PlayerData() {
players = FXCollections.observableArrayList();
}
public PlayerData(FileObject file, GroupData groupData) throws LoadException {
public PlayerData(FileObject file, GroupData groupData) throws FileSystemException, LoadException {
this.file = file;
Map<String, Map<String, Object>> rawPlayers;
try {
rawPlayers = YamlUtil.loadYaml(file.getContent());
} catch (FileSystemException e) {
throw new LoadException("Could not load players from " + file.getPublicURIString());
}
Map<String, Map<String, Object>> rawPlayers = YamlUtil.loadYaml(file.getContent());
if (rawPlayers == null) throw new LoadException("Could not load players from " + file.getPublicURIString());
players = FXCollections.observableArrayList(rawPlayers.entrySet().stream().map(e->new Player(PlayerProfile.query(e.getKey())[0], e.getValue(), groupData)).collect(Collectors.toList()));
}
public Player byProfile(PlayerProfile profile) {
for (Player p: this) if (p.identity.equals(profile)) return p;
return null;
List<Map<String, Object>> data = new ArrayList<>();
PlayerProfile[] profiles = PlayerProfile.of(rawPlayers.entrySet().stream().peek(e -> data.add(e.getValue())).map(e -> PlayerProfile.parseUUID(e.getKey())).toArray(UUID[]::new));
players = FXCollections.observableArrayList(IntStream.range(0, profiles.length).mapToObj(i->new Player(profiles[i], data.get(i), groupData)).toArray(Player[]::new));
}
public void save() {
public void save() throws FileSystemException {
if (file == null) {
try {
file = VFS.getManager().resolveFile(Objects.requireNonNull(Utils.fileChooser(Utils.ChooseType.SAVE, null, "Save players", "players.yml")).toUri());
......@@ -55,11 +48,7 @@ public class PlayerData implements ObservableList<Player> {
return;
}
}
try {
YamlUtil.saveYaml(players.stream().collect(Collectors.toMap(p->p.identity.uuid.toString(), Player::save)), file.getContent());
} catch (FileSystemException e) {
new Alert(Alert.AlertType.ERROR, "Could not save player data: " + e.getMessage()).showAndWait();
}
YamlUtil.saveYaml(players.stream().collect(Collectors.toMap(p->p.identity.uuid.toString(), Player::save)), file.getContent());
}
public void addListener(ListChangeListener<? super Player> listener) {
......
......@@ -2,6 +2,7 @@ package com.unitedworldminers.permio.editor.data;
import com.unitedworldminers.permio.editor.Main;
import com.unitedworldminers.permio.editor.util.Utils;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.image.Image;
......@@ -30,14 +31,14 @@ public class PlayerProfile {
private static final Pattern pattern1 = Pattern.compile("(\\w{32}).*(?<=name\":\")(\\w*)");
private static final Pattern pattern2 = Pattern.compile("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})");
private static final String replace2 = "$1-$2-$3-$4-$5";
public static final Map<String, PlayerProfile> cache = new HashMap<>();
public static final PlayerProfile NULL = new PlayerProfile();
private static final Map<String, PlayerProfile> cache = new HashMap<>();
private static final PlayerProfile NULL = new PlayerProfile();
@NotNull public final UUID uuid;
@NotNull public final StringProperty name;
public final Image image;
@Nullable
private static UUID uuidFromString(String s) {
static UUID parseUUID(String s) {
try {
return UUID.fromString(pattern2.matcher(s).replaceFirst(replace2));
} catch (IllegalArgumentException e) {
......@@ -48,7 +49,7 @@ public class PlayerProfile {
public static PlayerProfile[] query(String... any) {
UUID[] uuids = new UUID[any.length];
for (int i = 0; i < any.length; i++) {
UUID uuid = uuidFromString(any[i]);
UUID uuid = parseUUID(any[i]);
if (uuid != null) {
uuids[i] = uuid;
any[i] = null;
......@@ -74,7 +75,7 @@ public class PlayerProfile {
new Thread(()->{
String name = getName(uuid);
if (name != null) {
this.name.set(name);
Platform.runLater(() -> this.name.set(name));
cache.put(name.toLowerCase(), this);
}
}).start();
......@@ -94,7 +95,7 @@ public class PlayerProfile {
return Objects.equals(name, o.name) && Objects.equals(uuid, o.uuid);
}
public static PlayerProfile[] of(String... names) {
private static PlayerProfile[] of(String... names) {
if (Main.DEBUG) {
return Utils.transform(names, n-> n == null ? null : cache.getOrDefault(n.toLowerCase(), new PlayerProfile(UUID.randomUUID(), n)), PlayerProfile[]::new);
}
......@@ -120,7 +121,7 @@ public class PlayerProfile {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
response = Stream.of(reader.lines().collect(Collectors.joining()).replace("\n", "").replace(" ", "").replace("\t", "").split("},\\{")).map(s -> {
Matcher m = pattern1.matcher(s);
return m.find() ? new PlayerProfile(uuidFromString(m.group(1)), m.group(2)) : null;
return m.find() ? new PlayerProfile(parseUUID(m.group(1)), m.group(2)) : null;
}).filter(Objects::nonNull).collect(Collectors.toMap(p -> p.name.get().toLowerCase(), Function.identity()));
}
......@@ -149,7 +150,7 @@ public class PlayerProfile {
return name.get() + " (" + uuid.toString() + ')';
}
public static PlayerProfile[] of(UUID... uuids) {
static PlayerProfile[] of(UUID... uuids) {
PlayerProfile[] result = new PlayerProfile[uuids.length];
for (int i = 0; i < uuids.length; i++) {
UUID uuid = uuids[i];
......
......@@ -2,7 +2,6 @@ package com.unitedworldminers.permio.editor.screen;
import com.unitedworldminers.permio.editor.component.GroupsList;
import com.unitedworldminers.permio.editor.component.PermissionList;
import com.unitedworldminers.permio.editor.component.PlayerList;
import com.unitedworldminers.permio.editor.component.PlayerListForGroup;
import com.unitedworldminers.permio.editor.data.Group;
import javafx.beans.property.ObjectProperty;
......
......@@ -9,15 +9,15 @@ import com.unitedworldminers.permio.editor.util.Utils;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TabPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.util.Pair;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.VFS;
import org.jetbrains.annotations.Nullable;
import org.apache.commons.vfs2.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
......@@ -42,9 +42,19 @@ public class MainScreen {
menuBar.getMenus().add(new InstantMenu("Reload", this::menuReload));
// load if in fitting dir
boolean loaded = load(Paths.get("groups.yml"), Paths.get("players.yml")) == null || load(Paths.get("../groups.yml"), Paths.get("../players.yml")) == null;
if (!loaded) load();
System.out.println(loaded ? "loaded" : "empty");
try {
load(Paths.get("groups.yml"), Paths.get("players.yml"));
} catch (FileNotFoundException e) {
try {
load(Paths.get("../groups.yml"), Paths.get("../players.yml"));
} catch (FileNotFoundException e1) {
System.out.println("empty");
} catch (Exception e1) {
Utils.showExceptionAlert("Could not load data from parent directory", e);
}
} catch (Exception e) {
Utils.showExceptionAlert("Could not load data from current directory", e);
}
}
@FXML
......@@ -56,65 +66,15 @@ public class MainScreen {
Path players = Utils.fileChooser(Utils.ChooseType.OPEN, window, "Select players file", "players.yml");
if (players == null) return;
Exception err = load(groups, players);
if (err != null) {
Alert dialog = new Alert(Alert.AlertType.ERROR);
dialog.setContentText("Error loading data: " + err);
dialog.showAndWait();
}
}
@FXML
private void menuSave() {
save();
}
@FXML
private void menuReload() {
load(groups.file, players.file);
}
@Nullable
private Exception load(Path groupsFile, Path playersFile) {
try {
FileSystemManager fs = VFS.getManager();
return load(fs.resolveFile(groupsFile.toUri()), fs.resolveFile(playersFile.toUri()));
} catch (IOException e) {
return e;
}
}
@Nullable
private Exception load(FileObject groups, FileObject players) {
try {
MainScreen.groups = new GroupData(groups);
MainScreen.players = new PlayerData(players, MainScreen.groups);
} catch (LoadException e) {
return e;
}
return load();
}
private Exception load() {
groupsScreenController.load();
playersScreenController.load();
return null;
}
@Nullable
private String save() {
try {
groups.save();
players.save();
load(groups, players);
} catch (Exception e) {
return e.getMessage();
Utils.showExceptionAlert("Could not load data", e);
}
return null;
}
public void menuOpenSFTP() {
@FXML
private void menuOpenSFTP() {
Stage window = new Stage();
window.initOwner(menuBar.getScene().getWindow());
window.initModality(Modality.WINDOW_MODAL);
......@@ -129,15 +89,58 @@ public class MainScreen {
@SuppressWarnings("unchecked")
Pair<FileObject, FileObject> files = (Pair<FileObject, FileObject>) window.getUserData();
if (files != null) {
Exception ex = load(files.getKey(), files.getValue());
if (ex != null) Utils.showExceptionAlert("Could not load data", ex);
try {
load(files.getKey(), files.getValue());
} catch (Exception e) {
Utils.showExceptionAlert("Could not load SFTP data", e);
}
}
}
@FXML
private void menuSave() {
try {
save();
} catch (Exception e) {
Utils.showExceptionAlert("Could not save data", e);
}
}
@FXML
private void menuReload() {
try {
load(groups.file, players.file);
} catch (Exception e) {
Utils.showExceptionAlert("Could not reload data", e);
}
}
private void load(Path groupsFile, Path playersFile) throws FileSystemException, LoadException {
FileSystemManager fs = VFS.getManager();
load(fs.resolveFile(groupsFile.toUri()), fs.resolveFile(playersFile.toUri()));
}
private void load(FileObject groups, FileObject players) throws LoadException, FileSystemException {
MainScreen.groups = new GroupData(groups);
MainScreen.players = new PlayerData(players, MainScreen.groups);
load();
}
private void load() {
groupsScreenController.load();
playersScreenController.load();
}
private void save() throws FileSystemException {
groups.save();
players.save();
}
class InstantMenu extends Menu {
private final Runnable action;
public InstantMenu(String text, Runnable action) {
InstantMenu(String text, Runnable action) {
super(text);
this.action = action;
getItems().add(new MenuItem());
......
......@@ -21,7 +21,7 @@ public class PlayersScreen {
@FXML private TextField suffix;
@FXML private ComboBox<Group> group;
@FXML private PlayerProfileScreen playerProfileController;
public static final ObjectProperty<Player> activePlayer = new SimpleObjectProperty<>();
private static final ObjectProperty<Player> activePlayer = new SimpleObjectProperty<>();
@FXML
private void initialize() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment