赞 | 27 |
VIP | 400 |
好人卡 | 13 |
积分 | 17 |
经验 | 69730 |
最后登录 | 2023-6-12 |
在线时间 | 3038 小时 |
Lv3.寻梦者 (暗夜天使) 精灵族の天使
- 梦石
- 0
- 星屑
- 1697
- 在线时间
- 3038 小时
- 注册时间
- 2007-3-16
- 帖子
- 33731
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 精灵使者 于 2015-2-1 17:44 编辑
精灵在汉化游戏的时候,发现一些使用中文用户名的游戏无法启动,症状如下:
经检查出问题的脚本如下:
# Create Path Where Folder Should Be Created path = " " * 256 path = ENV['AV_APPDATA'].rstrip $appPath = path.to_s + "\\To the Moon - Freebird Games" # Create Your Folder if !File.exists?($appPath) Dir.mkdir($appPath) #出问题的那行 end
# Create Path Where Folder Should Be Created
path = " " * 256
path = ENV['AV_APPDATA'].rstrip
$appPath = path.to_s + "\\To the Moon - Freebird Games"
# Create Your Folder
if !File.exists?($appPath)
Dir.mkdir($appPath) #出问题的那行
end
于是就麻烦了。
中文用户名导致EV['AV_APPDATA']产生乱码,以至于后面的建立文件夹失败。
所以就需要进行S2U转换一下。
解决脚本如下:
#Using for Non-english speaking words encoding conversion #quintess non-english paths APPNAME = "\\To the Moon - Freebird Games" module Seiran20 module_function class ::Integer; def to_ptr; self; end; def to_param; 'i'; end; def ord; self; end; end class ::String;def to_ptr; [self].pack('p').unpack('L').first; end; def to_param; 'p'; end; end def procname(a, b) class << a; self; end.send :define_method, :inspect do b end a end def api(dll,func) procname lambda{|*args| Win32API.new(dll,func,args.map{|x|x.to_param}, 'i').call *args }, "Seiran20.api<#{dll}!#{func}>" end LL = api("kernel32", "LoadLibrary") GPA = api("kernel32", "GetProcAddress") def funcaddr(dll, func) x = GPA.call(LL.call(dll), func) x == 0 ? nil : x end def capi(dll, func) callproc(GPA.call(LL.call(dll), func)) procname lambda{|*args|apicall.call((code=[0x55,0xe589].pack('CS')+args.map{|x| [0x68, x.to_ptr].pack('CL')}.reverse.join+[0xb8, addr.to_ptr, 0xD0FF, 0xc481, (stdcall ? 0 : args.length*4) , 0x10c2c9].pack('CLSSLL')),0,0,0,0)}, "Seiran20.capi<#{dll}!#{func}>" end def to_wc(str, cp = 65001) (buf = "\0\0"*str.length)[0, 2*api('Kernel32', 'MultiByteToWideChar').call(cp, 0, str.to_ptr, -1, buf, buf.length)] end def to_mb(str, cp = 65001) (buf = "\0\0"* str.length)[0, api('Kernel32', 'WideCharToMultiByte').call(cp, 0, str.to_ptr, -1, buf, buf.length, 0, 0)] end end # Create Path Where Folder Should Be Created (edited) # path = " " * 256 # path = ENV['AV_APPDATA'].rstrip path = Seiran20.to_mb(Seiran20.to_wc(ENV['AV_APPDATA']+"\0", 0)+"\0\0").sub(/\0+$/, "") $appPath = path.to_s + APPNAME # redef File.exist for #72 Error def File.exists?(f) ((open("#{f}\\nul", "rb").close || true) rescue false) || ((open(f, "rb").close || true) rescue false) end # Create Your Folder if !File.exists?($appPath) Dir.mkdir($appPath) end
#Using for Non-english speaking words encoding conversion
#quintess non-english paths
APPNAME = "\\To the Moon - Freebird Games"
module Seiran20
module_function
class ::Integer; def to_ptr; self; end; def to_param; 'i'; end; def ord; self; end; end
class ::String;def to_ptr; [self].pack('p').unpack('L').first; end; def to_param; 'p'; end; end
def procname(a, b)
class << a; self; end.send :define_method, :inspect do b end
a
end
def api(dll,func)
procname lambda{|*args|
Win32API.new(dll,func,args.map{|x|x.to_param}, 'i').call *args
}, "Seiran20.api<#{dll}!#{func}>"
end
LL = api("kernel32", "LoadLibrary")
GPA = api("kernel32", "GetProcAddress")
def funcaddr(dll, func)
x = GPA.call(LL.call(dll), func)
x == 0 ? nil : x
end
def capi(dll, func)
callproc(GPA.call(LL.call(dll), func))
procname lambda{|*args|apicall.call((code=[0x55,0xe589].pack('CS')+args.map{|x| [0x68, x.to_ptr].pack('CL')}.reverse.join+[0xb8, addr.to_ptr, 0xD0FF, 0xc481, (stdcall ? 0 : args.length*4) , 0x10c2c9].pack('CLSSLL')),0,0,0,0)}, "Seiran20.capi<#{dll}!#{func}>"
end
def to_wc(str, cp = 65001)
(buf = "\0\0"*str.length)[0, 2*api('Kernel32', 'MultiByteToWideChar').call(cp, 0, str.to_ptr, -1, buf, buf.length)]
end
def to_mb(str, cp = 65001)
(buf = "\0\0"* str.length)[0, api('Kernel32', 'WideCharToMultiByte').call(cp, 0, str.to_ptr, -1, buf, buf.length, 0, 0)]
end
end
# Create Path Where Folder Should Be Created (edited)
# path = " " * 256
# path = ENV['AV_APPDATA'].rstrip
path = Seiran20.to_mb(Seiran20.to_wc(ENV['AV_APPDATA']+"\0", 0)+"\0\0").sub(/\0+$/, "")
$appPath = path.to_s + APPNAME
# redef File.exist for #72 Error
def File.exists?(f)
((open("#{f}\\nul", "rb").close || true) rescue false) ||
((open(f, "rb").close || true) rescue false)
end
# Create Your Folder
if !File.exists?($appPath)
Dir.mkdir($appPath)
end
由于是商业脚本所以考虑到没有权限修改,所以在此备份。
这是个严重的问题。
上面那个脚本依然出错的原因是,中文路径不支持File.exists
于是精灵就采用更改路径到公共路径下的方式来做,而各自的用户名将会被转换成数字分开。
# Create Path Where Folder Should Be Created(edited) $commonpath = ENV['CommonProgramfiles'] + "\\To the Moon - Freebird Games" $filename = " " * 36 $filename = (ENV['USERNAME'].rstrip).unpack("H*")[0].to_i(16).to_s(36) $appPath = $commonpath + "\\" + $filename # Create Your Folder if !File.exists?($commonpath) Dir.mkdir($commonpath) end if !File.exists?($appPath) Dir.mkdir($appPath) end save_file_a = $appPath music_file = $appPath + "\\" + "music.txt" window_file = $appPath + "\\" + "window.txt" user_name_file = $appPath + "\\" "user_name.txt" #make a mark of username
# Create Path Where Folder Should Be Created(edited)
$commonpath = ENV['CommonProgramfiles'] + "\\To the Moon - Freebird Games"
$filename = " " * 36
$filename = (ENV['USERNAME'].rstrip).unpack("H*")[0].to_i(16).to_s(36)
$appPath = $commonpath + "\\" + $filename
# Create Your Folder
if !File.exists?($commonpath)
Dir.mkdir($commonpath)
end
if !File.exists?($appPath)
Dir.mkdir($appPath)
end
save_file_a = $appPath
music_file = $appPath + "\\" + "music.txt"
window_file = $appPath + "\\" + "window.txt"
user_name_file = $appPath + "\\" "user_name.txt" #make a mark of username
这是另外一种方案,但是会和以前的英文版路径不兼容。这个问题解决有些麻烦。
所以使用注册表修改av_data这个也是个好办法,就是直接修改变量。这样不会影响到用户名的绝大多数玩家。
2015年2月1日更新:
精灵已经完成了插件脚本方式,不需要对原始的脚本做任何修改就可以兼容中文!
使用方法新建文档插入即可。
脚本如下:
#============================================================================== # ** Rewrite function on Dir and File (edited by fay_envoy) #------------------------------------------------------------------------------ # rewrite this code for solve the problem of non-English character problem. # some function only using for the game commercial scripts. #============================================================================== #-------------------------------------------------------------------------- # * Function needed #-------------------------------------------------------------------------- module Seiran20 module_function class ::Integer; def to_ptr; self; end; def to_param; 'i'; end; def ord; self; end; end class ::String;def to_ptr; [self].pack('p').unpack('L').first; end; def to_param; 'p'; end; end def procname(a, b) class << a; self; end.send :define_method, :inspect do b end a end def api(dll,func) procname lambda{|*args| Win32API.new(dll,func,args.map{|x|x.to_param}, 'i').call *args }, "Seiran20.api<#{dll}!#{func}>" end LL = api("kernel32", "LoadLibrary") GPA = api("kernel32", "GetProcAddress") def funcaddr(dll, func) x = GPA.call(LL.call(dll), func) x == 0 ? nil : x end def capi(dll, func) callproc(GPA.call(LL.call(dll), func)) procname lambda{|*args|apicall.call((code=[0x55,0xe589].pack('CS')+args.map{|x| [0x68, x.to_ptr].pack('CL')}.reverse.join+[0xb8, addr.to_ptr, 0xD0FF, 0xc481, (stdcall ? 0 : args.length*4) , 0x10c2c9].pack('CLSSLL')),0,0,0,0)}, "Seiran20.capi<#{dll}!#{func}>" end def to_wc(str, cp = 65001) (buf = "\0\0"*str.length)[0, 2*api('Kernel32', 'MultiByteToWideChar').call(cp, 0, str.to_ptr, -1, buf, buf.length)] end def to_mb(str, cp = 65001) (buf = "\0\0"* str.length)[0, api('Kernel32', 'WideCharToMultiByte').call(cp, 0, str.to_ptr, -1, buf, buf.length, 0, 0)] end def transcode(str) return to_mb(to_wc(str +"\0", 0)+"\0\0").sub(/\0+$/, "") end end PathFileExists = Win32API.new("shlwapi", "PathFileExistsW", "P", "I") MultiByteToWideChar = Win32API.new("kernel32", "MultiByteToWideChar", "ILPIPI", "I") #-------------------------------------------------------------------------- # * File.exists rewrite #-------------------------------------------------------------------------- def File.exists?(filename) nfilename = Seiran20.transcode(filename) + "\0" len = MultiByteToWideChar.call(65001, 0, nfilename, -1, 0, 0) << 1 buf = " " * len MultiByteToWideChar.call(65001, 0, nfilename, -1, buf, len) return PathFileExists.call(buf) == 0 ? false : true end #-------------------------------------------------------------------------- # * FileTest.exist rewrite #-------------------------------------------------------------------------- def FileTest.exist?(filename) return File.exists?(filename) end #-------------------------------------------------------------------------- # * Dir function rewrite (only needed) #-------------------------------------------------------------------------- class << Dir alias_method :old_mkdir, :mkdir def mkdir(*args,&block) args[0] = Seiran20.transcode(args[0]) old_mkdir(*args,&block) end end #-------------------------------------------------------------------------- # * File.new and open rewrite #-------------------------------------------------------------------------- class << File alias_method :old_new, :new alias_method :old_open, :open def new(*args,&block) args[0] = Seiran20.transcode(args[0]) old_new(*args,&block) end def open(*args,&block) args[0] = Seiran20.transcode(args[0]) old_open(*args,&block) end end #-------------------------------------------------------------------------- # * open rewrite( for commercial scripts) #-------------------------------------------------------------------------- alias old_open open def open(*args,&block) args[0] = Seiran20.transcode(args[0]) old_open(*args,&block) end
#==============================================================================
# ** Rewrite function on Dir and File (edited by fay_envoy)
#------------------------------------------------------------------------------
# rewrite this code for solve the problem of non-English character problem.
# some function only using for the game commercial scripts.
#==============================================================================
#--------------------------------------------------------------------------
# * Function needed
#--------------------------------------------------------------------------
module Seiran20
module_function
class ::Integer; def to_ptr; self; end; def to_param; 'i'; end; def ord; self; end; end
class ::String;def to_ptr; [self].pack('p').unpack('L').first; end; def to_param; 'p'; end; end
def procname(a, b)
class << a; self; end.send :define_method, :inspect do b end
a
end
def api(dll,func)
procname lambda{|*args|
Win32API.new(dll,func,args.map{|x|x.to_param}, 'i').call *args
}, "Seiran20.api<#{dll}!#{func}>"
end
LL = api("kernel32", "LoadLibrary")
GPA = api("kernel32", "GetProcAddress")
def funcaddr(dll, func)
x = GPA.call(LL.call(dll), func)
x == 0 ? nil : x
end
def capi(dll, func)
callproc(GPA.call(LL.call(dll), func))
procname lambda{|*args|apicall.call((code=[0x55,0xe589].pack('CS')+args.map{|x| [0x68, x.to_ptr].pack('CL')}.reverse.join+[0xb8, addr.to_ptr, 0xD0FF, 0xc481, (stdcall ? 0 : args.length*4) , 0x10c2c9].pack('CLSSLL')),0,0,0,0)}, "Seiran20.capi<#{dll}!#{func}>"
end
def to_wc(str, cp = 65001)
(buf = "\0\0"*str.length)[0, 2*api('Kernel32', 'MultiByteToWideChar').call(cp, 0, str.to_ptr, -1, buf, buf.length)]
end
def to_mb(str, cp = 65001)
(buf = "\0\0"* str.length)[0, api('Kernel32', 'WideCharToMultiByte').call(cp, 0, str.to_ptr, -1, buf, buf.length, 0, 0)]
end
def transcode(str)
return to_mb(to_wc(str +"\0", 0)+"\0\0").sub(/\0+$/, "")
end
end
PathFileExists = Win32API.new("shlwapi", "PathFileExistsW", "P", "I")
MultiByteToWideChar = Win32API.new("kernel32", "MultiByteToWideChar", "ILPIPI", "I")
#--------------------------------------------------------------------------
# * File.exists rewrite
#--------------------------------------------------------------------------
def File.exists?(filename)
nfilename = Seiran20.transcode(filename) + "\0"
len = MultiByteToWideChar.call(65001, 0, nfilename, -1, 0, 0) << 1
buf = " " * len
MultiByteToWideChar.call(65001, 0, nfilename, -1, buf, len)
return PathFileExists.call(buf) == 0 ? false : true
end
#--------------------------------------------------------------------------
# * FileTest.exist rewrite
#--------------------------------------------------------------------------
def FileTest.exist?(filename)
return File.exists?(filename)
end
#--------------------------------------------------------------------------
# * Dir function rewrite (only needed)
#--------------------------------------------------------------------------
class << Dir
alias_method :old_mkdir, :mkdir
def mkdir(*args,&block)
args[0] = Seiran20.transcode(args[0])
old_mkdir(*args,&block)
end
end
#--------------------------------------------------------------------------
# * File.new and open rewrite
#--------------------------------------------------------------------------
class << File
alias_method :old_new, :new
alias_method :old_open, :open
def new(*args,&block)
args[0] = Seiran20.transcode(args[0])
old_new(*args,&block)
end
def open(*args,&block)
args[0] = Seiran20.transcode(args[0])
old_open(*args,&block)
end
end
#--------------------------------------------------------------------------
# * open rewrite( for commercial scripts)
#--------------------------------------------------------------------------
alias old_open open
def open(*args,&block)
args[0] = Seiran20.transcode(args[0])
old_open(*args,&block)
end
|
|