所以我在GitHub上分享了这个gem,认为我可以修复并更新它的一些问题,以便在Rails项目中使用。我基本上得到了这个输出:
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
但是这只是给出了相同的响应,随机吐出编码错误而不是。
以下是包含所有代码的相关GitHub仓库:RubyMinecraft
非常感谢任何帮助。
答案 0 :(得分:2)
在Query
课程中有this line:
@key = Array(key).pack('N')
这会创建一个字符串,其关联的编码为ASCII-8BIT(即它是二进制字符串)。
稍后@key
this line使用了query = @sock.send("\xFE\xFD\x00\x01\x02\x03\x04" + @key, 0)
:
Encoding::CompatibilityError
在Ruby 2.0中,String文字的默认编码是UTF-8,因此这是将UTF-8字符串与二进制字符串组合。
当Ruby尝试这样做时,它首先检查二进制字符串是否只包含7位值(即所有字节都小于或等于127,顶部字节为0),如果是,则考虑它与UTF-8兼容,因此无需进一步解决它们。如果没有,(即如果它包含大于127的字节)则两个字符串不兼容并且引发@key
。
是否引发错误取决于query = @sock.send("\xFE\xFD\x00\x01\x02\x03\x04".force_encoding(Encoding::ASCII_8BIT) + @key, 0)
的内容,该内容是从服务器的响应初始化的。有时这个值恰好只包含7位值,因此不会引发错误,有时会有一个高位设置的字节,因此会产生错误。这就是错误似乎是“随机”的原因。
要修复它,您可以指定组合两个字符串的行中的字符串文字应视为二进制。最简单的方法是使用force_encoding
,如下所示:
{{1}}