mc의 부분 코드 연구

8313 단어

minecraft server


spigot 서버 코드 중,net.minecraft.server.v1_8_R3.PacketPlay OutPlayer Info는 게이머 프로필인 게임 프로필을 클라이언트에 서열화하는 데 사용됩니다.어떤 서버가 되돌아오는 형식이 요구에 부합되지 않아 어떤 도구를 사용한 후 어떤 서버가 붕괴되었다.

com.mojiang.authlib


서버와 클라이언트의 공용 코드로 yggdrasil 사용자 로그인 검증과 사용자 프로필을 가져오는 데 사용됩니다.
그 중에서com/mojang/authlib/yggdrasil/YggrasilMinecraftSessionService.자바는 모든 URL과 자원 도메인 이름 리스트를 정의합니다. 이 코드를 직접 변경하고 자바로 다시 포장하면 클라이언트와 서버 측의 행동을 변경할 수 있습니다.

spigot 서버


입구

spigot-1.7.x-1.8.1.jar!\org\bukkit\craftbukkit\Main
-> 
net.minecraft.server.v1_7_R4.MinecraftServer.main(options1);

  MinecraftServer             , org\bukkit\craftbukkit\v1_7_R4\CraftServer                    。

net.minecraft.server.v1_7_R4.LoginListener

