diff --git a/app/models/pet.rb b/app/models/pet.rb index a4aa5214..540a37a3 100644 --- a/app/models/pet.rb +++ b/app/models/pet.rb @@ -168,7 +168,7 @@ class Pet < ApplicationRecord # Return the response body as a `HashWithIndifferentAccess`. def self.send_amfphp_request(request, timeout: 10) begin - response = request.post(timeout: timeout, headers: { + response_data = request.post(timeout: timeout, headers: { "User-Agent" => Rails.configuration.user_agent_for_neopets, }) rescue RocketAMFExtensions::RemoteGateway::AMFError => e @@ -177,7 +177,7 @@ class Pet < ApplicationRecord raise DownloadError, e.message, e.backtrace end - HashWithIndifferentAccess.new(response.messages[0].data.body) + HashWithIndifferentAccess.new(response_data) end end diff --git a/lib/rocketamf_extensions/remote_gateway/request.rb b/lib/rocketamf_extensions/remote_gateway/request.rb index d102b6c3..9adde85a 100644 --- a/lib/rocketamf_extensions/remote_gateway/request.rb +++ b/lib/rocketamf_extensions/remote_gateway/request.rb @@ -54,7 +54,25 @@ module RocketAMFExtensions raise RocketAMF::AMFError.new(first_message_data) end - result + # HACK: It seems to me that these messages come back with Windows-1250 + # (or similar) encoding on the strings? I'm basing this on the + # Patchwork Staff item, whose description arrives as: + # + # "That staff is cute, but dont use it as a walking stick \x96 I " + + # "dont think it will hold you up!" + # + # And the `\x96` is meant to represent an endash, which it doesn't in + # UTF-8 or in most extended ASCII encodings, but *does* in Windows's + # specific extended ASCII. + # + # Idk if this is something to do with the AMFPHP spec or how the AMFPHP + # server code they use serializes strings (I couldn't find any + # reference to it?), or just their internal database encoding being + # passed along as-is, or what? But this seems to be the most correct + # interpretation I know how to do, so, let's do it! + result.messages[0].data.body.tap do |body| + reencode_strings! body, "Windows-1250", "UTF-8" + end end private @@ -86,6 +104,16 @@ module RocketAMFExtensions raise ConnectionError, e.message end end + + def reencode_strings!(target, from, to) + if target.is_a? String + target.force_encoding(from).encode!(to) + elsif target.is_a? Array + target.each { |x| reencode_strings!(x, from, to) } + elsif target.is_a? Hash + target.values.each { |x| reencode_strings!(x, from, to) } + end + end end class ConnectionError < RuntimeError