Skip to content

Commit f7d5ef0

Browse files
committed
feat: add support for 1.15-1.15.2
1 parent 142b289 commit f7d5ef0

File tree

13 files changed

+700
-0
lines changed

13 files changed

+700
-0
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
fail-fast: true
2727
matrix:
2828
mc_version:
29+
- 1.15
2930
- 1.16.2
3031
- 1.17
3132
- 1.18.2

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ specific minecraft versions.
1818

1919
| Minecraft Version | Subproject | Supported |
2020
|------------------------|------------|--------------------|
21+
| 1.15, 1.15.1, 1.15.2 | v1_15 | :white_check_mark: |
2122
| 1.16.2 - 1.16.5 | v1_16_2 | :white_check_mark: |
2223
| 1.17, 1.17.1 | v1_17 | :white_check_mark: |
2324
| 1.18.2 | v1_18_2 | :white_check_mark: |

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pluginManagement {
2929
rootProject.name = "cloudnet-bridge-fabric"
3030

3131
include(":common")
32+
include(":v1_15")
3233
include(":v1_16_2")
3334
include(":v1_17")
3435
include(":v1_18_2")

v1_15/build.gradle.kts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2025-present CloudNetService team & contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import org.apache.tools.ant.filters.ReplaceTokens
18+
19+
plugins {
20+
alias(libs.plugins.fabricLoom)
21+
}
22+
23+
val minecraftVersion = "1.15"
24+
val supportedVersionRange = "~1.15"
25+
26+
dependencies {
27+
shaded(projects.common)
28+
modImplementation(libs.fabricLoader)
29+
minecraft("com.mojang:minecraft:$minecraftVersion")
30+
mappings(loom.officialMojangMappings())
31+
}
32+
33+
loom {
34+
accessWidenerPath = project.file("src/main/resources/cloudnet_version_bridge.accesswidener")
35+
}
36+
37+
tasks.remapJar {
38+
dependsOn(tasks.shadowJar)
39+
inputFile = tasks.shadowJar.flatMap { it.archiveFile }
40+
archiveFileName = "bridge_${minecraftVersion.replace(".", "")}.jar"
41+
}
42+
43+
tasks.processResources {
44+
val tokens = mapOf(
45+
"mc_version" to minecraftVersion,
46+
"mc_version_range" to supportedVersionRange,
47+
"mc_version_dashed" to minecraftVersion.replace('.', '_'),
48+
)
49+
inputs.properties(tokens)
50+
filesMatching("*.json") {
51+
filter(ReplaceTokens::class, mapOf("tokens" to tokens))
52+
}
53+
54+
from(rootProject.layout.projectDirectory.dir(".mod_resources")) {
55+
into("")
56+
include("*.json")
57+
}
58+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright 2025-present CloudNetService team & contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package eu.cloudnetservice.modules.bridge.fabric.v1_15;
18+
19+
import eu.cloudnetservice.driver.service.ServiceInfoSnapshot;
20+
import eu.cloudnetservice.modules.bridge.fabric.BaseFabricBridgeManagement;
21+
import eu.cloudnetservice.modules.bridge.fabric.BridgeAccessorSpec;
22+
import eu.cloudnetservice.modules.bridge.impl.util.BridgeHostAndPortUtil;
23+
import eu.cloudnetservice.modules.bridge.player.NetworkPlayerServerInfo;
24+
import eu.cloudnetservice.modules.bridge.player.ServicePlayer;
25+
import eu.cloudnetservice.modules.bridge.player.executor.PlayerExecutor;
26+
import java.util.Optional;
27+
import java.util.UUID;
28+
import java.util.function.BiFunction;
29+
import net.minecraft.server.level.ServerPlayer;
30+
import org.jetbrains.annotations.NotNull;
31+
import org.jetbrains.annotations.Nullable;
32+
33+
public final class FabricBridgeManagementv115 extends BaseFabricBridgeManagement<ServerPlayer> {
34+
35+
/**
36+
* Constructs a new instance of the bridge management.
37+
*
38+
* @param bridgeAccessorSpec the accessor specification for the current server version.
39+
* @throws NullPointerException if the given accessor spec is null.
40+
*/
41+
public FabricBridgeManagementv115(@NotNull BridgeAccessorSpec<ServerPlayer> bridgeAccessorSpec) {
42+
super(bridgeAccessorSpec);
43+
}
44+
45+
/**
46+
* {@inheritDoc}
47+
*/
48+
@Override
49+
public @NotNull ServicePlayer wrapPlayer(@NotNull ServerPlayer player) {
50+
return new ServicePlayer(player.getUUID(), player.getGameProfile().getName());
51+
}
52+
53+
/**
54+
* {@inheritDoc}
55+
*/
56+
@Override
57+
public @NotNull NetworkPlayerServerInfo createPlayerInformation(@NotNull ServerPlayer player) {
58+
return new NetworkPlayerServerInfo(
59+
player.getUUID(),
60+
player.getGameProfile().getName(),
61+
null,
62+
BridgeHostAndPortUtil.fromSocketAddress(player.connection.getConnection().getRemoteAddress()),
63+
this.ownNetworkServiceInfo);
64+
}
65+
66+
/**
67+
* {@inheritDoc}
68+
*/
69+
@Override
70+
public @NotNull BiFunction<ServerPlayer, String, Boolean> permissionFunction() {
71+
return (player, _) -> player.hasPermissions(4);
72+
}
73+
74+
/**
75+
* {@inheritDoc}
76+
*/
77+
@Override
78+
public @NotNull Optional<ServiceInfoSnapshot> fallback(@NotNull ServerPlayer player, @Nullable String currServer) {
79+
return this.fallback(player.getUUID(), currServer, null, _ -> player.hasPermissions(4));
80+
}
81+
82+
/**
83+
* {@inheritDoc}
84+
*/
85+
@Override
86+
public void handleFallbackConnectionSuccess(@NotNull ServerPlayer player) {
87+
this.handleFallbackConnectionSuccess(player.getUUID());
88+
}
89+
90+
/**
91+
* {@inheritDoc}
92+
*/
93+
@Override
94+
public void removeFallbackProfile(@NotNull ServerPlayer player) {
95+
this.removeFallbackProfile(player.getUUID());
96+
}
97+
98+
/**
99+
* {@inheritDoc}
100+
*/
101+
@Override
102+
public @NotNull PlayerExecutor directPlayerExecutor(@NotNull UUID uniqueId) {
103+
throw new UnsupportedOperationException("not implemented on fabric");
104+
}
105+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2025-present CloudNetService team & contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package eu.cloudnetservice.modules.bridge.fabric.v1_15.forward;
18+
19+
import eu.cloudnetservice.modules.bridge.fabric.BaseMixinConfigPlugin;
20+
import org.jetbrains.annotations.NotNull;
21+
22+
/**
23+
* Mixin plugin to conditionally apply forwarding mixins only if they are actually needed.
24+
*
25+
* @since 2025.08.26
26+
*/
27+
public final class ForwardMixinPlugin extends BaseMixinConfigPlugin {
28+
29+
/**
30+
* If cloudnet ip forwarding support is disabled.
31+
*/
32+
private static final boolean DISABLE_CLOUDNET_FORWARDING = Boolean.getBoolean("cloudnet.ipforward.disabled");
33+
34+
/**
35+
* Conditionally applies the player forwarding mixins if they are enabled.
36+
*
37+
* @param targetClassName fully qualified class name of the target class
38+
* @param mixinClassName fully qualified class name of the mixin
39+
* @return true if the given mixin class should be applied, false otherwise.
40+
*/
41+
@Override
42+
public boolean shouldApplyMixin(@NotNull String targetClassName, @NotNull String mixinClassName) {
43+
var isForwardMixin = mixinClassName.contains(".forward.");
44+
return !isForwardMixin || !DISABLE_CLOUDNET_FORWARDING;
45+
}
46+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2025-present CloudNetService team & contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package eu.cloudnetservice.modules.bridge.fabric.v1_15.forward;
18+
19+
import com.mojang.authlib.GameProfile;
20+
import com.mojang.authlib.properties.Property;
21+
import io.netty.util.AttributeKey;
22+
import java.util.ArrayList;
23+
import java.util.List;
24+
import java.util.UUID;
25+
import org.jetbrains.annotations.NotNull;
26+
27+
/**
28+
* Accumulator for forwarded player data.
29+
*
30+
* @since 2025.08.26
31+
*/
32+
public final class ForwardingDataAccumulator {
33+
34+
/**
35+
* Key to get the forward data accumulator from a netty channel.
36+
*/
37+
public static final AttributeKey<ForwardingDataAccumulator> ACCUMULATOR_KEY =
38+
AttributeKey.newInstance("cloudnet_bridge$forward_data_accumulator");
39+
40+
/**
41+
* List of forwarded properties. Should only be appended to.
42+
*/
43+
public final List<Property> properties = new ArrayList<>();
44+
45+
/**
46+
* The unique id of the forwarded player.
47+
*/
48+
public UUID uniqueId;
49+
50+
/**
51+
* Converts the accumulated data into a game profile.
52+
*
53+
* @param name the name of the player.
54+
* @return the constructed game profile from the accumulated data.
55+
* @throws NullPointerException if the given name is null or this accumulator wasn't filled properly.
56+
*/
57+
public @NotNull GameProfile toGameProfile(@NotNull String name) {
58+
var profile = new GameProfile(this.uniqueId, name);
59+
for (var property : this.properties) {
60+
profile.getProperties().put(property.getName(), property);
61+
}
62+
63+
return profile;
64+
}
65+
}

0 commit comments

Comments
 (0)