Compare commits

..

3 commits

5 changed files with 199 additions and 44 deletions

View file

@ -6,7 +6,7 @@
<groupId>tech.sbdevelopment</groupId> <groupId>tech.sbdevelopment</groupId>
<artifactId>VehiclesPlusConverter</artifactId> <artifactId>VehiclesPlusConverter</artifactId>
<version>0.2.2</version> <version>0.2.4</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>VehiclesPlusConverter</name> <name>VehiclesPlusConverter</name>
@ -80,9 +80,9 @@
<dependency> <dependency>
<groupId>nl.sbdeveloper</groupId> <groupId>nl.sbdeveloper</groupId>
<artifactId>VehiclesPlus-v3</artifactId> <artifactId>VehiclesPlus-v3</artifactId>
<version>3.0.1</version> <version>3.0.3</version>
<scope>system</scope> <scope>system</scope>
<systemPath>${project.basedir}/src/libs/VehiclesPlus-3.0.1.jar</systemPath> <systemPath>${project.basedir}/src/libs/VehiclesPlus-3.0.3.jar</systemPath>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View file

@ -30,8 +30,8 @@ public final class VehiclesPlusConverter extends JavaPlugin {
} }
Version versionNew = Version.of(Bukkit.getPluginManager().getPlugin("VehiclesPlus").getDescription().getVersion()); Version versionNew = Version.of(Bukkit.getPluginManager().getPlugin("VehiclesPlus").getDescription().getVersion());
if (versionNew.isOlderThan(Version.of("3.0.2"))) { 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.2!"); Bukkit.getLogger().severe("Your VehiclesPlus v3 plugin is too old! Please update to at least v3.0.3!");
Bukkit.getPluginManager().disablePlugin(this); Bukkit.getPluginManager().disablePlugin(this);
return; return;
} }

View file

@ -1,9 +1,14 @@
package tech.sbdevelopment.vehiclesplusconverter.api; package tech.sbdevelopment.vehiclesplusconverter.api;
import java.io.IOException; import java.io.IOException;
import java.util.Set;
public class ConversionException extends IOException { public class ConversionException extends IOException {
public ConversionException(String before, String filename) { public ConversionException(String explanation, String filename) {
super(before + " " + filename + ".yml"); 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));
} }
} }

View file

