Skip to content

Instantly share code, notes, and snippets.

@Rayzeq
Last active July 5, 2022 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Rayzeq/6646828036025680b51cecc5d6c99c96 to your computer and use it in GitHub Desktop.
Save Rayzeq/6646828036025680b51cecc5d6c99c96 to your computer and use it in GitHub Desktop.
This diff is based on 3.0-1cda1c9
Note: if there are strange things (most notably casts to Object), it is due to a decompiler error and can be ignored.
diff --git a/net/minecraft/assets/lang/sklmessages_en_US.properties b/net/minecraft/assets/lang/sklmessages_en_US.properties
index 544d096..344e9e5 100644
--- a/net/minecraft/assets/lang/sklmessages_en_US.properties
+++ b/net/minecraft/assets/lang/sklmessages_en_US.properties
@@ -123,6 +123,7 @@ settings.box.light=Light Theme
settings.box.dark=Dark Theme
settings.sort.bylastplayed=Sort profiles by last played
settings.sort.byname=Sort profiles by name
+settings.sort.byuser=Sort profiles manually
settings.label.soon=More soon...
settings.label.color=Accent color
settings.picker.color=Choose color...
diff --git a/net/minecraft/launcher/profile/Profile.java b/net/minecraft/launcher/profile/Profile.java
index 136d94f..a7419e7 100644
--- a/net/minecraft/launcher/profile/Profile.java
+++ b/net/minecraft/launcher/profile/Profile.java
@@ -57,6 +57,8 @@ implements Comparable<Profile> {
private Date created;
@Expose
private Date lastUsed;
+ @Expose
+ private Integer orderingPos;
public Profile() {
this.lastUsed = this.created = new Date();
@@ -76,6 +78,7 @@ implements Comparable<Profile> {
this.overridePriority = copy.overridePriority;
this.type = copy.type == null ? ProfileType.CUSTOM : copy.type;
this.lastUsed = this.created = new Date();
+ this.orderingPos = copy.orderingPos;
}
public Profile(String name) {
@@ -240,6 +243,14 @@ implements Comparable<Profile> {
this.lastUsed = lastUsed;
}
+ public Integer getOrderingPos() {
+ return this.orderingPos;
+ }
+
+ public void setOrderingPos(Integer pos) {
+ this.orderingPos = pos;
+ }
+
@Override
public int compareTo(Profile o) {
return this.getName().compareTo(o.getName());
diff --git a/net/minecraft/launcher/profile/ProfileManager.java b/net/minecraft/launcher/profile/ProfileManager.java
index 3c9f696..c5429cd 100644
--- a/net/minecraft/launcher/profile/ProfileManager.java
+++ b/net/minecraft/launcher/profile/ProfileManager.java
@@ -35,6 +35,7 @@ import java.util.Objects;
import java.util.UUID;
import net.minecraft.launcher.Launcher;
import net.minecraft.launcher.profile.Profile;
+import net.minecraft.launcher.profile.SortMethod;
import net.minecraft.launcher.profile.ProfileType;
import net.minecraft.launcher.profile.RefreshedProfilesListener;
import org.apache.commons.io.FileUtils;
@@ -52,7 +53,7 @@ public class ProfileManager {
private final File profileFileBak;
private final List<RefreshedProfilesListener> refreshedProfilesListeners = Collections.synchronizedList(new ArrayList());
private String selectedProfile;
- private boolean sortByLastPlayed;
+ private SortMethod sortMethod;
public ProfileManager(Launcher launcher) {
this.launcher = launcher;
@@ -71,7 +72,7 @@ public class ProfileManager {
}
public void saveProfiles() throws IOException {
- RawProfileList rawProfileList = new RawProfileList(this.profiles, this.selectedProfile, this.sortByLastPlayed);
+ RawProfileList rawProfileList = new RawProfileList(this.profiles, this.selectedProfile, this.sortMethod);
String data = this.gson.toJson(rawProfileList);
FileUtils.writeStringToFile(this.profileFile, data, StandardCharsets.UTF_8);
FileUtils.writeStringToFile(this.profileFileBak, data, StandardCharsets.UTF_8);
@@ -81,7 +82,7 @@ public class ProfileManager {
this.launcher.getAccountsManager().saveAccounts();
this.profiles.clear();
this.selectedProfile = null;
- this.sortByLastPlayed = false;
+ this.sortMethod = SortMethod.NAME;
if (this.profileFile.isFile()) {
JsonObject object = JsonParser.parseString(FileUtils.readFileToString(this.profileFile, StandardCharsets.UTF_8)).getAsJsonObject();
Integer version = this.getProfileFormat(object);
@@ -102,7 +103,7 @@ public class ProfileManager {
RawProfileList rawProfileList = this.gson.fromJson((JsonElement)object, RawProfileList.class);
this.profiles.putAll(rawProfileList.profiles);
this.selectedProfile = rawProfileList.selectedProfile;
- this.sortByLastPlayed = rawProfileList.sortByLastPlayed;
+ this.sortMethod = rawProfileList.sortMethod;
this.fireRefreshEvent();
return true;
}
@@ -142,12 +143,7 @@ public class ProfileManager {
this.setSelectedById(DEFAULT_PROFILE_ID);
} else if (this.profiles.size() > 0) {
LOGGER.info("Selected profile not found, using first profile");
- ArrayList<Profile> profiles = new ArrayList<Profile>(this.profiles.values());
- if (this.isSortByLastPlayed()) {
- profiles.sort((o1, o2) -> o2.getLastUsed().compareTo(o1.getLastUsed()));
- } else {
- profiles.sort(Comparator.comparing(Profile::getName));
- }
+ ArrayList<Profile> profiles = this.getSortedProfileList();
this.setSelected((Profile)profiles.get(0));
} else {
LOGGER.info("No profiles found, creating default profile");
@@ -163,6 +159,23 @@ public class ProfileManager {
return this.profiles;
}
+ public ArrayList<Profile> getSortedProfileList() {
+ ArrayList<Profile> profiles = Lists.newArrayList(this.profiles.values());
+ switch(this.sortMethod) {
+ case NAME:
+ profiles.sort(Comparator.comparing(Profile::getName));
+ break;
+ case LAST_PLAYED:
+ profiles.sort((o1, o2) -> o2.getLastUsed().compareTo(o1.getLastUsed()));
+ break;
+ case USER:
+ profiles.sort(Comparator.comparing(Profile::getOrderingPos));
+ break;
+ }
+
+ return profiles;
+ }
+
public void putProfile(Profile profile) {
if (profile.getId() == null) {
profile.setId(UUIDTypeAdapter.fromUUID(UUID.randomUUID()));
@@ -181,6 +194,12 @@ public class ProfileManager {
public void removeProfile(Profile profile) {
LOGGER.info("Removing profile {}", (Object)profile.getDisplayName());
this.profiles.remove(profile.getId());
+ if (this.sortMethod == SortMethod.USER) {
+ ArrayList<Profile> profiles = this.getSortedProfileList();
+ for (int i = profile.getOrderingPos(); i < profiles.size(); i++) {
+ profiles.get(i).setOrderingPos(i);
+ }
+ }
}
public void setSelectedById(String selectedProfile) {
@@ -207,23 +226,29 @@ public class ProfileManager {
return this.profiles.get(id);
}
- public boolean isSortByLastPlayed() {
- return this.sortByLastPlayed;
+ public SortMethod getSortMethod() {
+ return this.sortMethod;
}
- public void setSortByLastPlayed(boolean sortByLastPlayed) {
- this.sortByLastPlayed = sortByLastPlayed;
+ public void setSortMethod(SortMethod sortMethod) {
+ if (this.sortMethod != SortMethod.USER && sortMethod == SortMethod.USER) {
+ ArrayList<Profile> profiles = this.getSortedProfileList();
+ for (int i = 0; i < profiles.size(); i++) {
+ profiles.get(i).setOrderingPos(i);
+ }
+ }
+ this.sortMethod = sortMethod;
}
private static class RawProfileList {
public Map<String, Profile> profiles;
public String selectedProfile;
- public boolean sortByLastPlayed;
+ public SortMethod sortMethod;
- private RawProfileList(Map<String, Profile> profiles, String selectedProfile, boolean sortByLastPlayed) {
+ private RawProfileList(Map<String, Profile> profiles, String selectedProfile, SortMethod sortMethod) {
this.profiles = profiles;
this.selectedProfile = selectedProfile;
- this.sortByLastPlayed = sortByLastPlayed;
+ this.sortMethod = sortMethod;
}
public static class Serializer
@@ -259,18 +284,28 @@ public class ProfileManager {
if (object.has("selectedProfile")) {
selectedProfile = object.getAsJsonPrimitive("selectedProfile").getAsString();
}
- boolean sortByLastPlayed = false;
+ SortMethod sortMethod = SortMethod.NAME;
if (object.has("settings") && (settingsObject = object.get("settings").getAsJsonObject()).has("profileSorting")) {
- sortByLastPlayed = settingsObject.getAsJsonPrimitive("profileSorting").getAsString().equals("byLastPlayed");
+ switch (settingsObject.getAsJsonPrimitive("profileSorting").getAsString()) {
+ case "byName":
+ sortMethod = SortMethod.NAME;
+ break;
+ case "byLastPlayed":
+ sortMethod = SortMethod.LAST_PLAYED;
+ break;
+ case "byUser":
+ sortMethod = SortMethod.USER;
+ break;
+ }
}
- return new RawProfileList(profiles, selectedProfile, sortByLastPlayed);
+ return new RawProfileList(profiles, selectedProfile, sortMethod);
}
@Override
public JsonElement serialize(RawProfileList src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject settings = new JsonObject();
settings.addProperty("enableAdvanced", false);
- settings.addProperty("profileSorting", src.sortByLastPlayed ? "byLastPlayed" : "byName");
+ settings.addProperty("profileSorting", src.sortMethod.getOptname());
JsonObject object = new JsonObject();
HashMap<String, Profile> profiles = new HashMap<String, Profile>();
for (Map.Entry<String, Profile> entry : src.profiles.entrySet()) {
diff --git a/net/minecraft/launcher/profile/SortMethod.java b/net/minecraft/launcher/profile/SortMethod.java
new file mode 100644
index 0000000..27d31a9
--- /dev/null
+++ b/net/minecraft/launcher/profile/SortMethod.java
@@ -0,0 +1,29 @@
+package net.minecraft.launcher.profile;
+
+import net.minecraft.launcher.LauncherLocale;
+
+public enum SortMethod {
+ NAME("byName", LauncherLocale.getMessage("settings.sort.byname")),
+ LAST_PLAYED("byLastPlayed", LauncherLocale.getMessage("settings.sort.bylastplayed")),
+ USER("byUser", LauncherLocale.getMessage("settings.sort.byuser"));
+
+ private final String text;
+ private final String optname;
+
+ private SortMethod(String optname, String text) {
+ this.text = text;
+ this.optname = optname;
+ }
+
+ public String getText() {
+ return this.text;
+ }
+
+ public String toString() {
+ return this.text;
+ }
+
+ public String getOptname() {
+ return this.optname;
+ }
+}
diff --git a/net/minecraft/launcher/ui/javafx/popups/profile/create/CreatePopup.java b/net/minecraft/launcher/ui/javafx/popups/profile/create/CreatePopup.java
index d75650f..02ca7b2 100644
--- a/net/minecraft/launcher/ui/javafx/popups/profile/create/CreatePopup.java
+++ b/net/minecraft/launcher/ui/javafx/popups/profile/create/CreatePopup.java
@@ -177,6 +177,7 @@ implements Initializable {
try {
ProfileManager manager = this.minecraftLauncher.getProfileManager();
this.profile.setGameDir(this.workDirFile != null ? this.workDirFile : this.minecraftLauncher.getWorkingDirectory());
+ this.profile.setOrderingPos(manager.getProfiles().size());
manager.putProfile(this.profile);
manager.setSelected(this.profile);
manager.saveProfiles();
diff --git a/net/minecraft/launcher/ui/javafx/popups/settings/SettingsPopup.java b/net/minecraft/launcher/ui/javafx/popups/settings/SettingsPopup.java
index 807ec70..2a66262 100644
--- a/net/minecraft/launcher/ui/javafx/popups/settings/SettingsPopup.java
+++ b/net/minecraft/launcher/ui/javafx/popups/settings/SettingsPopup.java
@@ -46,6 +46,7 @@ import net.minecraft.launcher.LauncherTheme;
import net.minecraft.launcher.ui.javafx.layout.main.LauncherPanel;
import net.minecraft.launcher.ui.javafx.utils.FXUtils;
import net.minecraft.launcher.util.LocaleComparator;
+import net.minecraft.launcher.profile.SortMethod;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -70,7 +71,7 @@ extends VBox {
private Locale oldLang;
private Color oldColor;
private boolean oldTheme;
- private JFXComboBox<Boolean> sortCombobox;
+ private JFXComboBox<Integer> sortCombobox;
private Label otherLabel;
public SettingsPopup(Launcher minecraftLauncher) {
@@ -127,7 +128,7 @@ extends VBox {
this.otherLabel.setStyle("-fx-font-size: 16px;");
HBox otherBox = new HBox();
otherBox.setSpacing(32.0);
- this.sortCombobox = new JFXComboBox();
+ this.sortCombobox = new JFXComboBox<Integer>();
otherBox.getChildren().addAll(new Node[]{this.sortCombobox});
this.getChildren().addAll(new Node[]{this.otherLabel, otherBox});
HBox footerBox = new HBox();
@@ -213,11 +214,11 @@ extends VBox {
LauncherTheme.setDark(this.darkBox.isSelected());
LauncherTheme.refreshTheme();
});
- this.sortCombobox.getItems().addAll((Object[])new Boolean[]{Boolean.TRUE, Boolean.FALSE});
- this.sortCombobox.getSelectionModel().select((Object)this.minecraftLauncher.getProfileManager().isSortByLastPlayed());
+ this.sortCombobox.getItems().addAll(new Integer[]{0, 1, 2});
+ this.sortCombobox.getSelectionModel().select(this.minecraftLauncher.getProfileManager().getSortMethod().ordinal());
this.sortCombobox.setButtonCell(new SortListCell());
this.sortCombobox.setCellFactory(param -> new SortListCell());
- this.sortCombobox.getSelectionModel().selectedItemProperty().addListener((options, oldValue, newValue) -> this.minecraftLauncher.getProfileManager().setSortByLastPlayed((boolean)newValue));
+ this.sortCombobox.getSelectionModel().selectedItemProperty().addListener((options, oldValue, newValue) -> this.minecraftLauncher.getProfileManager().setSortMethod(SortMethod.values()[(int)newValue]));
}
private void acceptChanges(JFXAlert<?> alert) {
@@ -256,19 +257,19 @@ extends VBox {
}
private static class SortListCell
- extends JFXListCell<Boolean> {
+ extends JFXListCell<Integer> {
private SortListCell() {
}
@Override
- protected void updateItem(Boolean item, boolean empty) {
+ protected void updateItem(Integer item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
this.setGraphic(null);
this.setText(null);
} else {
this.setGraphic(null);
- this.setText(item != false ? LauncherLocale.getMessage("settings.sort.bylastplayed") : LauncherLocale.getMessage("settings.sort.byname"));
+ this.setText(SortMethod.values()[item].getText());
}
}
}
diff --git a/net/minecraft/launcher/ui/javafx/sidebar/ProfileSelectionPanel.java b/net/minecraft/launcher/ui/javafx/sidebar/ProfileSelectionPanel.java
index 0e4dd68..9ed949b 100644
--- a/net/minecraft/launcher/ui/javafx/sidebar/ProfileSelectionPanel.java
+++ b/net/minecraft/launcher/ui/javafx/sidebar/ProfileSelectionPanel.java
@@ -64,6 +64,7 @@ import net.minecraft.launcher.Launcher;
import net.minecraft.launcher.LauncherLocale;
import net.minecraft.launcher.LauncherTheme;
import net.minecraft.launcher.profile.Profile;
+import net.minecraft.launcher.profile.SortMethod;
import net.minecraft.launcher.profile.ProfileManager;
import net.minecraft.launcher.profile.ProfileType;
import net.minecraft.launcher.profile.RefreshedProfilesListener;
@@ -162,13 +163,8 @@ implements RefreshedProfilesListener {
private void populateProfilesListView() {
String previous = this.minecraftLauncher.getProfileManager().getSelectedProfile().getId();
Profile selected = null;
- ArrayList<Profile> profiles = Lists.newArrayList(this.minecraftLauncher.getProfileManager().getProfiles().values());
+ ArrayList<Profile> profiles = this.minecraftLauncher.getProfileManager().getSortedProfileList();
this.profileListView.getItems().clear();
- if (this.minecraftLauncher.getProfileManager().isSortByLastPlayed()) {
- profiles.sort((o1, o2) -> o2.getLastUsed().compareTo(o1.getLastUsed()));
- } else {
- profiles.sort(Comparator.comparing(Profile::getName));
- }
this.skipSelectionUpdate = true;
if (profiles.size() > 0) {
for (Profile profile : profiles) {
@@ -206,22 +202,58 @@ implements RefreshedProfilesListener {
private final HBox hBox = new HBox();
private final Label label = new Label();
private final Pane pane = new Pane();
- private final JFXButton button = new JFXButton("");
+ private final JFXButton buttonUp = new JFXButton("");
+ private final JFXButton buttonDown = new JFXButton("");
+ private final JFXButton buttonMore = new JFXButton("");
private Profile lastItem;
ProfileListCell() {
this.label.setTextOverrun(OverrunStyle.CLIP);
this.label.setMaxWidth(175.0);
this.hBox.setAlignment(Pos.CENTER_LEFT);
- this.hBox.getChildren().addAll((Object[])new Node[]{this.label, this.pane, this.button});
+ this.hBox.getChildren().addAll(new Node[]{this.label, this.pane, this.buttonUp, this.buttonDown, this.buttonMore});
HBox.setHgrow((Node)this.pane, (Priority)Priority.ALWAYS);
- FontIcon icon = new FontIcon(FontAwesomeSolid.ELLIPSIS_V);
- this.button.setGraphic((Node)icon);
- this.button.setOnAction(event -> {
- Bounds pos = this.button.localToScreen(this.button.getBoundsInLocal());
- this.getContextMenu().show((Node)this.button, pos.getMinX(), pos.getMinY() + this.button.getHeight());
+
+ FontIcon iconUp = new FontIcon(FontAwesomeSolid.ANGLE_UP);
+ this.buttonUp.setGraphic((Node)iconUp);
+ this.buttonUp.setOnAction(event -> {
+ Integer itemPos = this.lastItem.getOrderingPos();
+ Profile previousItem = ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().getSortedProfileList().get(itemPos - 1);
+ this.lastItem.setOrderingPos(itemPos - 1);
+ previousItem.setOrderingPos(itemPos);
+ try {
+ ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().saveProfiles();
+ ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().fireRefreshEvent();
+ } catch (IOException ex) {
+ LOGGER.error("Couldn't save profiles whilst changing position of '" + this.lastItem.getDisplayName() + "'", (Throwable)ex);
+ }
});
- this.button.setVisible(false);
+ this.buttonUp.setVisible(false);
+
+ FontIcon iconDown = new FontIcon(FontAwesomeSolid.ANGLE_DOWN);
+ this.buttonDown.setGraphic((Node)iconDown);
+ this.buttonDown.setOnAction(event -> {
+ Integer itemPos = this.lastItem.getOrderingPos();
+ Profile nextItem = ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().getSortedProfileList().get(itemPos + 1);
+ this.lastItem.setOrderingPos(itemPos + 1);
+ nextItem.setOrderingPos(itemPos);
+ try {
+ ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().saveProfiles();
+ ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().fireRefreshEvent();
+ } catch (IOException ex) {
+ LOGGER.error("Couldn't save profiles whilst changing position of '" + this.lastItem.getDisplayName() + "'", (Throwable)ex);
+ }
+ });
+ this.buttonDown.setVisible(false);
+
+ FontIcon iconMore = new FontIcon(FontAwesomeSolid.ELLIPSIS_V);
+ this.buttonMore.setGraphic((Node)iconMore);
+ this.buttonMore.setOnAction(event -> {
+ Bounds pos = this.buttonMore.localToScreen(this.buttonMore.getBoundsInLocal());
+ this.getContextMenu().show((Node)this.buttonMore, pos.getMinX(), pos.getMinY() + this.buttonMore.getHeight());
+ });
+ this.buttonMore.setVisible(false);
+
this.selectedProperty().addListener((observable, oldValue, newValue) -> {
Profile item = (Profile)this.getItem();
if (!this.isEmpty() && item != null) {
@@ -247,6 +279,9 @@ implements RefreshedProfilesListener {
duplicateProfile.setOnAction(event -> {
Profile duplicatedProfile = new Profile(ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().getSelectedProfile());
duplicatedProfile.setName("Copy of " + duplicatedProfile.getName());
+ // Note: it would be nice to insert it just after the current profile,
+ // but that would require us to do work on form submit in that special case
+ duplicatedProfile.setOrderingPos(ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().getProfiles().size());
ProfileSelectionPanel.this.showEditProfileDialog(ProfileSelectionPanel.this.minecraftLauncher, duplicatedProfile);
});
MenuItem browseProfile = new MenuItem(LauncherLocale.getMessage("sidebar.menu.item.browse"));
@@ -307,7 +342,9 @@ implements RefreshedProfilesListener {
}
private void updateItemSelection(Profile item, boolean selected) {
- this.button.setVisible(selected && item.getType() == ProfileType.CUSTOM);
+ this.buttonUp.setVisible(selected && ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().getSortMethod() == SortMethod.USER && this.lastItem.getOrderingPos() != 0);
+ this.buttonDown.setVisible(selected && ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().getSortMethod() == SortMethod.USER && this.lastItem.getOrderingPos() != (ProfileSelectionPanel.this.minecraftLauncher.getProfileManager().getProfiles().size() - 1));
+ this.buttonMore.setVisible(selected && item.getType() == ProfileType.CUSTOM);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment