From 5ba7cc29724428e2c5f5d3b07e7b5f4ceeff592d Mon Sep 17 00:00:00 2001 From: EoD <293499+EoD@users.noreply.github.com> Date: Sat, 17 May 2025 18:54:12 +0000 Subject: [PATCH 1/5] add action to automatically backport PRs --- .github/workflows/backport-prs.yml | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/backport-prs.yml diff --git a/.github/workflows/backport-prs.yml b/.github/workflows/backport-prs.yml new file mode 100644 index 0000000..3c7b90c --- /dev/null +++ b/.github/workflows/backport-prs.yml @@ -0,0 +1,38 @@ +name: Backport merged pull request +on: + pull_request_target: + types: [closed] + issue_comment: + types: [created] +permissions: + contents: write # so it can comment + pull-requests: write # so it can create pull requests +jobs: + backport: + name: Backport pull request + runs-on: ubuntu-latest + + # Only run when pull request is merged + # or when a comment starting with `/backport` is created by someone other than the + # https://github.com/backport-action bot user (user id: 97796249). Note that if you use your + # own PAT as `github_token`, that you should replace this id with yours. + if: > + ( + github.event_name == 'pull_request_target' && + github.event.pull_request.merged + ) || ( + github.event_name == 'issue_comment' && + github.event.issue.pull_request && + github.event.comment.user.id != 97796249 && + startsWith(github.event.comment.body, '/backport') + ) + steps: + - uses: actions/checkout@v4 + - name: Create backport pull requests + uses: korthout/backport-action@v3 + with: + pull_description: | + Backport of #${pull_number} to `${target_branch}`. + + ### Description + ${pull_description} From 319fe678f3819928f35d5d5ee7d052b50d7986bf Mon Sep 17 00:00:00 2001 From: EoD <293499+EoD@users.noreply.github.com> Date: Sat, 17 May 2025 19:08:48 +0000 Subject: [PATCH 2/5] remove unused override in the language files --- src/main/resources/assets/playersync/lang/en_us.json | 1 - src/main/resources/assets/playersync/lang/zh_cn.json | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/resources/assets/playersync/lang/en_us.json b/src/main/resources/assets/playersync/lang/en_us.json index 8e04540..4b03f8e 100644 --- a/src/main/resources/assets/playersync/lang/en_us.json +++ b/src/main/resources/assets/playersync/lang/en_us.json @@ -1,6 +1,5 @@ { "playersync.item_placeholder_description": "Item is unknown on this server. This can either\nbe a modded item, an added, or a removed vanilla\nitem.\nThis voucher will automatically be replaced with\nthe corresponding item when joining a server\nwhere the item is known.", - "playersync.placeholder_title_override": "Item Voucher", "playersync.item_placeholder_title": "Item Voucher", "playersync.already_online": "You can't join more than one synchronization server at the same time." } diff --git a/src/main/resources/assets/playersync/lang/zh_cn.json b/src/main/resources/assets/playersync/lang/zh_cn.json index 92bbe6a..f206090 100644 --- a/src/main/resources/assets/playersync/lang/zh_cn.json +++ b/src/main/resources/assets/playersync/lang/zh_cn.json @@ -1,6 +1,5 @@ { "playersync.item_placeholder_description": "物品在此服务器未知。这可能是一个模组物品,或是不同版本的原版物品。\n这张券将会在加入可识别此物品的服务器后自动替换为对应物品。", - "playersync.placeholder_title_override": "物品券", "playersync.item_placeholder_title": "物品券", "playersync.already_online": "你不能同时加入多个同步的服务器。" -} \ No newline at end of file +} From d83bad5a3321adb4ff44e7717f72ad0167eabdd4 Mon Sep 17 00:00:00 2001 From: EoD <293499+EoD@users.noreply.github.com> Date: Sat, 17 May 2025 18:45:03 +0000 Subject: [PATCH 3/5] fix XP being lost or duplicated The current calculation did not work for larger amounts of levels and either removed or added levels unintentionally. --- .../fubuki/playersync/sync/VanillaSync.java | 56 +++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java b/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java index 86b7552..b33ccf0 100644 --- a/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java +++ b/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java @@ -184,10 +184,8 @@ public class VanillaSync { // Restore basic attributes serverPlayer.setHealth(rs2.getInt("health")); serverPlayer.getFoodData().setFoodLevel(rs2.getInt("food_level")); - serverPlayer.totalExperience = 0; - serverPlayer.experienceLevel = 0; - serverPlayer.experienceProgress = 0; - serverPlayer.giveExperiencePoints(rs2.getInt("xp")); + + setXpForPlayer(serverPlayer, rs2.getInt("xp")); serverPlayer.setScore(rs2.getInt("score")); // Restore left-hand item @@ -462,7 +460,7 @@ public class VanillaSync { PlayerSync.LOGGER.info("Storing data for player " + player_uuid + " (init=" + init + ")"); // Basic Attributes - int XP = player.totalExperience; + int XP = getTotalExperience(player); int score = player.getScore(); int food_level = player.getFoodData().getFoodLevel(); int health = (int) player.getHealth(); @@ -625,4 +623,52 @@ public class VanillaSync { } } } + + private static void setXpForPlayer(ServerPlayer serverPlayer, int databaseXp) { + // Don't use giveExperience() as it has several side-effects: + // triggers an event, sends network packets, increases the score, ... + serverPlayer.totalExperience = databaseXp; + serverPlayer.experienceLevel = 0; + serverPlayer.experienceProgress = 0; + + int xpForLevel; + + while (databaseXp >= (xpForLevel = serverPlayer.getXpNeededForNextLevel())) { + databaseXp -= xpForLevel; + serverPlayer.experienceLevel++; + } + + serverPlayer.experienceProgress = serverPlayer.experienceLevel > 0 + ? (float) databaseXp / serverPlayer.getXpNeededForNextLevel() + : 0f; + + PlayerSync.LOGGER.debug("Giving player " + + serverPlayer.experienceLevel + " levels and " + + serverPlayer.experienceProgress * 100 + "% experience progress, calculated from " + + serverPlayer.totalExperience + " XP."); + } + + private static int getTotalExperience(final Player player) { + int level = player.experienceLevel; + int totalXp = 0; + + // Calculate total XP for completed levels + if (level > 30) { + totalXp = (int) (4.5 * Math.pow(level, 2) - 162.5 * level + 2220); + } else if (level > 15) { + totalXp = (int) (2.5 * Math.pow(level, 2) - 40.5 * level + 360); + } else { + totalXp = level * level + 6 * level; + } + + // Add partial level progress + totalXp += Math.round(player.getXpNeededForNextLevel() * player.experienceProgress); + + PlayerSync.LOGGER.debug("Experience calcuation for " + + player.experienceLevel + " levels and " + + player.experienceProgress * 100 + "% experience progress yields " + + totalXp + " XP."); + + return totalXp; + } } From e0f0b518519f9514d0c34e3d09eef69531bf2dc7 Mon Sep 17 00:00:00 2001 From: EoD <293499+EoD@users.noreply.github.com> Date: Sun, 18 May 2025 17:18:23 +0000 Subject: [PATCH 4/5] use PAT in backport action --- .github/workflows/backport-prs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/backport-prs.yml b/.github/workflows/backport-prs.yml index 3c7b90c..0e9d05a 100644 --- a/.github/workflows/backport-prs.yml +++ b/.github/workflows/backport-prs.yml @@ -31,6 +31,7 @@ jobs: - name: Create backport pull requests uses: korthout/backport-action@v3 with: + github_token: ${{ secrets.TOKEN }} pull_description: | Backport of #${pull_number} to `${target_branch}`. From e2b90ccf988cf0d450685f850c1cfd527f8e836c Mon Sep 17 00:00:00 2001 From: EoD <293499+EoD@users.noreply.github.com> Date: Sun, 18 May 2025 22:02:56 +0000 Subject: [PATCH 5/5] bump mod version to 2.1.1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d2941d6..e3c4215 100644 --- a/gradle.properties +++ b/gradle.properties @@ -34,7 +34,7 @@ mod_name=PlayerSync # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=GPL-3.0 license # The mod version. See https://semver.org/ -mod_version=2.1.0 +mod_version=2.1.1 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html