@ -23,14 +23,19 @@ import nl.sbdeveloper.vehiclesplus.api.vehicles.settings.impl.*;
import nl.sbdeveloper.vehiclesplus.storage.db.exceptions.DataStorageException; import nl.sbdeveloper.vehiclesplus.storage.db.exceptions.DataStorageException;
import nl.sbdeveloper.vehiclesplus.utils.jackson.ColorList; import nl.sbdeveloper.vehiclesplus.utils.jackson.ColorList;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import tech.sbdevelopment.vehiclesplusconverter.VehiclesPlusConverter; import tech.sbdevelopment.vehiclesplusconverter.VehiclesPlusConverter;
import tech.sbdevelopment.vehiclesplusconverter.api.ConversionException; import tech.sbdevelopment.vehiclesplusconverter.api.ConversionException;
import java.util.List; import java.io.File;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level;
import static tech.sbdevelopment.vehiclesplusconverter.utils.MainUtil.*; import static tech.sbdevelopment.vehiclesplusconverter.utils.MainUtil.*;
@ -73,8 +78,7 @@ public class Converter {
try { try {
disablePlugin(VehiclesPlus.getInstance()); disablePlugin(VehiclesPlus.getInstance());
disablePlugin(VehiclesPlusConverter.getInstance()); disablePlugin(VehiclesPlusConverter.getInstance());
} catch (Exception e) { } catch (Exception ignored) {
e.printStackTrace();
} }
} }
counter--; counter--;
@ -85,13 +89,14 @@ public class Converter {
private static void convertRims() { private static void convertRims() {
for (Map.Entry<String, RimDesign> entry : VehiclesPlus.getVehicleManager().getRimDesignHashMap().entrySet()) { 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( nl.sbdeveloper.vehiclesplus.api.vehicles.rims.RimDesign rd = new nl.sbdeveloper.vehiclesplus.api.vehicles.rims.RimDesign(
entry.getValue().getName(), entry.getValue().getName().toLowerCase(),
entry.getValue().getSkin(), entry.getValue().getSkin(),
HolderItemPosition.HEAD, HolderItemPosition.HEAD,
entry.getValue().getPrice() entry.getValue().getPrice()
); );
nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getRimDesigns().put(entry.getKey(), rd); nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getRimDesigns().put(entry.getKey(), rd);
rd.save();
VehiclesPlusConverter.getInstance().getLogger().info("Converted rim design: " + rd.getName()); VehiclesPlusConverter.getInstance().getLogger().info("Converted rim design: " + rd.getName());
} }
@ -106,6 +111,7 @@ public class Converter {
); );
nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getFuelTypes().put(entry.getKey(), ft); nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getFuelTypes().put(entry.getKey(), ft);
ft.save();
VehiclesPlusConverter.getInstance().getLogger().info("Converted fuel type: " + ft.getName()); VehiclesPlusConverter.getInstance().getLogger().info("Converted fuel type: " + ft.getName());
} }
@ -115,6 +121,11 @@ public class Converter {
VehiclesPlusConverter.getInstance().getLogger().info("Converting vehicle models: " + VehiclesPlusAPI.getVehicleManager().getBaseVehicleMap().values().stream().map(BaseVehicle::getName).reduce((s1, s2) -> s1 + ", " + s2).orElse("")); 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()) { for (BaseVehicle baseVehicle : VehiclesPlusAPI.getVehicleManager().getBaseVehicleMap().values()) {
if (baseVehicle.getName().startsWith("Example")) {
VehiclesPlusConverter.getInstance().getLogger().info("Skipping example vehicle model: " + baseVehicle.getName());
continue;
}
try { try {
VehicleModel.Builder vehicleModelBuilder = VehicleModel.builder() VehicleModel.Builder vehicleModelBuilder = VehicleModel.builder()
.id(baseVehicle.getName()) .id(baseVehicle.getName())
@ -137,7 +148,12 @@ public class Converter {
turretSeat.getXOffset(), turretSeat.getXOffset(),
turretSeat.getYOffset(), turretSeat.getYOffset(),
turretSeat.getZOffset(), 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) { } else if (part instanceof Seat) {
Seat seat = (Seat) part; Seat seat = (Seat) part;
@ -187,15 +203,52 @@ public class Converter {
)); ));
} else if (part instanceof Wheel) { } else if (part instanceof Wheel) {
Wheel wheel = (Wheel) part; Wheel wheel = (Wheel) part;
vehicleModelBuilder = vehicleModelBuilder.part(new nl.sbdeveloper.vehiclesplus.api.vehicles.parts.impl.Wheel( 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.getXOffset(),
wheel.getYOffset(), wheel.getYOffset(),
wheel.getZOffset(), wheel.getZOffset(),
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())), newRimDesign,
wheel.getColor(), wheel.getColor(),
wheel.getSteering(), wheel.getSteering(),
wheel.getRotationOffset() 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()
));
}
} }
} }
@ -275,6 +328,7 @@ public class Converter {
VehiclesPlusConverter.getInstance().getLogger().info("Converted vehicle model: " + model.getId()); VehiclesPlusConverter.getInstance().getLogger().info("Converted vehicle model: " + model.getId());
saveToVehiclesPlus(model, "vehicles/" + model.getTypeId(), model.getId()); saveToVehiclesPlus(model, "vehicles/" + model.getTypeId(), model.getId());
nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getVehicleModels().put(model.getId(), model);
} catch (Exception e) { } catch (Exception e) {
VehiclesPlusConverter.getInstance().getLogger().log(java.util.logging.Level.SEVERE, "Could not convert vehicle model: " + baseVehicle.getName(), e); VehiclesPlusConverter.getInstance().getLogger().log(java.util.logging.Level.SEVERE, "Could not convert vehicle model: " + baseVehicle.getName(), e);
} }
@ -282,40 +336,77 @@ public class Converter {
} }
private static void convertVehicles() { private static void convertVehicles() {
for (Map.Entry<UUID, List<StorageVehicle>> set : VehiclesPlusAPI.getVehicleManager().getPlayerVehicleHashMap().entrySet()) { File baseDir = new File("plugins/VehiclesPlusPro/data");
UUID ownerUUID = set.getKey(); if (!baseDir.exists()) {
String ownerName = Bukkit.getOfflinePlayer(ownerUUID).getName(); VehiclesPlusConverter.getInstance().getLogger().severe("Could not find the VehiclesPlusPro data folder!");
if (ownerName == null) { return;
VehiclesPlusConverter.getInstance().getLogger().severe("Could not convert vehicles for player with UUID " + ownerUUID + ", the player name is unknown!"); }
continue;
}
final Garage garage = nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getGarage(ownerName).orElseGet(() -> new Garage(ownerName, ownerUUID)); for (File playerDir : baseDir.listFiles()) {
VehiclesPlusConverter.getInstance().getLogger().info("Converting vehicles for player with UUID " + ownerUUID + " (" + ownerName + ")..."); if (playerDir.isDirectory()) {
String ownerUUID = playerDir.getName();
for (StorageVehicle vehicle : set.getValue()) { OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(ownerUUID));
try { if (player.getName() == null) {
nl.sbdeveloper.vehiclesplus.api.vehicles.impl.StorageVehicle newVehicle = new nl.sbdeveloper.vehiclesplus.api.vehicles.impl.StorageVehicle( VehiclesPlusConverter.getInstance().getLogger().severe("Could not find player with UUID: " + ownerUUID + ", skipping...");
UUID.randomUUID(), continue;
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
);
newVehicle.forceSave();
garage.addVehicle(newVehicle.getUuid());
} catch (Exception 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()); VehiclesPlusConverter.getInstance().getLogger().info("Converting vehicles for player with UUID " + ownerUUID + "...");
} final Garage garage = nl.sbdeveloper.vehiclesplus.api.VehiclesPlusAPI.getPersonalGarage(player);
try { int i = 0;
garage.forceSave(); for (File vehicleFile : playerDir.listFiles()) {
} catch (DataStorageException e) { if (vehicleFile.getName().contains(".yml")) {
e.printStackTrace(); StorageVehicle vehicle;
Bukkit.getLogger().severe("Could not convert vehicles for player with UUID " + ownerUUID + ", could not save the garage!"); 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;
}
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())),
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);
}
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);
} }
} }
} }

View file

@ -3,6 +3,7 @@ package tech.sbdevelopment.vehiclesplusconverter.utils;
import com.google.common.io.Files; import com.google.common.io.Files;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import nl.sbdeveloper.vehiclesplus.storage.file.HJSONFile; import nl.sbdeveloper.vehiclesplus.storage.file.HJSONFile;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import tech.sbdevelopment.vehiclesplusconverter.VehiclesPlusConverter; import tech.sbdevelopment.vehiclesplusconverter.VehiclesPlusConverter;
import tech.sbdevelopment.vehiclesplusconverter.api.ConversionException; import tech.sbdevelopment.vehiclesplusconverter.api.ConversionException;
@ -86,4 +87,62 @@ public class MainUtil {
VehiclesPlusConverter.getInstance().getLogger().log(Level.SEVERE, "Couldn't save to the file " + fileName, e); 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;
}
} }