2013-07-13 2 views
3

GitHub에서이 보석을 수정하여 Rails 프로젝트에서 사용하기 위해 일부 문제를 수정하고 업데이트 할 수 있다고 생각했습니다. 나는 기본적으로이 출력을 얻을 :Ruby Gem이 임의로 인코딩 오류를 반환합니다

irb(main):020:0> query = Query::simpleQuery('xx.xxx.xxx.xx', 25565) 
=> [false, #<Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT>] 

irb(main):021:0> query = Query::simpleQuery('xx.xxx.xxx.xx', 25565) 
=> {:motd=>"Craftnet", :gametype=>"SMP", :map=>"world", :numplayers=>"0", :maxplayers=>"48"} 

첫 번째 응답은 인코딩 오류의 예이고, 두 번째는 (IP의 아웃 촬영) 원하는 출력됩니다. 기본적으로 이것은 Minecraft 서버에 정보를 문의하는 것입니다.

나는
Encoding.default_external = Encoding::UTF_8 
Encoding.default_internal = Encoding::UTF_8 

를 사용하여 시도하지만 그건 그냥 동일한 응답, 무작위로 인코딩 오류를 뱉어하지했다. 어떤 도움을 크게 감상 할 수 RubyMinecraft

: 여기

는 모든 코드와 관련 GitHub의의의 repo입니다. Query 클래스

답변

2

this line있다 :

@key = Array(key).pack('N') 

이것은 ASCII-8BIT의 연관된 인코딩 문자열을 (즉, 그것은 바이너리 스트링이다) 생성한다. 루비 2.0 문자열 리터럴의 기본 인코딩에서

query = @sock.send("\xFE\xFD\x00\x01\x02\x03\x04" + @key, 0) 

이 UTF-8, 그래서 이것은 바이너리 하나에 UTF-8 문자열을 결합한다 :

나중에 @keythis line에 사용됩니다.

루비가이 작업을 시도하면 먼저 이진 문자열에 7 비트 값만 들어 있는지 확인합니다 (즉, 모든 바이트가 127보다 작거나 같고 맨 위 바이트가 0 임). 그렇지 않으면 UTF-8과 호환되므로 더 이상의 문제없이 결합합니다. 그렇지 않은 경우 (즉, 127보다 큰 바이트를 포함하는 경우) 두 문자열은 호환되지 않으며 Encoding::CompatibilityError이 발생합니다.

오류 발생 여부는 @key의 내용에 따라 달라지며 서버의 응답으로 초기화됩니다. 때때로이 값은 7 비트 값만 포함하기 때문에 오류가 발생하지 않으며, 다른 비트는 상위 비트가 설정된 바이트가 있기 때문에 오류가 발생합니다. 이것이 오류가 "무작위"로 나타나는 이유입니다.

두 개의 문자열이 결합 된 줄의 문자열 리터럴을 이진으로 처리하도록 지정할 수 있습니다.

query = @sock.send("\xFE\xFD\x00\x01\x02\x03\x04".force_encoding(Encoding::ASCII_8BIT) + @key, 0) 
+0

당신이 너무 많이뿐만 아니라이 내 루비 지식을 더욱 않았 감사뿐만 아니라 내 문제를 해결 : 가장 간단한 방법은 다음과 같이 force_encoding을 사용하는 것입니다. – Tylerjd

관련 문제