public void a(PacketLoginInEncryptionBegin packetlogininencryptionbegin) { 함수는 로그인 요청을 처리하는 데 사용되며, 에서 라인을 켜서 서버에 로그인을 검증합니다(해적판 서버의 경우 라인에서fireLogin Events에서 로그인 성공을 선언합니다).
1.7 버전의spigot의 실현은 ThreadPlayerLookupUUID 루틴 클래스를 열어 로그인을 검증하는 것이다.1.8.8 버전은 이 함수에서 익명 루틴 클래스를 직접 열었지만 그 안의 절차는 대체적으로 같다. 모두 호출LoginListener.this.server.aD().hasJoinedServer(...)을 통해 로그인을 검증한 것이다. 이aD()는 위에서 언급한 YggdrasilMinecraftSessionService로 되돌아온다.
hasJoinedServer에서 net.minecraft.util.com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService.makeRequest 형식의 대상을 얻기 위해 링크를 지정합니다. 이 대상의 json 원형은 mc의 로그인 검증 인터페이스 문서에 있습니다. 더 이상 말하지 않겠습니다.Response를 받은 후hasJoinedServer는Response를 사용하여 Game Profile을 구성하고 되돌려줍니다.Login Listener는 되돌아오는 Game Profile을 구성원 변수 i에 저장합니다.
여기에 연결이 성공하면 연결 후 처리 프로세스를 터치하기 시작합니다. 그 중 하나는 Login Listener를 타고 Player List를 호출한 다음에 위에서 언급한 PacketPlay OutPlayer Info를 통해 가방을 만들고 넷을 통과하는 것입니다.minecraft.server.v1_7_R4.PlayerConnection.SendPacket()이 전송 대기열에 추가되어 마지막으로 전송됩니다.네트워크 전송 시 PacketPlayOutPlayerInfo 호출b 이 패키지를 2진법으로 서열화합니다.
하지만 Spigot 1.7의, 패키지 데이터serializer에서.version>=20 이 지점이야말로 피부와 망토 등의 정보를 완전하게 출력할 수 있다.다른 지점에서name만 출력됩니다.통과http://wiki.vg/Protocol_version_numbers에서 20버전 번호는 1.7.10(version=5)과 1.8버전(version=47) 사이에 있는 어떤 테스트 버전의 버전 번호이기 때문에 구버전 mc 클라이언트는 프로퍼티스가 있는 게임 프로필의 패키지를 직접 되돌려주지 않을 것이다.
1.7.10 즉 version이 5인 프로토콜에서 사용자 목록에는 세 개의 필드인 Player name, Online, Ping만 표시되어 있기 때문에 코드 차이가 발생합니다.
47버전의 프로토콜에서 더 많은 형식을 구분하고 액션을 추가하여 한 그룹에 대한 알림을 제공합니다.action이 0(add player)인 메시지에는 Game Profile의 Property 속성이 함께 표시됩니다.
1.7.10 이전 버전에서는 Mojang API#UUID-> Profile+Skin/Cape를 통해서만 피부와 망토를 요청할 수 있었습니다.
 public void PacketPlayOutPlayerInfo.b(PacketDataSerializer packetdataserializer) throws IOException {
    if(packetdataserializer.version >= 20) {
        ...
         case 0:
                packetdataserializer.a(this.player.getName());
                PropertyMap properties = this.player.getProperties();
                packetdataserializer.b(properties.size());
                Iterator i$ = properties.values().iterator();

                while(i$.hasNext()) {
                    Property property = (Property)i$.next();
                    packetdataserializer.a(property.getName());
                    packetdataserializer.a(property.getValue());
                    packetdataserializer.writeBoolean(property.hasSignature());
                    if(property.hasSignature()) {
                        packetdataserializer.a(property.getSignature());
                    }
                }
        ...
    } else {        
        packetdataserializer.a(this.username);
        packetdataserializer.writeBoolean(this.action != 4);
        packetdataserializer.writeShort(this.ping);
    }
}

BungeeCord


지원되는 클라이언트 버전 목록

HasJoinedMinecraftServerResponse에서 SUPPORTED 를 정의했습니다.VERSION_IDS:
    public static final List SUPPORTED_VERSIONS = Arrays.asList(
            "1.8.x",
            "1.9.x",
            "1.10.x",
            "1.11.x"
    );
    public static final List SUPPORTED_VERSION_IDS = Arrays.asList( ProtocolConstants.MINECRAFT_1_8,
            ProtocolConstants.MINECRAFT_1_9,
            ProtocolConstants.MINECRAFT_1_9_1,
            ProtocolConstants.MINECRAFT_1_9_2,
            ProtocolConstants.MINECRAFT_1_9_4,
            ProtocolConstants.MINECRAFT_1_10,
            ProtocolConstants.MINECRAFT_1_11
    );


정품 로그인 확인

net.md_5.bungee.protocol.ProtocolConstants.javanet.md_5.bungee.connection.InitialHandler 방법에서 호출
      :
HttpClient.get("https://sessionserver.mojang.com/session/minecraft/hasJoined?username=" + xxx,new Callback(){
  if (success){
     ...
   }  else {
      InitialHandler.this.disconnect("           ")
   }   
});

클라이언트


authlib


위 서버와 같이 클라이언트의authlib이 있습니다.minecraft의 public void handle(EncryptionResponse encryptResponse) 디렉터리에서 원래 클라이언트와 같은 버전을 바꾸면 됩니다.

피부와 망토 획득


서버가 MojangAPi 인증 클라이언트에 액세스하여 로그인하면 스킨과 망토 데이터가 생기고 캐시가 추가됩니다.
1.8 버전 로그인에 성공하면 서버가 클라이언트의 PlayerList_Item 메시지에 피부와 망토 데이터가 들어가기 때문에 클라이언트는 자신과 다른 사람의 피부를 직접 보여줄 수 있다.
1.7 이전 버전의 클라이언트, 1.7 버전은 Spawn Player를 통해 한 유저에게 주위에서 사용자의 피부 데이터를 볼 수 있음을 알립니다.그러나 자신의 피부는 Yggdrasil Minecraft Session Service 클래스의 보호된 Game Profile fill Game Profile(Game Profile Game profile,boolean flag) 방법에서 Mojang Api를 방문하여 자신의 피부 데이터를 얻어야 하며, 되돌아오는 결과는 서버가 Mojang APi를 방문하여 얻는 결과와 차이가 많지 않다.
{
    "timestamp": 1501839740,
    "profileId": "08d699bb6400355e981b678c9441fa75",
    "profileName": "k1988",
    "signatureRequired": false,
    "textures": {
        "CAPE": {
            "url": "http://icon.mc.kuai8.com/cape/douyu.png"
        },
        "SKIN": {
            "url": "http://icon.mc.kuai8.com/imshop/201708/20170803110431142.png"
        }
    }
}

화이트 리스트


안전을 위해 피부와 망토의 연결은 Yggdrasil Minecraft Session 서비스에서 이루어져야 합니다.isWhitelistedDomain에서 미리 정의된 몇 개의 백명단 주소를 판단합니다.

forge 버전


무적 모드


spigot를 컴파일할 때 넷을 역컴파일했습니다.minecraft.server.Entity 코드에는 함수가 있습니다.
    public boolean damageEntity(DamageSource damagesource, float f) {
        if (this.isInvulnerable(damagesource)) {
            return false;
        } else {
            this.ac();
            return false;
        }
    }

forge버전.minecraft\libraries\com\mojang\authlib의 코드에도 유사하지만 더 복잡한 함수가 있는데 훅이 이 함수의 기능을 직접 Returnfalse로 떨어뜨리면 무적 모드를 실현할 수 있다.
public boolean func_70097_a(DamageSource source, float amount) {
    if(this.func_180431_b(source)) {
        return false;
    } else {
        boolean flag = this.field_71133_b.func_71262_S() && this.func_175400_cq() && "fall".equals(source.field_76373_n);
        if(!flag && this.field_147101_bU > 0 && source != DamageSource.field_76380_i) {
            return false;
        } else {
            if(source instanceof EntityDamageSource) {
                Entity entity = source.func_76346_g();
                if(entity instanceof EntityPlayer && !this.func_96122_a((EntityPlayer)entity)) {
                    return false;
                }

                if(entity instanceof EntityArrow) {
                    EntityArrow entityarrow = (EntityArrow)entity;
                    if(entityarrow.field_70250_c instanceof EntityPlayer && !this.func_96122_a((EntityPlayer)entityarrow.field_70250_c)) {
                        return false;
                    }
                }
            }

            return super.func_70097_a(source, amount);
        }
    }
}

피부 성별 선택


게임의 기본 스킨은 Steve 또는 Alex 선택 방식입니다.
ref:http://wiki.vg/Mojang_API#UUID_-.3E_Profile_.2B_Skin.2FCape
/*
 * uuid hashCode       Alex,     Steve
 */
private static void printType(String uuid) {
    UUID uid = UUID.fromString(uuid);
    if ((uid.hashCode() & 1) != 0) {
      System.out.println(uid.toString() + " = Alex");
    } else {
      System.out.println(uid.toString() + " = Steve");
    }
  }

좋은 웹페이지 즐겨찾기