Skip to content

Commit

Permalink
Delete signature & Automatic detect the packet ID
Browse files Browse the repository at this point in the history
  • Loading branch information
heartalborada-del committed Jan 24, 2025
1 parent 7dd7a58 commit e315cb5
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import moe.caa.multilogin.api.internal.main.MultiCoreAPI;
import org.jetbrains.annotations.ApiStatus;

import java.util.LinkedHashMap;
import java.util.Map;

/**
* 子模块注入接口
*/
Expand All @@ -13,4 +16,5 @@ public interface Injector {
* 开始注入
*/
void inject(MultiCoreAPI api) throws Throwable;
void registerChatSession(Map<Integer,Integer> packetMapping);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package moe.caa.multilogin.api.internal.main;

import moe.caa.multilogin.api.MapperConfigAPI;
import moe.caa.multilogin.api.internal.auth.AuthAPI;
import moe.caa.multilogin.api.internal.command.CommandAPI;
import moe.caa.multilogin.api.internal.handle.HandlerAPI;
Expand Down Expand Up @@ -46,6 +47,11 @@ public interface MultiCoreAPI {
*/
HandlerAPI getPlayerHandler();

/**
* 获得版本映射
*/
MapperConfigAPI getMapperConfig();

/**
* 获得插件对象
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,91 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import moe.caa.multilogin.api.MapperConfigAPI;
import moe.caa.multilogin.core.main.MultiCore;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;

import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* ChatSessionBlocker 数据包映射配置
*/
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
@ToString
public class MapperConfig {
private final LinkedHashMap<String,Integer> packetMapping;
public static MapperConfig read(CommentedConfigurationNode rootNode) throws SerializationException, ConfException {
LinkedHashMap<String,Integer> mapper = new LinkedHashMap<>() {{
put("MINECRAFT_1_19_3", 0x20);
put("MINECRAFT_1_19_4", 0x06);
put("MINECRAFT_1_20_5", 0x07);
put("MINECRAFT_1_21_2", 0x08);
}};
ConfigurationNode mapperNode = rootNode.node("mapper");
for (Map.Entry<Object, ? extends ConfigurationNode> entry : mapperNode.childrenMap().entrySet()) {
String key = entry.getKey().toString();
String hexValue = entry.getValue().getString();
int intValue = Integer.decode(hexValue);
mapper.put(key, intValue);
public class MapperConfig implements MapperConfigAPI {
private final LinkedHashMap<Integer,Integer> packetMapping = new LinkedHashMap<>() {
@Override
public Integer put(Integer key, Integer value) {
if(key<761) return value;
if(this.containsValue(value)) {
Integer existingKey = findKeyByValue(value);
if (existingKey != null && existingKey > key) {
super.remove(existingKey);
super.put(key, value);
}
return value;
}
return super.put(key,value);
}
private Integer findKeyByValue(Integer value) {
for (Map.Entry<Integer, Integer> entry : this.entrySet()) {
if (entry.getValue().equals(value)) {
return entry.getKey();
}
}
return null;
}
{
put(761,0x20);
put(762,0x06);
put(765,0x07);
put(768,0x08);
}
};

private final File dataFolder;
MapperConfig(File dataFolder) {
this.dataFolder = dataFolder;
}

@Override
public void save() {
try {
YamlConfigurationLoader loader = YamlConfigurationLoader.builder().file(new File(dataFolder, "mapper.yml")).indent(2).build();
CommentedConfigurationNode rootNode = loader.load();
CommentedConfigurationNode mapperNode = rootNode.node("mapper");
for (Map.Entry<Integer, Integer> entry : packetMapping.entrySet()) {
mapperNode.node(entry.getKey().toString()).set(String.format("0x%02X", entry.getValue()));
}
loader.save(rootNode);
} catch (ConfigurateException e) {
throw new RuntimeException(e);
}
}

@Override
public void reload() {
YamlConfigurationLoader loader = YamlConfigurationLoader.builder().file(new File(dataFolder, "mapper.yml")).build();
try {
ConfigurationNode mapperNode = loader.load().node("mapper");
for (Map.Entry<Object, ? extends ConfigurationNode> entry : mapperNode.childrenMap().entrySet()) {
String key = entry.getKey().toString();
String hexValue = entry.getValue().getString();
if (hexValue != null) {
int intValue = Integer.decode(hexValue);
packetMapping.put(Integer.parseInt(key), intValue);
}
}
} catch (ConfigurateException e) {
throw new RuntimeException(e);
}
return new MapperConfig(mapper);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class PluginConfig {
@Getter
private SqlConfig sqlConfig;
@Getter
private MapperConfig mapperConfig;
@Getter
private String nameAllowedRegular;
private final MultiCore core;
@Getter
Expand Down Expand Up @@ -88,6 +90,10 @@ public void reload() throws IOException, URISyntaxException {
saveResource("config.yml", false);
saveResource("mapper.yml", false);
saveResourceDir("examples", true);
if (mapperConfig != null)
mapperConfig.save();
mapperConfig = new MapperConfig(dataFolder);
mapperConfig.reload();

CommentedConfigurationNode configConfigurationNode =
YamlConfigurationLoader.builder().file(new File(dataFolder, "config.yml")).build().load();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.Getter;
import moe.caa.multilogin.api.MapperConfigAPI;
import moe.caa.multilogin.api.MultiLoginAPI;
import moe.caa.multilogin.api.MultiLoginAPIProvider;
import moe.caa.multilogin.api.data.MultiLoginPlayerData;
Expand All @@ -17,6 +18,7 @@
import moe.caa.multilogin.core.auth.service.yggdrasil.serialize.GameProfileSerializer;
import moe.caa.multilogin.core.auth.service.yggdrasil.serialize.PropertySerializer;
import moe.caa.multilogin.core.command.CommandHandler;
import moe.caa.multilogin.core.configuration.MapperConfig;
import moe.caa.multilogin.core.configuration.PluginConfig;
import moe.caa.multilogin.core.configuration.service.BaseServiceConfig;
import moe.caa.multilogin.core.database.SQLManager;
Expand Down Expand Up @@ -70,7 +72,6 @@ public class MultiCore implements MultiCoreAPI, MultiLoginAPI {
@Getter
private final String httpRequestHeaderUserAgent = "MultiLogin/v2.0";


/**
* 构建猫踢核心,这个方法将会被反射调用
*/
Expand Down Expand Up @@ -175,6 +176,11 @@ public void close() {
sqlManager.close();
}

@Override
public MapperConfigAPI getMapperConfig() {
return pluginConfig.getMapperConfig();
}

@NotNull
@Override
public Collection<BaseServiceConfig> getServices() {
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/resources/mapper.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mapper:
"MINECRAFT_1_19_3": 0x20
"MINECRAFT_1_19_4": 0x06
"MINECRAFT_1_20_5": 0x07
"MINECRAFT_1_21_2": 0x08
761: 0x20
762: 0x06
765: 0x07
768: 0x08
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,20 @@ public void inject(MultiCoreAPI multiCoreAPI) throws NoSuchFieldException, Class
redirectInput(serverbound, EncryptionResponsePacket.class, () -> new MultiEncryptionResponse(multiCoreAPI));
redirectInput(serverbound, ServerLoginPacket.class, () -> new MultiServerLogin(multiCoreAPI));
}
}

public void registerChatSession(Map<Integer,Integer> packetMapping) {
// chat
try {
CommentedConfigurationNode mapperConfigurationNode =
YamlConfigurationLoader.builder().file(new File(multiCoreAPI.getPlugin().getDataFolder(), "mapper.yml")).build().load();

MapperConfig mapperConfig = MapperConfig.read(mapperConfigurationNode);
StateRegistry.PacketRegistry serverbound = getServerboundPacketRegistry(StateRegistry.PLAY);

LinkedList<StateRegistry.PacketMapping> playerSessionPacketMapping = new LinkedList<>();
for (Map.Entry<String, Integer> entry : mapperConfig.getPacketMapping().entrySet()) {
for (Map.Entry<Integer, Integer> entry : packetMapping.entrySet()) {
LoggerProvider.getLogger().debug("Register PlayerSessionPacketBlocker for protocol version: " + entry.getKey());
playerSessionPacketMapping.add(createPacketMapping(entry.getValue(), ProtocolVersion.valueOf(entry.getKey()), false));
playerSessionPacketMapping.add(createPacketMapping(entry.getValue(), ProtocolVersion.getProtocolVersion(entry.getKey()), false));
}
registerPacket(serverbound, PlayerSessionPacketBlocker.class, PlayerSessionPacketBlocker::new, playerSessionPacketMapping.toArray(new StateRegistry.PacketMapping[0]));

} catch (Throwable throwable){
LoggerProvider.getLogger().error("Unable to register PlayerSessionPacketBlocker, chat session blocker does not work as expected.", throwable);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,37 @@
public class PlayerSessionPacketBlocker implements MinecraftPacket {
private UUID sessionId;
private IdentifiedKey identifiedKey;
private boolean hasKey = false;

public PlayerSessionPacketBlocker(){

}

@Override
public void decode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
sessionId = ProtocolUtils.readUuid(byteBuf);
identifiedKey = ProtocolUtils.readPlayerKey(protocolVersion, byteBuf);
try {
sessionId = ProtocolUtils.readUuid(byteBuf);
identifiedKey = ProtocolUtils.readPlayerKey(protocolVersion, byteBuf);
} catch (Exception ignore) {
hasKey = false;
}
}

@Override
public void encode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
ProtocolUtils.writeUuid(byteBuf, sessionId);
ProtocolUtils.writePlayerKey(byteBuf, identifiedKey);
try {
//不发送ChatSession
if (hasKey) {
ProtocolUtils.writeUuid(byteBuf, sessionId);
ProtocolUtils.writePlayerKey(byteBuf, identifiedKey);
}
} catch (Exception ignore) {
//idk why does it throw the `java.lang.IllegalArgumentException`
//Caused by: java.lang.IllegalArgumentException: Unknown node type 3
// at com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket.deserializeNode(AvailableCommandsPacket.java:219)
// at com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket.decode(AvailableCommandsPacket.java:88)
// at com.velocitypowered.proxy.protocol.netty.MinecraftDecoder.tryDecode(MinecraftDecoder.java:83)
}
}

@Override
Expand Down
25 changes: 14 additions & 11 deletions velocity/libraries/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
1. 编译 velocity
2. 复制 proxy 和 api 下带 SNAPSHOT 的 jar 进来
1. 手动编译
1. 编译 velocity
2. 复制 proxy 和 api 下带 SNAPSHOT 的 jar 进来

例子:

```
git clone --depth 1 https://github.com/PaperMC/Velocity Velocity
cd Velocity
gradle build
cp proxy/build/libs/velocity-proxy-*-SNAPSHOT.jar ../
cp api/build/libs/velocity-api-*-SNAPSHOT.jar ../
```
例子:

```
git clone --depth 1 https://github.com/PaperMC/Velocity Velocity
cd Velocity
gradle build
cp proxy/build/libs/velocity-proxy-*-SNAPSHOT.jar ../
cp api/build/libs/velocity-api-*-SNAPSHOT.jar ../
```
2. Gradle自动编译
1. 在根目录下运行 `./gradlew MultiLogin:velocity:getLatestVelocity` 或 `gradle MultiLogin:velocity:getLatestVelocity`
Loading

0 comments on commit e315cb5

Please sign in to comment.