Skip to content

Commit b2c842b

Browse files
AuroraLS3AnttiMK
andauthored
Sponge API 13 (#4020)
* Update to Sponge API 13 * Fix sponge including minecraft in the Plan jar Co-authored-by: Antti Koponen <koponen942@outlook.com> * Fix plugin startup issue due to net.kyori classes in META-INF * Replace Gamemode mixin with the appropriate listener --------- Co-authored-by: Antti Koponen <koponen942@outlook.com>
1 parent 4cb090f commit b2c842b

13 files changed

Lines changed: 92 additions & 150 deletions

File tree

Plan/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ subprojects {
6161
bukkitVersion = "1.13.2-R0.1-SNAPSHOT"
6262
spigotVersion = "1.13.2-R0.1-SNAPSHOT"
6363
paperVersion = "1.13.2-R0.1-SNAPSHOT"
64-
spongeVersion = "8.1.0"
64+
spongeVersion = "13.0.0"
6565
nukkitVersion = "1.0-SNAPSHOT"
6666
bungeeVersion = "1.16-R0.4"
6767
velocityVersion = "3.0.0-SNAPSHOT"

Plan/common/src/main/resources/assets/plan/geocodes.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,5 +251,6 @@
251251
"são tomé and príncipe": "STP",
252252
"turks and caicos islands": "TCA",
253253
"norfolk island": "NFK",
254-
"pitcairn islands": "PCN"
254+
"pitcairn islands": "PCN",
255+
"antarctica": "ATA"
255256
}

Plan/plugin/build.gradle

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,6 @@ dependencies {
2121
implementation project(path: ":extensions:adventure", configuration: "shadow")
2222
}
2323

24-
jar {
25-
// Add the sponge mixin into the manifest
26-
manifest.attributes([
27-
"MixinConfigs": "plan-sponge.mixins.json"
28-
])
29-
}
30-
3124
tasks.named("shadowJar", ShadowJar) {
3225
// Exclude these files
3326
exclude "**/*.svg"
@@ -39,6 +32,7 @@ tasks.named("shadowJar", ShadowJar) {
3932
exclude "**/module-info.class"
4033
exclude "module-info.class"
4134
exclude "META-INF/versions/" // Causes Sponge to crash
35+
exclude "META-INF/services/net.kyori.**" // Causes ResolutionException on Sponge due to export to net.kyori module
4236
exclude "mozilla/**/*"
4337

4438
// Exclude extra dependencies

Plan/sponge/build.gradle

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ plugins {
66
id "org.spongepowered.gradle.vanilla" version "0.2.1-SNAPSHOT"
77
}
88

9+
// Shadow plugin applied even though shadow is not used in the module,
10+
// so that VanillaGradle doesn't include Minecraft in runtimeClassPath
11+
apply plugin: "com.gradleup.shadow"
12+
913
dependencies {
1014
implementation project(":common")
1115

@@ -68,10 +72,10 @@ sponge {
6872
}
6973

7074
minecraft {
71-
version("1.16.5")
75+
version("1.21.3")
7276
platform(MinecraftPlatform.SERVER)
7377
}
7478

75-
compileJava {
76-
options.release = 11
79+
tasks.withType(JavaCompile).configureEach {
80+
options.release.set(21)
7781
}

Plan/sponge/src/main/java/com/djrapitops/plan/gathering/domain/SpongePlayerData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public Optional<String> getJoinAddress() {
7070

7171
@Override
7272
public Optional<String> getCurrentWorld() {
73-
return Sponge.game().server().worldManager().worldDirectory(player.world().key())
73+
return Optional.ofNullable(Sponge.game().server().worldManager().worldDirectory(player.world().key()))
7474
.map(path -> path.getFileName().toString());
7575
}
7676

Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/PlayerOnlineListener.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
import com.djrapitops.plan.storage.database.transactions.events.StoreAllowlistBounceTransaction;
3131
import com.djrapitops.plan.utilities.logging.ErrorContext;
3232
import com.djrapitops.plan.utilities.logging.ErrorLogger;
33+
import org.jetbrains.annotations.NotNull;
3334
import org.spongepowered.api.Game;
3435
import org.spongepowered.api.Sponge;
35-
import org.spongepowered.api.entity.living.player.Player;
3636
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
3737
import org.spongepowered.api.event.Listener;
3838
import org.spongepowered.api.event.Order;
@@ -151,11 +151,12 @@ private void actOnJoinEvent(ServerSideConnectionEvent.Join event) {
151151

152152
@Listener(order = Order.DEFAULT)
153153
public void beforeQuit(ServerSideConnectionEvent.Disconnect event) {
154-
leaveEventConsumer.beforeLeave(PlayerLeave.builder()
155-
.server(serverInfo.getServer())
156-
.player(new SpongePlayerData(event.player()))
157-
.time(System.currentTimeMillis())
158-
.build());
154+
getPlayer(event)
155+
.ifPresent(player -> leaveEventConsumer.beforeLeave(PlayerLeave.builder()
156+
.server(serverInfo.getServer())
157+
.player(player)
158+
.time(System.currentTimeMillis())
159+
.build()));
159160
}
160161

161162
@Listener(order = Order.POST)
@@ -169,14 +170,22 @@ public void onQuit(ServerSideConnectionEvent.Disconnect event) {
169170

170171
private void actOnQuitEvent(ServerSideConnectionEvent.Disconnect event) {
171172
long time = System.currentTimeMillis();
172-
Player player = event.player();
173-
UUID playerUUID = player.uniqueId();
173+
getPlayer(event)
174+
.ifPresent(player -> {
175+
UUID playerUUID = player.getUUID();
176+
SpongeAFKListener.afkTracker.loggedOut(playerUUID, time);
177+
leaveEventConsumer.onLeaveGameServer(PlayerLeave.builder()
178+
.server(serverInfo.getServer())
179+
.player(player)
180+
.time(System.currentTimeMillis())
181+
.build());
182+
});
183+
}
174184

175-
SpongeAFKListener.afkTracker.loggedOut(playerUUID, time);
176-
leaveEventConsumer.onLeaveGameServer(PlayerLeave.builder()
177-
.server(serverInfo.getServer())
178-
.player(new SpongePlayerData(event.player()))
179-
.time(System.currentTimeMillis())
180-
.build());
185+
private @NotNull Optional<SpongePlayerData> getPlayer(ServerSideConnectionEvent.Disconnect event) {
186+
return event.profile()
187+
.map(GameProfile::uuid)
188+
.flatMap(playerUUID -> game.server().player(playerUUID))
189+
.map(SpongePlayerData::new);
181190
}
182191
}

Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeAFKListener.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.spongepowered.api.event.filter.cause.First;
3232
import org.spongepowered.api.event.message.PlayerChatEvent;
3333
import org.spongepowered.api.event.network.ServerSideConnectionEvent;
34+
import org.spongepowered.api.profile.GameProfile;
3435

3536
import javax.inject.Inject;
3637
import java.util.Map;
@@ -122,6 +123,6 @@ public void onSettingsChange(PlayerChangeClientSettingsEvent event) {
122123

123124
@Listener(order = Order.POST)
124125
public void onLeave(ServerSideConnectionEvent.Disconnect event) {
125-
ignorePermissionInfo.remove(event.player().uniqueId());
126+
event.profile().map(GameProfile::uuid).ifPresent(ignorePermissionInfo::remove);
126127
}
127128
}

Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeDeathListener.java

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
import org.spongepowered.api.entity.living.player.Player;
3939
import org.spongepowered.api.entity.projectile.Projectile;
4040
import org.spongepowered.api.event.Listener;
41-
import org.spongepowered.api.event.cause.entity.damage.source.EntityDamageSource;
41+
import org.spongepowered.api.event.cause.entity.damage.source.DamageSource;
4242
import org.spongepowered.api.event.entity.DestructEntityEvent;
4343
import org.spongepowered.api.item.ItemType;
4444
import org.spongepowered.api.item.ItemTypes;
@@ -83,7 +83,7 @@ public void onEntityDeath(DestructEntityEvent.Death event) {
8383
}
8484

8585
try {
86-
List<EntityDamageSource> causes = event.cause().allOf(EntityDamageSource.class);
86+
List<DamageSource> causes = event.cause().allOf(DamageSource.class);
8787
Optional<Player> foundKiller = findKiller(causes, 0);
8888
if (foundKiller.isEmpty()) {
8989
return;
@@ -107,28 +107,38 @@ private PlayerKill.Victim getVictim(Player victim) {
107107
return new PlayerKill.Victim(victim.uniqueId(), victim.name());
108108
}
109109

110-
public Optional<Player> findKiller(List<EntityDamageSource> causes, int depth) {
110+
public Optional<Player> findKiller(List<DamageSource> causes, int depth) {
111111
if (causes.isEmpty() || causes.size() < depth) {
112112
return Optional.empty();
113113
}
114114

115-
EntityDamageSource damageSource = causes.get(depth);
116-
Entity killerEntity = damageSource.source();
115+
DamageSource damageSource = causes.get(depth);
116+
Optional<Entity> source = damageSource.source();
117+
if (source.isEmpty()) source = damageSource.indirectSource();
118+
if (source.isEmpty()) return Optional.empty();
117119

118-
if (killerEntity instanceof Player) return Optional.of((Player) killerEntity);
119-
if (killerEntity instanceof Wolf) return getOwner((Wolf) killerEntity);
120-
if (killerEntity instanceof Projectile) return getShooter((Projectile) killerEntity);
121-
if (killerEntity instanceof EndCrystal) return findKiller(causes, depth + 1);
122-
return Optional.empty();
120+
Entity killerEntity = source.get();
121+
122+
return switch (killerEntity) {
123+
case Player player -> Optional.of(player);
124+
case Wolf wolf -> getOwner(wolf);
125+
case Projectile projectile -> getShooter(projectile);
126+
case EndCrystal endCrystal -> findKiller(causes, depth + 1);
127+
default -> Optional.empty();
128+
};
123129
}
124130

125131
public String findWeapon(DestructEntityEvent.Death death) {
126-
Optional<EntityDamageSource> damagedBy = death.cause().first(EntityDamageSource.class);
132+
Optional<DamageSource> damagedBy = death.cause().first(DamageSource.class);
127133
if (damagedBy.isPresent()) {
128-
EntityDamageSource damageSource = damagedBy.get();
129-
Entity killerEntity = damageSource.source();
134+
DamageSource damageSource = damagedBy.get();
135+
Optional<Entity> source = damageSource.source();
136+
if (source.isEmpty()) source = damageSource.indirectSource();
137+
if (source.isEmpty()) return "Unknown";
138+
139+
Entity killerEntity = source.get();
130140

131-
if (killerEntity instanceof Player) return getItemInHand((Player) killerEntity);
141+
if (killerEntity instanceof Player player) return getItemInHand(player);
132142
if (killerEntity instanceof Wolf) return "Wolf";
133143

134144
Optional<ResourceKey> entityType = killerEntity.type().findKey(RegistryTypes.ENTITY_TYPE);
@@ -148,14 +158,14 @@ private String getItemInHand(Player killer) {
148158

149159
private Optional<Player> getShooter(Projectile projectile) {
150160
ProjectileSource source = projectile.shooter().map(Value::get).orElse(null);
151-
if (source instanceof Player) {
152-
return Optional.of((Player) source);
161+
if (source instanceof Player player) {
162+
return Optional.of(player);
153163
}
154164

155165
return Optional.empty();
156166
}
157167

158168
private Optional<Player> getOwner(Wolf wolf) {
159-
return wolf.tamer().flatMap(uuid -> Sponge.game().server().player(uuid.get()));
169+
return wolf.owner().flatMap(uuid -> Sponge.game().server().player(uuid.get()));
160170
}
161171
}

Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeGMChangeListener.java

Lines changed: 17 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,21 @@
2222
import com.djrapitops.plan.settings.config.WorldAliasSettings;
2323
import com.djrapitops.plan.storage.database.DBSystem;
2424
import com.djrapitops.plan.storage.database.transactions.events.StoreWorldNameTransaction;
25-
import com.djrapitops.plan.utilities.logging.ErrorContext;
2625
import com.djrapitops.plan.utilities.logging.ErrorLogger;
27-
import net.minecraft.world.entity.player.Player;
28-
import net.minecraft.world.level.GameType;
29-
import org.spongepowered.api.ResourceKey;
3026
import org.spongepowered.api.Sponge;
27+
import org.spongepowered.api.data.DataTransactionResult;
28+
import org.spongepowered.api.data.Keys;
29+
import org.spongepowered.api.data.value.Value;
3130
import org.spongepowered.api.entity.living.player.gamemode.GameMode;
32-
import org.spongepowered.api.entity.living.player.gamemode.GameModes;
3331
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
32+
import org.spongepowered.api.event.Listener;
33+
import org.spongepowered.api.event.Order;
34+
import org.spongepowered.api.event.data.ChangeDataHolderEvent;
3435
import org.spongepowered.api.registry.RegistryTypes;
3536

3637
import javax.inject.Inject;
37-
import java.util.ArrayList;
38-
import java.util.List;
3938
import java.util.Optional;
4039
import java.util.UUID;
41-
import java.util.function.Consumer;
4240

4341
/**
4442
* Listener for GameMode change on Sponge.
@@ -47,8 +45,6 @@
4745
*/
4846
public class SpongeGMChangeListener {
4947

50-
public static final List<Consumer<Event>> EVENT_CONSUMERS = new ArrayList<>(); // Available to the mixin
51-
5248
private final WorldAliasSettings worldAliasSettings;
5349
private final ServerInfo serverInfo;
5450
private final DBSystem dbSystem;
@@ -65,65 +61,31 @@ public SpongeGMChangeListener(
6561
this.serverInfo = serverInfo;
6662
this.dbSystem = dbSystem;
6763
this.errorLogger = errorLogger;
68-
EVENT_CONSUMERS.add(this::onMixin);
6964
}
7065

71-
public static class Event {
72-
private final Player player;
73-
private final GameType gameType;
74-
75-
public Event(Player player, GameType gameType) {
76-
this.player = player;
77-
this.gameType = gameType;
66+
@Listener(order = Order.POST)
67+
public void onGMChange(ChangeDataHolderEvent.ValueChange event) {
68+
ServerPlayer player = event.targetHolder() instanceof ServerPlayer serverPlayer ? serverPlayer : null;
69+
if (player == null) {
70+
return;
7871
}
79-
}
8072

81-
private void onMixin(Event event) {
82-
ServerPlayer serverPlayer = Sponge.game().server()
83-
.player(event.player.getUUID())
84-
.orElse(null);
85-
if (serverPlayer == null) {
86-
// uh oh
87-
errorLogger.error(
88-
new RuntimeException("GameMode changed for player but no ServerPlayer was found"),
89-
ErrorContext.builder()
90-
.related(event.player, event.player.getGameProfile().getName())
91-
.whatToDo("Report this, the gamemode change mixin might be broken")
92-
.build()
93-
);
73+
DataTransactionResult result = event.endResult();
74+
Optional<Value.Immutable<GameMode>> gameModeValue = result.successfulValue(Keys.GAME_MODE);
75+
if (gameModeValue.isEmpty()) {
9476
return;
9577
}
9678

97-
GameMode gameMode = GameModes.registry().value(ResourceKey.sponge(event.gameType.getName()));
98-
actOnGMChangeEvent(serverPlayer, gameMode);
79+
GameMode newMode = gameModeValue.get().get();
80+
actOnGMChangeEvent(player, newMode);
9981
}
10082

101-
// This listener can replace the mixin if this pr is merged:
102-
// https://github.com/SpongePowered/Sponge/pull/3563
103-
104-
// @Listener(order = Order.POST)
105-
// public void onGMChange(ChangeDataHolderEvent.ValueChange event) {
106-
// ServerPlayer player = event.targetHolder() instanceof ServerPlayer ? (ServerPlayer) event.targetHolder() : null;
107-
// if (player == null) {
108-
// return;
109-
// }
110-
//
111-
// DataTransactionResult result = event.endResult();
112-
// Optional<Value.Immutable<GameMode>> gameModeValue = result.successfulValue(Keys.GAME_MODE);
113-
// if (gameModeValue.isEmpty()) {
114-
// return;
115-
// }
116-
//
117-
// GameMode newMode = gameModeValue.get().get();
118-
// actOnGMChangeEvent(player, newMode);
119-
// }
120-
12183
private void actOnGMChangeEvent(ServerPlayer player, GameMode gameMode) {
12284
UUID uuid = player.uniqueId();
12385
long time = System.currentTimeMillis();
12486

12587
String gameModeText = gameMode.key(RegistryTypes.GAME_MODE).value().toUpperCase();
126-
String worldName = Sponge.game().server().worldManager().worldDirectory(player.world().key())
88+
String worldName = Optional.ofNullable(Sponge.game().server().worldManager().worldDirectory(player.world().key()))
12789
.map(path -> path.getFileName().toString()).orElse("Unknown");
12890

12991
dbSystem.getDatabase().executeTransaction(new StoreWorldNameTransaction(serverInfo.getServerUUID(), worldName));

Plan/sponge/src/main/java/com/djrapitops/plan/gathering/listeners/sponge/SpongeWorldChangeListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ private void actOnEvent(ChangeEntityWorldEvent event, ServerPlayer player) {
7676

7777
UUID uuid = player.uniqueId();
7878

79-
String worldName = Sponge.game().server().worldManager().worldDirectory(event.destinationWorld().key())
79+
String worldName = Optional.ofNullable(Sponge.game().server().worldManager().worldDirectory(event.destinationWorld().key()))
8080
.map(path -> path.getFileName().toString()).orElse("Unknown");
8181
String gameMode = getGameMode(player);
8282

0 commit comments

Comments
 (0)