mirror of
https://github.com/WiIIiam278/HuskSync.git
synced 2025-12-24 00:59:18 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5056a794d8 | ||
|
|
5e6068431a | ||
|
|
8d69508689 | ||
|
|
efb6d8a7de | ||
|
|
79d9778378 | ||
|
|
6a6695e447 | ||
|
|
8862e6cd70 | ||
|
|
0b29de9efc | ||
|
|
962cdfce0b | ||
|
|
0c527202e5 | ||
|
|
d4e33aa9d2 | ||
|
|
2fcd58fc18 | ||
|
|
3d10b2324f | ||
|
|
31419f3b97 | ||
|
|
8105ac27fc | ||
|
|
44f251a948 | ||
|
|
463e707d27 | ||
|
|
2d85910744 |
@@ -83,9 +83,9 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2'
|
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.3'
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.2'
|
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.3'
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.2'
|
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.3'
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation project(path: ':common')
|
implementation project(path: ':common')
|
||||||
|
|
||||||
implementation 'net.william278.uniform:uniform-bukkit:1.1.4'
|
implementation 'net.william278.uniform:uniform-bukkit:1.2.1'
|
||||||
implementation 'net.william278:mpdbdataconverter:1.0.1'
|
implementation 'net.william278:mpdbdataconverter:1.0.1'
|
||||||
implementation 'net.william278:hsldataconverter:1.0'
|
implementation 'net.william278:hsldataconverter:1.0'
|
||||||
implementation 'net.william278:mapdataapi:1.0.3'
|
implementation 'net.william278:mapdataapi:1.0.3'
|
||||||
@@ -10,12 +10,12 @@ dependencies {
|
|||||||
implementation 'net.kyori:adventure-platform-bukkit:4.3.3'
|
implementation 'net.kyori:adventure-platform-bukkit:4.3.3'
|
||||||
implementation 'dev.triumphteam:triumph-gui:3.1.10'
|
implementation 'dev.triumphteam:triumph-gui:3.1.10'
|
||||||
implementation 'space.arim.morepaperlib:morepaperlib:0.4.4'
|
implementation 'space.arim.morepaperlib:morepaperlib:0.4.4'
|
||||||
implementation 'de.tr7zw:item-nbt-api:2.13.1-SNAPSHOT'
|
implementation 'de.tr7zw:item-nbt-api:2.13.1'
|
||||||
|
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||||
compileOnly 'com.github.retrooper.packetevents:spigot:2.3.0'
|
compileOnly 'com.github.retrooper.packetevents:spigot:2.3.0'
|
||||||
compileOnly 'com.comphenix.protocol:ProtocolLib:5.1.0'
|
compileOnly 'com.comphenix.protocol:ProtocolLib:5.1.0'
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.32'
|
compileOnly 'org.projectlombok:lombok:1.18.34'
|
||||||
compileOnly 'commons-io:commons-io:2.16.1'
|
compileOnly 'commons-io:commons-io:2.16.1'
|
||||||
compileOnly 'org.json:json:20240303'
|
compileOnly 'org.json:json:20240303'
|
||||||
compileOnly 'net.william278:minedown:1.8.2'
|
compileOnly 'net.william278:minedown:1.8.2'
|
||||||
@@ -25,7 +25,7 @@ dependencies {
|
|||||||
compileOnly 'net.william278:AdvancementAPI:97a9583413'
|
compileOnly 'net.william278:AdvancementAPI:97a9583413'
|
||||||
compileOnly "redis.clients:jedis:$jedis_version"
|
compileOnly "redis.clients:jedis:$jedis_version"
|
||||||
|
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.32'
|
annotationProcessor 'org.projectlombok:lombok:1.18.34'
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync, BukkitTask.S
|
|||||||
@Override
|
@Override
|
||||||
public boolean isDependencyLoaded(@NotNull String name) {
|
public boolean isDependencyLoaded(@NotNull String name) {
|
||||||
final Plugin plugin = getServer().getPluginManager().getPlugin(name);
|
final Plugin plugin = getServer().getPluginManager().getPlugin(name);
|
||||||
return plugin != null && plugin.isEnabled();
|
return plugin != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register bStats metrics
|
// Register bStats metrics
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.google.gson.annotations.SerializedName;
|
|||||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||||
import de.tr7zw.changeme.nbtapi.NBTPersistentDataContainer;
|
import de.tr7zw.changeme.nbtapi.NBTPersistentDataContainer;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
import net.kyori.adventure.util.TriState;
|
||||||
import net.william278.desertwell.util.ThrowingConsumer;
|
import net.william278.desertwell.util.ThrowingConsumer;
|
||||||
import net.william278.desertwell.util.Version;
|
import net.william278.desertwell.util.Version;
|
||||||
import net.william278.husksync.BukkitHuskSync;
|
import net.william278.husksync.BukkitHuskSync;
|
||||||
@@ -35,6 +36,7 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Registry;
|
import org.bukkit.Registry;
|
||||||
import org.bukkit.Statistic;
|
import org.bukkit.Statistic;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.advancement.AdvancementProgress;
|
import org.bukkit.advancement.AdvancementProgress;
|
||||||
import org.bukkit.attribute.AttributeInstance;
|
import org.bukkit.attribute.AttributeInstance;
|
||||||
import org.bukkit.attribute.AttributeModifier;
|
import org.bukkit.attribute.AttributeModifier;
|
||||||
@@ -565,6 +567,11 @@ public abstract class BukkitData implements Data {
|
|||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public static class Attributes extends BukkitData implements Data.Attributes, Adaptable {
|
public static class Attributes extends BukkitData implements Data.Attributes, Adaptable {
|
||||||
|
|
||||||
|
private static final String EQUIPMENT_SLOT_GROUP = "org.bukkit.inventory.EquipmentSlotGroup";
|
||||||
|
private static final String EQUIPMENT_SLOT_GROUP$ANY = "ANY";
|
||||||
|
private static final String EQUIPMENT_SLOT$getGroup = "getGroup";
|
||||||
|
private static TriState USE_KEYED_MODIFIERS = TriState.NOT_SET;
|
||||||
|
|
||||||
private List<Attribute> attributes;
|
private List<Attribute> attributes;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -572,12 +579,12 @@ public abstract class BukkitData implements Data {
|
|||||||
final List<Attribute> attributes = Lists.newArrayList();
|
final List<Attribute> attributes = Lists.newArrayList();
|
||||||
Registry.ATTRIBUTE.forEach(id -> {
|
Registry.ATTRIBUTE.forEach(id -> {
|
||||||
final AttributeInstance instance = player.getAttribute(id);
|
final AttributeInstance instance = player.getAttribute(id);
|
||||||
if (instance == null || instance.getValue() == instance.getDefaultValue() || plugin
|
if (instance == null || Double.compare(instance.getValue(), instance.getDefaultValue()) == 0
|
||||||
.getSettings().getSynchronization().isIgnoredAttribute(id.getKey().toString())) {
|
|| plugin.getSettings().getSynchronization().isIgnoredAttribute(id.getKey().toString())) {
|
||||||
// We don't sync unmodified or disabled attributes
|
// We don't sync unmodified or disabled attributes
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
attributes.add(adapt(instance, plugin.getMinecraftVersion()));
|
attributes.add(adapt(instance));
|
||||||
});
|
});
|
||||||
return new BukkitData.Attributes(attributes);
|
return new BukkitData.Attributes(attributes);
|
||||||
}
|
}
|
||||||
@@ -596,18 +603,18 @@ public abstract class BukkitData implements Data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static Attribute adapt(@NotNull AttributeInstance instance, @NotNull Version version) {
|
private static Attribute adapt(@NotNull AttributeInstance instance) {
|
||||||
return new Attribute(
|
return new Attribute(
|
||||||
instance.getAttribute().getKey().toString(),
|
instance.getAttribute().getKey().toString(),
|
||||||
instance.getBaseValue(),
|
instance.getBaseValue(),
|
||||||
instance.getModifiers().stream().map(m -> adapt(m, version)).collect(Collectors.toSet())
|
instance.getModifiers().stream().map(BukkitData.Attributes::adapt).collect(Collectors.toSet())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static Modifier adapt(@NotNull AttributeModifier modifier, @NotNull Version version) {
|
private static Modifier adapt(@NotNull AttributeModifier modifier) {
|
||||||
return new Modifier(
|
return new Modifier(
|
||||||
version.compareTo(Version.fromString("1.21")) >= 0 ? null : modifier.getUniqueId(),
|
getModifierId(modifier),
|
||||||
modifier.getName(),
|
modifier.getName(),
|
||||||
modifier.getAmount(),
|
modifier.getAmount(),
|
||||||
modifier.getOperation().ordinal(),
|
modifier.getOperation().ordinal(),
|
||||||
@@ -615,28 +622,71 @@ public abstract class BukkitData implements Data {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Nullable
|
||||||
public void apply(@NotNull BukkitUser user, @NotNull BukkitHuskSync plugin) throws IllegalStateException {
|
private static UUID getModifierId(@NotNull AttributeModifier modifier) {
|
||||||
Registry.ATTRIBUTE.forEach(id -> applyAttribute(user.getPlayer().getAttribute(id), getAttribute(id).orElse(null)));
|
try {
|
||||||
|
return modifier.getUniqueId();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void applyAttribute(@Nullable AttributeInstance instance, @Nullable Attribute attribute) {
|
private static void applyAttribute(@Nullable AttributeInstance instance, @Nullable Attribute attribute,
|
||||||
|
@NotNull HuskSync plugin) {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
instance.setBaseValue(attribute == null ? instance.getDefaultValue() : attribute.baseValue());
|
instance.setBaseValue(attribute == null ? instance.getDefaultValue() : attribute.baseValue());
|
||||||
instance.getModifiers().forEach(instance::removeModifier);
|
instance.getModifiers().forEach(instance::removeModifier);
|
||||||
if (attribute != null) {
|
if (attribute != null) {
|
||||||
attribute.modifiers().forEach(modifier -> instance.addModifier(new AttributeModifier(
|
attribute.modifiers().forEach(modifier -> instance.addModifier(adapt(modifier, plugin)));
|
||||||
modifier.uuid(),
|
|
||||||
modifier.name(),
|
|
||||||
modifier.amount(),
|
|
||||||
AttributeModifier.Operation.values()[modifier.operationType()],
|
|
||||||
modifier.equipmentSlot() != -1 ? EquipmentSlot.values()[modifier.equipmentSlot()] : null
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("JavaReflectionMemberAccess")
|
||||||
|
@NotNull
|
||||||
|
private static AttributeModifier adapt(@NotNull Modifier modifier, @NotNull HuskSync plugin) {
|
||||||
|
final int slotId = modifier.equipmentSlot();
|
||||||
|
if (USE_KEYED_MODIFIERS == TriState.NOT_SET) {
|
||||||
|
USE_KEYED_MODIFIERS = TriState.byBoolean(plugin.getMinecraftVersion()
|
||||||
|
.compareTo(Version.fromString("1.21")) >= 0);
|
||||||
|
}
|
||||||
|
if (USE_KEYED_MODIFIERS == TriState.TRUE) {
|
||||||
|
try {
|
||||||
|
// Reflexively create a modern keyed attribute modifier instance. Remove in favor of API long-term.
|
||||||
|
final EquipmentSlot slot = slotId != -1 ? EquipmentSlot.values()[slotId] : null;
|
||||||
|
final Class<?> slotGroup = Class.forName(EQUIPMENT_SLOT_GROUP);
|
||||||
|
final String modifierName = modifier.name() == null ? modifier.uuid().toString() : modifier.name();
|
||||||
|
return AttributeModifier.class.getDeclaredConstructor(
|
||||||
|
NamespacedKey.class, double.class, AttributeModifier.Operation.class, slotGroup
|
||||||
|
).newInstance(
|
||||||
|
NamespacedKey.fromString(modifierName),
|
||||||
|
modifier.amount(),
|
||||||
|
AttributeModifier.Operation.values()[modifier.operationType()],
|
||||||
|
slot == null ? slotGroup.getField(EQUIPMENT_SLOT_GROUP$ANY).get(null)
|
||||||
|
: EquipmentSlot.class.getDeclaredMethod(EQUIPMENT_SLOT$getGroup).invoke(slot)
|
||||||
|
);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
plugin.log(Level.WARNING, "Error reflectively creating keyed attribute modifier", e);
|
||||||
|
USE_KEYED_MODIFIERS = TriState.FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new AttributeModifier(
|
||||||
|
modifier.uuid(),
|
||||||
|
modifier.name(),
|
||||||
|
modifier.amount(),
|
||||||
|
AttributeModifier.Operation.values()[modifier.operationType()],
|
||||||
|
slotId != -1 ? EquipmentSlot.values()[slotId] : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(@NotNull BukkitUser user, @NotNull BukkitHuskSync plugin) throws IllegalStateException {
|
||||||
|
Registry.ATTRIBUTE.forEach(id -> applyAttribute(
|
||||||
|
user.getPlayer().getAttribute(id), getAttribute(id).orElse(null), plugin
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -696,11 +746,12 @@ public abstract class BukkitData implements Data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set health scale
|
// Set health scale
|
||||||
|
double scale = healthScale <= 0 ? player.getMaxHealth() : healthScale;
|
||||||
try {
|
try {
|
||||||
player.setHealthScale(healthScale);
|
player.setHealthScale(scale);
|
||||||
player.setHealthScaled(isHealthScaled);
|
player.setHealthScaled(isHealthScaled);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
plugin.log(Level.WARNING, "Error setting %s's health scale to %s".formatted(player.getName(), healthScale), e);
|
plugin.log(Level.WARNING, "Error setting %s's health scale to %s".formatted(player.getName(), scale), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ public class BukkitSerializer {
|
|||||||
case "1.20", "1.20.1", "1.20.2" -> DataFixerUtil.VERSION1_20_2;
|
case "1.20", "1.20.1", "1.20.2" -> DataFixerUtil.VERSION1_20_2;
|
||||||
case "1.20.3", "1.20.4" -> DataFixerUtil.VERSION1_20_4;
|
case "1.20.3", "1.20.4" -> DataFixerUtil.VERSION1_20_4;
|
||||||
case "1.20.5", "1.20.6" -> DataFixerUtil.VERSION1_20_5;
|
case "1.20.5", "1.20.6" -> DataFixerUtil.VERSION1_20_5;
|
||||||
|
case "1.21" -> DataFixerUtil.VERSION1_21;
|
||||||
default -> DataFixerUtil.getCurrentVersion();
|
default -> DataFixerUtil.getCurrentVersion();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ public class MpdbMigrator extends Migrator {
|
|||||||
If any of these are not correct, please correct them
|
If any of these are not correct, please correct them
|
||||||
using the command:
|
using the command:
|
||||||
"husksync migrate mpdb set <parameter> <value>"
|
"husksync migrate mpdb set <parameter> <value>"
|
||||||
(e.g.: "husksync migrate mpdb set host 1.2.3.4")
|
(e.g.: "husksync migrate set mpdb host 1.2.3.4")
|
||||||
|
|
||||||
STEP 3] HuskSync will migrate data into the database
|
STEP 3] HuskSync will migrate data into the database
|
||||||
tables configures in the config.yml file of this
|
tables configures in the config.yml file of this
|
||||||
@@ -263,7 +263,7 @@ public class MpdbMigrator extends Migrator {
|
|||||||
before proceeding.
|
before proceeding.
|
||||||
|
|
||||||
STEP 4] To start the migration, please run:
|
STEP 4] To start the migration, please run:
|
||||||
"husksync migrate mpdb start"
|
"husksync migrate start mpdb"
|
||||||
|
|
||||||
NOTE: This migrator currently WORKS WITH MPDB version
|
NOTE: This migrator currently WORKS WITH MPDB version
|
||||||
v4.9.2 and below!
|
v4.9.2 and below!
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ dependencies {
|
|||||||
exclude module: 'slf4j-api'
|
exclude module: 'slf4j-api'
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOnly 'net.william278.uniform:uniform-common:1.1.4'
|
compileOnly 'net.william278.uniform:uniform-common:1.2.1'
|
||||||
compileOnly 'com.mojang:brigadier:1.1.8'
|
compileOnly 'com.mojang:brigadier:1.1.8'
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.32'
|
compileOnly 'org.projectlombok:lombok:1.18.34'
|
||||||
compileOnly 'org.jetbrains:annotations:24.1.0'
|
compileOnly 'org.jetbrains:annotations:24.1.0'
|
||||||
compileOnly 'net.kyori:adventure-api:4.17.0'
|
compileOnly 'net.kyori:adventure-api:4.17.0'
|
||||||
compileOnly 'net.kyori:adventure-platform-api:4.3.3'
|
compileOnly 'net.kyori:adventure-platform-api:4.3.3'
|
||||||
@@ -38,5 +38,5 @@ dependencies {
|
|||||||
testCompileOnly 'de.exlll:configlib-yaml:4.5.0'
|
testCompileOnly 'de.exlll:configlib-yaml:4.5.0'
|
||||||
testCompileOnly 'org.jetbrains:annotations:24.1.0'
|
testCompileOnly 'org.jetbrains:annotations:24.1.0'
|
||||||
|
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.32'
|
annotationProcessor 'org.projectlombok:lombok:1.18.34'
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ public class HuskSyncCommand extends PluginCommand {
|
|||||||
private final AboutMenu aboutMenu;
|
private final AboutMenu aboutMenu;
|
||||||
|
|
||||||
public HuskSyncCommand(@NotNull HuskSync plugin) {
|
public HuskSyncCommand(@NotNull HuskSync plugin) {
|
||||||
super("husksync", List.of(), Permission.Default.TRUE, plugin);
|
super("husksync", List.of(), Permission.Default.TRUE, ExecutionScope.ALL, plugin);
|
||||||
this.updateChecker = plugin.getUpdateChecker();
|
this.updateChecker = plugin.getUpdateChecker();
|
||||||
this.aboutMenu = AboutMenu.builder()
|
this.aboutMenu = AboutMenu.builder()
|
||||||
.title(Component.text("HuskSync"))
|
.title(Component.text("HuskSync"))
|
||||||
@@ -160,6 +160,10 @@ public class HuskSyncCommand extends PluginCommand {
|
|||||||
.collect(Collectors.joining("\n"))
|
.collect(Collectors.joining("\n"))
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
sub.addSubCommand("help", (help) -> help.addSyntax((cmd) -> {
|
||||||
|
final Migrator migrator = cmd.getArgument("migrator", Migrator.class);
|
||||||
|
plugin.log(Level.INFO, migrator.getHelpMenu());
|
||||||
|
}, migrator()));
|
||||||
sub.addSubCommand("start", (start) -> start.addSyntax((cmd) -> {
|
sub.addSubCommand("start", (start) -> start.addSyntax((cmd) -> {
|
||||||
final Migrator migrator = cmd.getArgument("migrator", Migrator.class);
|
final Migrator migrator = cmd.getArgument("migrator", Migrator.class);
|
||||||
migrator.start().thenAccept(succeeded -> {
|
migrator.start().thenAccept(succeeded -> {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import java.util.UUID;
|
|||||||
public abstract class ItemsCommand extends PluginCommand {
|
public abstract class ItemsCommand extends PluginCommand {
|
||||||
|
|
||||||
protected ItemsCommand(@NotNull String name, @NotNull List<String> aliases, @NotNull HuskSync plugin) {
|
protected ItemsCommand(@NotNull String name, @NotNull List<String> aliases, @NotNull HuskSync plugin) {
|
||||||
super(name, aliases, Permission.Default.IF_OP, plugin);
|
super(name, aliases, Permission.Default.IF_OP, ExecutionScope.IN_GAME, plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ public abstract class PluginCommand extends Command {
|
|||||||
|
|
||||||
protected final HuskSync plugin;
|
protected final HuskSync plugin;
|
||||||
|
|
||||||
protected PluginCommand(@NotNull String name, @NotNull List<String> aliases,
|
protected PluginCommand(@NotNull String name, @NotNull List<String> aliases, @NotNull Permission.Default defPerm,
|
||||||
@NotNull Permission.Default permissionDefault, @NotNull HuskSync plugin) {
|
@NotNull ExecutionScope scope, @NotNull HuskSync plugin) {
|
||||||
super(name, aliases, getDescription(plugin, name), new Permission(createPermission(name), permissionDefault));
|
super(name, aliases, getDescription(plugin, name), new Permission(createPermission(name), defPerm), scope);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import java.util.logging.Level;
|
|||||||
public class UserDataCommand extends PluginCommand {
|
public class UserDataCommand extends PluginCommand {
|
||||||
|
|
||||||
public UserDataCommand(@NotNull HuskSync plugin) {
|
public UserDataCommand(@NotNull HuskSync plugin) {
|
||||||
super("userdata", List.of("playerdata"), Permission.Default.IF_OP, plugin);
|
super("userdata", List.of("playerdata"), Permission.Default.IF_OP, ExecutionScope.ALL, plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -155,14 +155,14 @@ public interface Data {
|
|||||||
*/
|
*/
|
||||||
interface Advancements extends Data {
|
interface Advancements extends Data {
|
||||||
|
|
||||||
|
String RECIPE_ADVANCEMENT = "minecraft:recipe";
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
List<Advancement> getCompleted();
|
List<Advancement> getCompleted();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
default List<Advancement> getCompletedExcludingRecipes() {
|
default List<Advancement> getCompletedExcludingRecipes() {
|
||||||
return getCompleted().stream()
|
return getCompleted().stream().filter(adv -> !adv.getKey().startsWith(RECIPE_ADVANCEMENT)).toList();
|
||||||
.filter(advancement -> !advancement.getKey().startsWith("minecraft:recipe"))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCompleted(@NotNull List<Advancement> completed);
|
void setCompleted(@NotNull List<Advancement> completed);
|
||||||
@@ -191,13 +191,13 @@ public interface Data {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private static Map<String, Long> adaptDateMap(@NotNull Map<String, Date> dateMap) {
|
private static Map<String, Long> adaptDateMap(@NotNull Map<String, Date> dateMap) {
|
||||||
return dateMap.entrySet().stream()
|
return dateMap.entrySet().stream()
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getTime()));
|
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getTime()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static Map<String, Date> adaptLongMap(@NotNull Map<String, Long> dateMap) {
|
private static Map<String, Date> adaptLongMap(@NotNull Map<String, Long> dateMap) {
|
||||||
return dateMap.entrySet().stream()
|
return dateMap.entrySet().stream()
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, e -> new Date(e.getValue())));
|
.collect(Collectors.toMap(Map.Entry::getKey, e -> new Date(e.getValue())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -250,9 +250,9 @@ public interface Data {
|
|||||||
void setWorld(@NotNull World world);
|
void setWorld(@NotNull World world);
|
||||||
|
|
||||||
record World(
|
record World(
|
||||||
@SerializedName("name") @NotNull String name,
|
@SerializedName("name") @NotNull String name,
|
||||||
@SerializedName("uuid") @NotNull UUID uuid,
|
@SerializedName("uuid") @NotNull UUID uuid,
|
||||||
@SerializedName("environment") @NotNull String environment
|
@SerializedName("environment") @NotNull String environment
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -324,9 +324,9 @@ public interface Data {
|
|||||||
List<Attribute> getAttributes();
|
List<Attribute> getAttributes();
|
||||||
|
|
||||||
record Attribute(
|
record Attribute(
|
||||||
@NotNull String name,
|
@NotNull String name,
|
||||||
double baseValue,
|
double baseValue,
|
||||||
@NotNull Set<Modifier> modifiers
|
@NotNull Set<Modifier> modifiers
|
||||||
) {
|
) {
|
||||||
|
|
||||||
public double getValue() {
|
public double getValue() {
|
||||||
@@ -387,8 +387,8 @@ public interface Data {
|
|||||||
|
|
||||||
default Optional<Attribute> getAttribute(@NotNull Key key) {
|
default Optional<Attribute> getAttribute(@NotNull Key key) {
|
||||||
return getAttributes().stream()
|
return getAttributes().stream()
|
||||||
.filter(attribute -> attribute.name().equals(key.asString()))
|
.filter(attribute -> attribute.name().equals(key.asString()))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
default void removeAttribute(@NotNull Key key) {
|
default void removeAttribute(@NotNull Key key) {
|
||||||
@@ -397,8 +397,8 @@ public interface Data {
|
|||||||
|
|
||||||
default double getMaxHealth() {
|
default double getMaxHealth() {
|
||||||
return getAttribute(MAX_HEALTH_KEY)
|
return getAttribute(MAX_HEALTH_KEY)
|
||||||
.map(Attribute::getValue)
|
.map(Attribute::getValue)
|
||||||
.orElse(20.0);
|
.orElse(20.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void setMaxHealth(double maxHealth) {
|
default void setMaxHealth(double maxHealth) {
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ public class DataSnapshot {
|
|||||||
.map(entry -> Map.entry(plugin.getIdentifier(entry.getKey()).orElseThrow(), entry.getValue()))
|
.map(entry -> Map.entry(plugin.getIdentifier(entry.getKey()).orElseThrow(), entry.getValue()))
|
||||||
.collect(Collectors.toMap(
|
.collect(Collectors.toMap(
|
||||||
Map.Entry::getKey,
|
Map.Entry::getKey,
|
||||||
entry -> plugin.deserializeData(entry.getKey(), entry.getValue()),
|
entry -> plugin.deserializeData(entry.getKey(), entry.getValue(), getMinecraftVersion()),
|
||||||
(a, b) -> b, () -> Maps.newTreeMap(SerializerRegistry.DEPENDENCY_ORDER_COMPARATOR)
|
(a, b) -> b, () -> Maps.newTreeMap(SerializerRegistry.DEPENDENCY_ORDER_COMPARATOR)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package net.william278.husksync.data;
|
package net.william278.husksync.data;
|
||||||
|
|
||||||
|
import net.william278.desertwell.util.Version;
|
||||||
import net.william278.husksync.HuskSync;
|
import net.william278.husksync.HuskSync;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -119,19 +120,36 @@ public interface SerializerRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserialize data for the given {@link Identifier}
|
* Deserialize data of a given {@link Version Minecraft version} for the given {@link Identifier data identifier}
|
||||||
|
*
|
||||||
|
* @param identifier the {@link Identifier} to deserialize data for
|
||||||
|
* @param data the data to deserialize
|
||||||
|
* @param dataMcVersion the Minecraft version of the data
|
||||||
|
* @return the deserialized data
|
||||||
|
* @throws IllegalStateException if no serializer is found for the given {@link Identifier}
|
||||||
|
* @since 3.6.4
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default Data deserializeData(@NotNull Identifier identifier, @NotNull String data,
|
||||||
|
@NotNull Version dataMcVersion) throws IllegalStateException {
|
||||||
|
return getSerializer(identifier).map(serializer -> serializer.deserialize(data, dataMcVersion)).orElseThrow(
|
||||||
|
() -> new IllegalStateException("No serializer found for %s".formatted(identifier))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize data for the given {@link Identifier data identifier}
|
||||||
*
|
*
|
||||||
* @param identifier the {@link Identifier} to deserialize data for
|
* @param identifier the {@link Identifier} to deserialize data for
|
||||||
* @param data the data to deserialize
|
* @param data the data to deserialize
|
||||||
* @return the deserialized data
|
* @return the deserialized data
|
||||||
* @throws IllegalStateException if no serializer is found for the given {@link Identifier}
|
|
||||||
* @since 3.5.4
|
* @since 3.5.4
|
||||||
|
* @deprecated Use {@link #deserializeData(Identifier, String, Version)} instead
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
default Data deserializeData(@NotNull Identifier identifier, @NotNull String data) throws IllegalStateException {
|
@Deprecated(since = "3.6.5")
|
||||||
return getSerializer(identifier).map(serializer -> serializer.deserialize(data)).orElseThrow(
|
default Data deserializeData(@NotNull Identifier identifier, @NotNull String data) {
|
||||||
() -> new IllegalStateException("No serializer found for %s".formatted(identifier))
|
return deserializeData(identifier, data, getPlugin().getMinecraftVersion());
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ This guide will walk you through how to upgrade from HuskSync v1.4.x to HuskSync
|
|||||||
|
|
||||||
### 3. Configure the migrator
|
### 3. Configure the migrator
|
||||||
- With your servers back on and correctly configured to run HuskSync v3.x, ensure nobody is online.
|
- With your servers back on and correctly configured to run HuskSync v3.x, ensure nobody is online.
|
||||||
- Use the console on one of your Spigot servers to enter: `husksync migrate legacy`
|
- Use the console on one of your Spigot servers to enter: `husksync migrate help legacy`
|
||||||
- Carefully read the migration configuration instructions. In most cases, you won't have to change the settings, but if you do need to adjust them, use `husksync migrate legacy set <setting> <value>`.
|
- Carefully read the migration configuration instructions. In most cases, you won't have to change the settings, but if you do need to adjust them, use `husksync migrate set legacy <setting> <value>`.
|
||||||
- Migration will be carried out *from* the database you specify with the settings in console *to* the database configured in `config.yml`. If you're migrating from multiple clusters, ensure you run the migrator on the correct servers corresponding to the migrator.
|
- Migration will be carried out *from* the database you specify with the settings in console *to* the database configured in `config.yml`. If you're migrating from multiple clusters, ensure you run the migrator on the correct servers corresponding to the migrator.
|
||||||
|
|
||||||
### 4. Start the migrator
|
### 4. Start the migrator
|
||||||
- Run `husksync migrate legacy start` to begin the migration process. This may take some time, depending on the amount of data you're migrating.
|
- Run `husksync migrate start legacy` to begin the migration process. This may take some time, depending on the amount of data you're migrating.
|
||||||
|
|
||||||
### 5. Ensure the migration was successful
|
### 5. Ensure the migration was successful
|
||||||
- HuskSync will notify in console when migration is complete. Verify that the migration went OK by logging in and using the `/userdata list <username>` command to see if the data was imported with the `legacy migration` saveCause.
|
- HuskSync will notify in console when migration is complete. Verify that the migration went OK by logging in and using the `/userdata list <username>` command to see if the data was imported with the `legacy migration` saveCause.
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ This guide will walk you through how to migrate from MySQLPlayerDataBridge (MPDB
|
|||||||
|
|
||||||
### 2. Configure the migrator
|
### 2. Configure the migrator
|
||||||
- With your servers back on and correctly configured to run HuskSync v3.x, ensure nobody is online.
|
- With your servers back on and correctly configured to run HuskSync v3.x, ensure nobody is online.
|
||||||
- Use the console on one of your Spigot servers to enter: `husksync migrate mpdb`. If the MPDB migrator is not available, ensure MySQLPlayerDataBridge is still installed.
|
- Use the console on one of your Spigot servers to enter: `husksync migrate help mpdb`. If the MPDB migrator is not available, ensure MySQLPlayerDataBridge is still installed.
|
||||||
- Adjust the migration setting as needed using the following command: `husksync migrate mpdb set <setting> <value>`.
|
- Adjust the migration setting as needed using the following command: `husksync migrate set mpdb <setting> <value>`.
|
||||||
- Note that migration will be carried out *from* the database you specify with the settings in console *to* the database configured in `config.yml`.
|
- Note that migration will be carried out *from* the database you specify with the settings in console *to* the database configured in `config.yml`.
|
||||||
|
|
||||||
### 3. Start the migrator
|
### 3. Start the migrator
|
||||||
- Run `husksync migrate mpdb start` to begin the migration process. This may take some time, depending on the amount of data you're migrating.
|
- Run `husksync migrate start mpdb` to begin the migration process. This may take some time, depending on the amount of data you're migrating.
|
||||||
|
|
||||||
### 4. Uninstall MySQLPlayerDataBridge
|
### 4. Uninstall MySQLPlayerDataBridge
|
||||||
- HuskSync will display a message in console when data migration is complete.
|
- HuskSync will display a message in console when data migration is complete.
|
||||||
|
|||||||
@@ -18,20 +18,21 @@ dependencies {
|
|||||||
modImplementation include("net.kyori:adventure-platform-fabric:${adventure_platform_fabric_version}")
|
modImplementation include("net.kyori:adventure-platform-fabric:${adventure_platform_fabric_version}")
|
||||||
modImplementation include("me.lucko:fabric-permissions-api:${fabric_permissions_api_version}")
|
modImplementation include("me.lucko:fabric-permissions-api:${fabric_permissions_api_version}")
|
||||||
modImplementation include("eu.pb4:sgui:${sgui_version}")
|
modImplementation include("eu.pb4:sgui:${sgui_version}")
|
||||||
modImplementation include('net.william278.uniform:uniform-fabric:1.1.4+1.20.1')
|
modImplementation include('net.william278.uniform:uniform-fabric:1.2.1+1.20.1')
|
||||||
modCompileOnly "net.fabricmc.fabric-api:fabric-api:${fabric_api_version}"
|
modCompileOnly "net.fabricmc.fabric-api:fabric-api:${fabric_api_version}"
|
||||||
|
|
||||||
implementation include('org.apache.commons:commons-pool2:2.12.0')
|
implementation include('org.apache.commons:commons-pool2:2.12.0')
|
||||||
implementation include("redis.clients:jedis:$jedis_version")
|
implementation include("redis.clients:jedis:$jedis_version")
|
||||||
implementation include("com.mysql:mysql-connector-j:$mysql_driver_version")
|
implementation include("com.mysql:mysql-connector-j:$mysql_driver_version")
|
||||||
implementation include("org.mariadb.jdbc:mariadb-java-client:$mariadb_driver_version")
|
implementation include("org.mariadb.jdbc:mariadb-java-client:$mariadb_driver_version")
|
||||||
|
implementation include("org.postgresql:postgresql:$postgres_driver_version")
|
||||||
implementation include("org.xerial.snappy:snappy-java:$snappy_version")
|
implementation include("org.xerial.snappy:snappy-java:$snappy_version")
|
||||||
|
|
||||||
compileOnly 'org.jetbrains:annotations:24.1.0'
|
compileOnly 'org.jetbrains:annotations:24.1.0'
|
||||||
compileOnly 'net.william278:DesertWell:2.0.4'
|
compileOnly 'net.william278:DesertWell:2.0.4'
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.32'
|
compileOnly 'org.projectlombok:lombok:1.18.34'
|
||||||
|
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.32'
|
annotationProcessor 'org.projectlombok:lombok:1.18.34'
|
||||||
|
|
||||||
shadow project(path: ":common")
|
shadow project(path: ":common")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ org.gradle.jvmargs='-Dfile.encoding=UTF-8'
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
javaVersion=17
|
javaVersion=17
|
||||||
|
|
||||||
plugin_version=3.6.1
|
plugin_version=3.6.6
|
||||||
plugin_archive=husksync
|
plugin_archive=husksync
|
||||||
plugin_description=A modern, cross-server player data synchronization system
|
plugin_description=A modern, cross-server player data synchronization system
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
|
plugins {
|
||||||
|
id 'xyz.jpenilla.run-paper' version '2.3.0'
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':bukkit')
|
implementation project(':bukkit')
|
||||||
compileOnly project(':common')
|
compileOnly project(':common')
|
||||||
|
|
||||||
implementation 'net.william278.uniform:uniform-paper:1.1.4'
|
implementation 'net.william278.uniform:uniform-paper:1.2.1'
|
||||||
|
|
||||||
compileOnly 'io.papermc.paper:paper-api:1.19.4-R0.1-SNAPSHOT'
|
compileOnly 'io.papermc.paper:paper-api:1.19.4-R0.1-SNAPSHOT'
|
||||||
compileOnly 'org.jetbrains:annotations:24.1.0'
|
compileOnly 'org.jetbrains:annotations:24.1.0'
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.32'
|
compileOnly 'org.projectlombok:lombok:1.18.34'
|
||||||
|
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.32'
|
annotationProcessor 'org.projectlombok:lombok:1.18.34'
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
@@ -42,4 +46,14 @@ shadowJar {
|
|||||||
relocate 'de.tr7zw.changeme.nbtapi', 'net.william278.husksync.libraries.nbtapi'
|
relocate 'de.tr7zw.changeme.nbtapi', 'net.william278.husksync.libraries.nbtapi'
|
||||||
|
|
||||||
minimize()
|
minimize()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
runServer {
|
||||||
|
minecraftVersion('1.21')
|
||||||
|
|
||||||
|
downloadPlugins {
|
||||||
|
url('https://download.luckperms.net/1549/bukkit/loader/LuckPerms-Bukkit-5.4.134.jar')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
certifi==2023.7.22
|
certifi==2024.7.4
|
||||||
charset-normalizer==3.2.0
|
charset-normalizer==3.2.0
|
||||||
colorama==0.4.6
|
colorama==0.4.6
|
||||||
idna==3.7
|
idna==3.7
|
||||||
|
|||||||
Reference in New Issue
Block a user