Compare commits
No commits in common. "master" and "0.2" have entirely different histories.
6 changed files with 51 additions and 209 deletions
13
README.md
13
README.md
|
@ -2,11 +2,8 @@
|
|||
This plugin helps with the conversion of data from VehiclesPlus v2 to v3.
|
||||
|
||||
## Usage
|
||||
0. Make sure VehiclesPlus v2 is still installed. Otherwise install it again, you can find the .jar in the version history.
|
||||
1. **Back up your v2 VehiclesPlusPro plugin data folder!**
|
||||
1. Download VehiclesPlus v3 and the [latest release](https://git.sbdevelopment.tech/SBDevelopment/VehiclesPlusConverter/releases) of the converter and install it into your `plugins` folder.
|
||||
1. (Re)start your server and check your console to make sure both v2 and v3 load correctly.
|
||||
1. Execute `/vpconvert` and read the instructions.
|
||||
1. The plugin will convert all the data to the v3 data folder and stop the server.
|
||||
1. Make sure to remove the .jar files of both VehiclesPlus v2 and VehiclesPlusConverter!
|
||||
1. Start your server again and enjoy v3! 😉
|
||||
1. Make sure you installed both VehiclesPlus v2 and VehiclesPlus v3.
|
||||
2. Download the [latest release](https://github.com/SBDPlugins/VehiclesPlusConverter/releases) of the converter and install it into your `plugins` folder.
|
||||
3. Restart your server.
|
||||
4. Use the `/vpconvert` command and follow the instructions.
|
||||
5. The server will restart. After the restart, the new vehicles will be loaded.
|
6
pom.xml
6
pom.xml
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>tech.sbdevelopment</groupId>
|
||||
<artifactId>VehiclesPlusConverter</artifactId>
|
||||
<version>0.2.4</version>
|
||||
<version>0.2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>VehiclesPlusConverter</name>
|
||||
|
@ -80,9 +80,9 @@
|
|||
<dependency>
|
||||
<groupId>nl.sbdeveloper</groupId>
|
||||
<artifactId>VehiclesPlus-v3</artifactId>
|
||||
<version>3.0.3</version>
|
||||
<version>3.0.1</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/libs/VehiclesPlus-3.0.3.jar</systemPath>
|
||||
<systemPath>${project.basedir}/src/libs/VehiclesPlus-3.0.1.jar</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -30,8 +30,8 @@ public final class VehiclesPlusConverter extends JavaPlugin {
|
|||
}
|
||||
|
||||
Version versionNew = Version.of(Bukkit.getPluginManager().getPlugin("VehiclesPlus").getDescription().getVersion());
|
||||
if (versionNew.isOlderThan(Version.of("3.0.3"))) {
|
||||
Bukkit.getLogger().severe("Your VehiclesPlus v3 plugin is too old! Please update to at least v3.0.3!");
|
||||
if (versionNew.isOlderThan(Version.of("3.0.1"))) {
|
||||
Bukkit.getLogger().severe("Your VehiclesPlus v3 plugin is too old! Please update to at least v3.0.1!");
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
package tech.sbdevelopment.vehiclesplusconverter.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
public class ConversionException extends IOException {
|
||||
public ConversionException(String explanation, String filename) {
|
||||
super(explanation + " " + filename + ".yml!");
|
||||
}
|
||||
|
||||
public ConversionException(String explanation, String filename, String expected, Set<String> available) {
|
||||
super(explanation + " " + filename + ".yml! Expected " + expected + ", available: " + String.join(", ", available));
|
||||
public ConversionException(String before, String filename) {
|
||||
super(before + " " + filename + ".yml");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,19 +23,14 @@ import nl.sbdeveloper.vehiclesplus.api.vehicles.settings.impl.*;
|
|||
import nl.sbdeveloper.vehiclesplus.storage.db.exceptions.DataStorageException;
|
||||
import nl.sbdeveloper.vehiclesplus.utils.jackson.ColorList;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import tech.sbdevelopment.vehiclesplusconverter.VehiclesPlusConverter;
|
||||
import tech.sbdevelopment.vehiclesplusconverter.api.ConversionException;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static tech.sbdevelopment.vehiclesplusconverter.utils.MainUtil.*;
|
||||
|
||||
|
@ -78,7 +73,8 @@ public class Converter {
|
|||
try {
|
||||
disablePlugin(VehiclesPlus.getInstance());
|
||||
disablePlugin(VehiclesPlusConverter.getInstance());
|
||||
} catch (Exception ignored) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
counter--;
|
||||
|
@ -89,14 +85,13 @@ public class Converter {
|
|||
private static void convertRims() {
|
||||
for (Map.Entry<String, RimDesign> entry : VehiclesPlus.getVehicleManager().getRimDesignHashMap().entrySet()) {
|
||||
nl.sbdeveloper.vehiclesplus.api.vehicles.rims.RimDesign rd = new nl.sbdeveloper.vehiclesplus.api.vehicles.rims.RimDesign(
|
||||
entry.getValue().getName().toLowerCase(),
|
||||
entry.getValue().getName(),
|
||||
entry.getValue().getSkin(),
|
||||
HolderItemPosition.HEAD,
|
||||
entry.getValue().getPrice()
|
||||
);
|
||||
|
||||
nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getRimDesigns().put(entry.getKey(), rd);
|
||||
rd.save();
|
||||
|
||||
VehiclesPlusConverter.getInstance().getLogger().info("Converted rim design: " + rd.getName());
|
||||
}
|
||||
|
@ -111,7 +106,6 @@ public class Converter {
|
|||
);
|
||||
|
||||
nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getFuelTypes().put(entry.getKey(), ft);
|
||||
ft.save();
|
||||
|
||||
VehiclesPlusConverter.getInstance().getLogger().info("Converted fuel type: " + ft.getName());
|
||||
}
|
||||
|
@ -121,11 +115,6 @@ public class Converter {
|
|||
VehiclesPlusConverter.getInstance().getLogger().info("Converting vehicle models: " + VehiclesPlusAPI.getVehicleManager().getBaseVehicleMap().values().stream().map(BaseVehicle::getName).reduce((s1, s2) -> s1 + ", " + s2).orElse(""));
|
||||
|
||||
for (BaseVehicle baseVehicle : VehiclesPlusAPI.getVehicleManager().getBaseVehicleMap().values()) {
|
||||
if (baseVehicle.getName().startsWith("Example")) {
|
||||
VehiclesPlusConverter.getInstance().getLogger().info("Skipping example vehicle model: " + baseVehicle.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
VehicleModel.Builder vehicleModelBuilder = VehicleModel.builder()
|
||||
.id(baseVehicle.getName())
|
||||
|
@ -148,12 +137,7 @@ public class Converter {
|
|||
turretSeat.getXOffset(),
|
||||
turretSeat.getYOffset(),
|
||||
turretSeat.getZOffset(),
|
||||
baseVehicle.getPartList()
|
||||
.stream()
|
||||
.filter(Turret.class::isInstance)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new ConversionException("No Turret found while loading TurretSeat in file", baseVehicle.getName()))
|
||||
.getUID()
|
||||
baseVehicle.getPartList().stream().filter(Turret.class::isInstance).findFirst().orElseThrow(() -> new ConversionException("No Turret found while loading TurretSeat in file", baseVehicle.getName())).getUID()
|
||||
));
|
||||
} else if (part instanceof Seat) {
|
||||
Seat seat = (Seat) part;
|
||||
|
@ -203,52 +187,15 @@ public class Converter {
|
|||
));
|
||||
} else if (part instanceof Wheel) {
|
||||
Wheel wheel = (Wheel) part;
|
||||
ItemStack wheelSkin = wheel.getSkinColored();
|
||||
|
||||
// Try to find an existing rim design with this skin
|
||||
Optional<nl.sbdeveloper.vehiclesplus.api.vehicles.rims.RimDesign> matchingRimDesign = nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getRimDesigns()
|
||||
.values()
|
||||
.stream()
|
||||
.filter(rd -> compareItems(rd.getSkin(), wheelSkin))
|
||||
.findFirst();
|
||||
|
||||
if (matchingRimDesign.isEmpty()) {
|
||||
// Create a new rim design since no matching one exists
|
||||
String newRimDesignName = generateRimName();
|
||||
nl.sbdeveloper.vehiclesplus.api.vehicles.rims.RimDesign newRimDesign = new nl.sbdeveloper.vehiclesplus.api.vehicles.rims.RimDesign(
|
||||
newRimDesignName,
|
||||
wheelSkin,
|
||||
HolderItemPosition.HEAD,
|
||||
1000
|
||||
);
|
||||
|
||||
// Add the new rim design to the rim designs map
|
||||
nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getRimDesigns().put(newRimDesignName, newRimDesign);
|
||||
newRimDesign.save();
|
||||
VehiclesPlusConverter.getInstance().getLogger().info("Created new rim design '" + newRimDesignName + "' for wheel skin!");
|
||||
|
||||
// Create the wheel part with the new rim design
|
||||
vehicleModelBuilder = vehicleModelBuilder.part(new nl.sbdeveloper.vehiclesplus.api.vehicles.parts.impl.Wheel(
|
||||
wheel.getXOffset(),
|
||||
wheel.getYOffset(),
|
||||
wheel.getZOffset(),
|
||||
newRimDesign,
|
||||
nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getRimDesign(VehiclesPlus.getVehicleManager().getRimDesignHashMap().values().stream().findFirst().orElseThrow(() -> new ConversionException("No RimDesign found while loading Wheel in file", baseVehicle.getName())).getName()).orElseThrow(() -> new ConversionException("No matching RimDesign found while loading Wheel in file", baseVehicle.getName())),
|
||||
wheel.getColor(),
|
||||
wheel.getSteering(),
|
||||
wheel.getRotationOffset()
|
||||
));
|
||||
} else {
|
||||
// Use the existing rim design that matches the skin
|
||||
vehicleModelBuilder = vehicleModelBuilder.part(new nl.sbdeveloper.vehiclesplus.api.vehicles.parts.impl.Wheel(
|
||||
wheel.getXOffset(),
|
||||
wheel.getYOffset(),
|
||||
wheel.getZOffset(),
|
||||
matchingRimDesign.get(),
|
||||
wheel.getColor(),
|
||||
wheel.getSteering(),
|
||||
wheel.getRotationOffset()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,7 +227,7 @@ public class Converter {
|
|||
.horn(new Horn(
|
||||
baseVehicle.getHornSettings().getEnabled(),
|
||||
new Sounds.Sound(
|
||||
baseVehicle.getHornSettings().getSound().name(),
|
||||
baseVehicle.getHornSettings().getSound().parseSound().name(),
|
||||
1
|
||||
)
|
||||
))
|
||||
|
@ -328,85 +275,47 @@ public class Converter {
|
|||
VehiclesPlusConverter.getInstance().getLogger().info("Converted vehicle model: " + model.getId());
|
||||
|
||||
saveToVehiclesPlus(model, "vehicles/" + model.getTypeId(), model.getId());
|
||||
nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getVehicleModels().put(model.getId(), model);
|
||||
} catch (Exception e) {
|
||||
VehiclesPlusConverter.getInstance().getLogger().log(java.util.logging.Level.SEVERE, "Could not convert vehicle model: " + baseVehicle.getName(), e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void convertVehicles() {
|
||||
File baseDir = new File("plugins/VehiclesPlusPro/data");
|
||||
if (!baseDir.exists()) {
|
||||
VehiclesPlusConverter.getInstance().getLogger().severe("Could not find the VehiclesPlusPro data folder!");
|
||||
return;
|
||||
}
|
||||
|
||||
for (File playerDir : baseDir.listFiles()) {
|
||||
if (playerDir.isDirectory()) {
|
||||
String ownerUUID = playerDir.getName();
|
||||
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(ownerUUID));
|
||||
if (player.getName() == null) {
|
||||
VehiclesPlusConverter.getInstance().getLogger().severe("Could not find player with UUID: " + ownerUUID + ", skipping...");
|
||||
for (Map.Entry<UUID, List<StorageVehicle>> set : VehiclesPlusAPI.getVehicleManager().getPlayerVehicleHashMap().entrySet()) {
|
||||
UUID ownerUUID = set.getKey();
|
||||
String ownerName = Bukkit.getOfflinePlayer(ownerUUID).getName();
|
||||
if (ownerName == null) {
|
||||
VehiclesPlusConverter.getInstance().getLogger().severe("Could not convert vehicles for player with UUID " + ownerUUID + ", the player name is unknown!");
|
||||
continue;
|
||||
}
|
||||
|
||||
VehiclesPlusConverter.getInstance().getLogger().info("Converting vehicles for player with UUID " + ownerUUID + "...");
|
||||
final Garage garage = nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getPersonalGarage(player);
|
||||
|
||||
int i = 0;
|
||||
for (File vehicleFile : playerDir.listFiles()) {
|
||||
if (vehicleFile.getName().contains(".yml")) {
|
||||
StorageVehicle vehicle;
|
||||
try {
|
||||
vehicle = StorageVehicle.loadFromStorage(vehicleFile.getAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not convert vehicles for player with UUID " + ownerUUID + ", could not load the vehicle!", e);
|
||||
continue;
|
||||
}
|
||||
if (vehicle == null) {
|
||||
Bukkit.getLogger().warning("Failed to load vehicle for player with UUID " + ownerUUID + " from file: " + vehicleFile.getName() + ", skipping...");
|
||||
continue;
|
||||
}
|
||||
final Garage garage = nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getGarage(ownerName).orElseGet(() -> new Garage(ownerName, ownerUUID));
|
||||
VehiclesPlusConverter.getInstance().getLogger().info("Converting vehicles for player with UUID " + ownerUUID + " (" + ownerName + ")...");
|
||||
|
||||
for (StorageVehicle vehicle : set.getValue()) {
|
||||
try {
|
||||
nl.sbdeveloper.vehiclesplus.api.vehicles.impl.StorageVehicle newVehicle = new nl.sbdeveloper.vehiclesplus.api.vehicles.impl.StorageVehicle(
|
||||
UUID.randomUUID(),
|
||||
nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getVehicleModels().values().stream().filter(v -> v.getId().equalsIgnoreCase(vehicle.getBaseVehicle())).findFirst().orElseThrow(() -> new ConversionException("No VehicleModel found for", vehicle.getUuid(), vehicle.getBaseVehicle(), nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getVehicleModels().keySet())),
|
||||
nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getVehicleModels().values().stream().filter(v -> v.getId().equalsIgnoreCase(vehicle.getBaseVehicle())).findFirst().orElseThrow(() -> new ConversionException("No VehicleModel found for", vehicle.getUuid())),
|
||||
false
|
||||
);
|
||||
|
||||
// Set the vehicle's stats
|
||||
newVehicle.getStatics().forceSetMaxSpeed(vehicle.getVehicleStats().getSpeed());
|
||||
newVehicle.getStatics().forceSetTurningRadius(vehicle.getVehicleStats().getSteering());
|
||||
newVehicle.getStatics().forceSetFuelTank(vehicle.getVehicleStats().getFuelTank());
|
||||
newVehicle.getStatics().setCurrentFuel(vehicle.getVehicleStats().getCurrentFuel());
|
||||
newVehicle.getStatics().forceSetAcceleration(vehicle.getVehicleStats().getAcceleration());
|
||||
newVehicle.getStatics().setBroken(vehicle.getVehicleStats().getBroken());
|
||||
newVehicle.getStatics().setCurrentHealth(vehicle.getVehicleStats().getHealth());
|
||||
|
||||
// Set the trunk
|
||||
newVehicle.getTrunkItems().addAll(Arrays.asList(vehicle.getVehicleTrunk().getContents()));
|
||||
|
||||
newVehicle.forceSave();
|
||||
garage.addVehicle(newVehicle.getUuid());
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not convert vehicles for player with UUID " + ownerUUID + ", could not save the vehicle!", e);
|
||||
e.printStackTrace();
|
||||
Bukkit.getLogger().severe("Could not convert vehicles for player with UUID " + ownerUUID + ", could not save the vehicle!");
|
||||
}
|
||||
|
||||
VehiclesPlusConverter.getInstance().getLogger().info("Converted vehicle: " + vehicle.getUuid());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
garage.forceSave();
|
||||
} catch (DataStorageException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not convert vehicles for player with UUID " + ownerUUID + ", could not save the garage!", e);
|
||||
}
|
||||
|
||||
VehiclesPlusConverter.getInstance().getLogger().info("Converted " + i + " vehicles for player with UUID " + ownerUUID);
|
||||
e.printStackTrace();
|
||||
Bukkit.getLogger().severe("Could not convert vehicles for player with UUID " + ownerUUID + ", could not save the garage!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package tech.sbdevelopment.vehiclesplusconverter.utils;
|
|||
import com.google.common.io.Files;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import nl.sbdeveloper.vehiclesplus.storage.file.HJSONFile;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import tech.sbdevelopment.vehiclesplusconverter.VehiclesPlusConverter;
|
||||
import tech.sbdevelopment.vehiclesplusconverter.api.ConversionException;
|
||||
|
@ -87,62 +86,4 @@ public class MainUtil {
|
|||
VehiclesPlusConverter.getInstance().getLogger().log(Level.SEVERE, "Couldn't save to the file " + fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two ItemStacks for equality based on material type and metadata
|
||||
*
|
||||
* @param item1 First ItemStack
|
||||
* @param item2 Second ItemStack
|
||||
* @return true if the items are considered equal
|
||||
*/
|
||||
public static boolean compareItems(ItemStack item1, ItemStack item2) {
|
||||
if (item1 == null || item2 == null) return false;
|
||||
if (!item1.getType().equals(item2.getType())) return false;
|
||||
|
||||
org.bukkit.inventory.meta.ItemMeta meta1 = item1.getItemMeta();
|
||||
org.bukkit.inventory.meta.ItemMeta meta2 = item2.getItemMeta();
|
||||
|
||||
if (meta1 == null || meta2 == null) return meta1 == meta2;
|
||||
|
||||
// Check CustomModelData if available (1.14+)
|
||||
try {
|
||||
return meta1.hasCustomModelData() && meta2.hasCustomModelData()
|
||||
&& meta1.getCustomModelData() == meta2.getCustomModelData();
|
||||
} catch (NoSuchMethodError ignored) {
|
||||
// Pre 1.14, check Durability/Damage value instead
|
||||
return item1.getDurability() == item2.getDurability();
|
||||
}
|
||||
}
|
||||
|
||||
private static final String[] RIM_PREFIXES = {
|
||||
"sport", "racing", "luxury", "classic", "vintage", "modern", "elite", "premium", "pro", "ultra"
|
||||
};
|
||||
|
||||
private static final String[] RIM_TYPES = {
|
||||
"star", "spoke", "mesh", "alloy", "chrome", "forged", "cast", "split", "blade", "wave"
|
||||
};
|
||||
|
||||
private static final String[] RIM_SUFFIXES = {
|
||||
"design", "series", "line", "edition", "collection", "style", "plus", "max", "elite", "pro"
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a realistic rim design name
|
||||
*
|
||||
* @return A random rim design name
|
||||
*/
|
||||
public static String generateRimName() {
|
||||
String prefix = RIM_PREFIXES[(int) (Math.random() * RIM_PREFIXES.length)];
|
||||
String type = RIM_TYPES[(int) (Math.random() * RIM_TYPES.length)];
|
||||
String suffix = RIM_SUFFIXES[(int) (Math.random() * RIM_SUFFIXES.length)];
|
||||
|
||||
// Add a random number between 100 and 999
|
||||
int number = 100 + (int) (Math.random() * 900);
|
||||
|
||||
// Convert to PascalCase
|
||||
return prefix.substring(0, 1).toUpperCase() + prefix.substring(1) +
|
||||
type.substring(0, 1).toUpperCase() + type.substring(1) +
|
||||
suffix.substring(0, 1).toUpperCase() + suffix.substring(1) +
|
||||
number;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue