#==============================================================================
# □ SPG(SmliP Gospel File Encrypt System) (分割定义 1)
#==============================================================================
# 福音文件加密系统
module SPG
#--------------------------------------------------------------------------
# ● 常量
#--------------------------------------------------------------------------
# 文件后缀名称
FILE_NAME_SUFFIX_SPG = ".spg"
FILE_NAME_SUFFIX_SAVE = ".rxdata"
#--------------------------------------------------------------------------
# ● 定义实例变量
#--------------------------------------------------------------------------
attr_reader :map_data # 全游戏地图初始化数据(只读)
attr_reader :rxdata # 综合数据(只读)
attr_reader :save_data # 存档数据(只读)
#--------------------------------------------------------------------------
# ● 更新
#--------------------------------------------------------------------------
def self.update
if @wait_count != nil
if @wait_count > 0
@wait_count -= 1
else
for l in @logo
l.visible = false
end
@logo[@logo_index].visible = true
@logo_index += 1
@logo_index = (@logo_index % 3)
@wait_count = 3
end
end
end
#--------------------------------------------------------------------------
# ● 开始图片进度条
# type : 图片摆放样式(<=0:保存样式 >0:读取样式)
#--------------------------------------------------------------------------
def self.start_picture(type = 1)
@wait_count = 0
@logo = []
# 图片摆放样式
type = type.to_i
for i in 0...3
s = Sprite.new
# 图片摆放样式(<=0:保存样式 >0:读取样式)
if type <= 0
s.bitmap = RPG::Cache.picture("LOGO/青蛙游戏/路易/save logo/路易-#{i}.png")
s.x = 640 - s.bitmap.width
s.y = 480 - s.bitmap.height
else
s.bitmap = RPG::Cache.picture("LOGO/青蛙游戏/路易/load logo/路易-#{i}.png")
s.x = 640 * 0.5 - s.bitmap.width * 0.5
s.y = 480 * 0.5 - s.bitmap.height * 0.5
end
s.z = 9999
s.visible = false
@logo.push(s)
end
@logo[0].visible = true
@logo[1].visible = false
@logo[2].visible = false
@logo_index = 0
end
#--------------------------------------------------------------------------
# ● 结束图片进度条
#--------------------------------------------------------------------------
def self.end_picture
@wait_count = nil
if @logo != nil
for l in @logo
l.dispose if l != nil
end
end
end
#--------------------------------------------------------------------------
# ● 执行加解密
# type : 加解密方式(<=0:加密方式 >=1:解密方式(保存为文件) >=2:解密方式(直接读取解密后的文件数据))
# file_name : 需要处理的文件名
# password : 密匙字符串(范围:1-0、A-Z、a-z)(作为执行加解密的指令方式,可以是多位)
#--------------------------------------------------------------------------
def self.start(type, file_name, password = "")
begin
type = type.to_i
password = password.to_s
# 大写字母
edh_upcase = ["A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z" ]
# 大写字母
edh_downcase = ["A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z" ]
edh_numeric = ["1","2","3","4","5","6","7","8","9","0"]
filename_object = "#{file_name}"
filename_new = "#{filename_object}" + "_new"
# 文件不存在的情况下
unless FileTest.exist?(filename_object)
return false
end
object = File.open(filename_object, "rb")
# 存储源文件数据用数组
object_data = object.readlines.clone
object.close
# 层数上限
code_max = 20
# 自校检随机值库存
rand_code_data = []
# 加解密次数
encrypt_num = 5
# 解密
if type >= 1
# 解压缩的方式读取文件
object = Zlib::GzipReader.open(filename_object)
#object = File.open(filename_object, "rb")
# 自定义字符串
by_text = Marshal.load(object)
for i in 1..code_max
# 读取
rand_code_data.push(Marshal.load(object))
end
nil_value = 0
for i in 0...rand_code_data.size
# 读取
nil_value += 1 if rand_code_data[i] == nil
end
# 读入各种对像
object_new = Marshal.load(object)
# (有自定义密匙的情况下)
if nil_value == 0
result_value = 0
for i in 0...rand_code_data.size
# 数值化
result_value += self.code_list(rand_code_data[i])[0][0, 1].to_i
end
# 求余
result_value = result_value % code_max
password = rand_code_data[result_value]
else
# 数据下一层是密匙
password = Marshal.load(object)
end
object.close
code_text = self.code_list(password)
object_new = [object_new[0]]
# 进行N次解密操作
for i in 1..encrypt_num
object_new = self.code_denote(1, object_new[0], code_text[0])
end
return self.load(object_new)
else
# ……
end
rescue
print("(010)无法运行游戏!请检查文件是否缺少或损坏。")
exit
end
end
#--------------------------------------------------------------------------
# ● 读取数据
# object : 解密后的对象数据
#--------------------------------------------------------------------------
def self.load(object)
# 代入对象数据
object_new = object
# 初始化存值
file = nil
for i in 0...object_new[0].size
# 如果存值是零的情况下(设为零是因为在不确定存值类型的情况下可以自动赋值,从而自动的改变了存值类型)
if file == nil
file = object_new[0][i]
else
file += object_new[0][i]
end
end
# 读取描绘存档文件用的角色数据
d = Marshal.load(file)
return d
end
#--------------------------------------------------------------------------
# ● 码表解析(加解密执行代码)
# code_text : 需要解码的码表字符串
#--------------------------------------------------------------------------
def self.code_list(code_text)
code_text = code_text.to_s
result_code = ""
for i in 0...code_text.size
# 获取一个字符串
case code_text[i, 1]
when "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" # 数值(1-0)
result_code += code_text[i, 1]
when "A" # 大写(A-Z)
result_code += "0"
when "B"
result_code += "1"
when "C"
result_code += "2"
when "D"
result_code += "3"
when "E"
result_code += "4"
when "F"
result_code += "5"
when "G"
result_code += "6"
when "H"
result_code += "7"
when "I"
result_code += "8"
when "J"
result_code += "9"
when "K"
result_code += "10"
when "L"
result_code += "11"
when "M"
result_code += "12"
when "N"
result_code += "13"
when "O"
result_code += "14"
when "P"
result_code += "15"
when "Q"
result_code += "16"
when "R"
result_code += "17"
when "S"
result_code += "18"
when "T"
result_code += "19"
when "U"
result_code += "20"
when "V"
result_code += "21"
when "W"
result_code += "22"
when "X"
result_code += "23"
when "Y"
result_code += "24"
when "Z"
result_code += "25"
when "a" # 小写(a-z)
result_code += "26"
when "b"
result_code += "27"
when "c"
result_code += "28"
when "d"
result_code += "29"
when "e"
result_code += "30"
when "f"
result_code += "31"
when "g"
result_code += "32"
when "h"
result_code += "33"
when "i"
result_code += "34"
when "j"
result_code += "35"
when "k"
result_code += "36"
when "l"
result_code += "37"
when "m"
result_code += "38"
when "n"
result_code += "39"
when "o"
result_code += "40"
when "p"
result_code += "41"
when "q"
result_code += "42"
when "r"
result_code += "43"
when "s"
result_code += "44"
when "t"
result_code += "45"
when "u"
result_code += "46"
when "v"
result_code += "47"
when "w"
result_code += "48"
when "x"
result_code += "49"
when "y"
result_code += "50"
when "z"
result_code += "51"
else # 默认的加解密执行方式
result_code += "312"
end
end
# 返回 已经解码的码表(=>指令表)
return [result_code]
end
#--------------------------------------------------------------------------
# ● 执行指令表(执行加解密方式)
# type : 加解密方式(<=0:加密方式 >=1:解密方式(保存为文件) >=2:解密方式(直接读取解密后的文件数据))
# object : 对象数据
# code_text : 需要执行的指令表字符串
#--------------------------------------------------------------------------
def self.code_denote(type, object, code_text)
tyep = type.to_i
code = code_text
# 获取对象数据
object_new = [object]
for i in 0...code.size
# 解密
if type >= 1
# 获取一个字符串并且转换为数值()
code_value = code[(code.size - 1 - i), 1].to_i
# 类型(<=0:加密 >0:解密)
code_type = 1
# 加密
else
# 获取一个字符串并且转换为数值
code_value = code[i, 1].to_i
# 类型(<=0:加密 >0:解密)
code_type = 0
end
#--------------------------------------------------------------------------
# ● 方式1:交叉法(执行一次为加密,再执行一次为解密)
# object : 源流数据组
# type : 类型(<=0:加密 >0:解密)
# value : 单元间隔数
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
# ● 方式2:插入法(首单元删除法)
# object : 源流数据组
# type : 类型(<=0:首单元向尾部前面添加(默认:加密) >0:尾部前面单元向首单元前面添加(默认:解密))
# value : 执行次数
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
# ● 方式3:插入法(指定单元位移到指定位置上)
# object : 源流数据组
# type : 类型(<=0:指定元向指定位置前面添加(默认:加密) >0:指定位置单元向指定位置上前面添加(默认:解密))
# value : 执行次数
# place : 位移位置([指定位置索引, 位移的所在索引])
#--------------------------------------------------------------------------
# 分歧 执行命令
case code_value
when 1
begin
# 方式1:交叉法(执行一次为加密,再执行一次为解密)
object_new = self.deed_1(object_new[0], code_type)
rescue
p "错误代码(SPG1)"
end
when 2
begin
# 方式2:插入法(首单元删除法)
object_new = self.deed_2(object_new[0], code_type)
rescue
p "错误代码(SPG2)"
end
when 3
begin
# 方式3:插入法(指定单元位移到指定位置上)
object_new = self.deed_3(object_new[0], code_type)
rescue
p "错误代码(SPG3)"
end
when 4
begin
object_new = self.deed_1(object_new[0], code_type)
rescue
p "错误代码(SPG4)"
end
when 5
begin
object_new = self.deed_2(object_new[0], code_type, 2)
rescue
p "错误代码(SPG5)"
end
when 6
begin
object_new = self.deed_2(object_new[0], code_type, 3)
rescue
p "错误代码(SPG6)"
end
when 7
begin
object_new = self.deed_3(object_new[0], code_type, 3, [1, 3])
rescue
p "错误代码(SPG7)"
end
when 8
begin
object_new = self.deed_3(object_new[0], code_type, 3, [2, 2])
rescue
p "错误代码(SPG8)"
end
when 9
begin
object_new = self.deed_3(object_new[0], code_type, 3, [3, 1])
rescue
p "错误代码(SPG9)"
end
when 0
else
end # case
end
# 压缩字符串操作
for i in 0...object_new[0].size
if type >= 1
# 解压
object_new[0][i] = self.zlib(object_new[0][i], 1)[0]
else
# 加压
# 解压
object_new[0][i] = self.zlib(object_new[0][i], 0)[0]
end
end
# 更新画面(防错:10秒备份)
Graphics.update
return object_new
end # def
#--------------------------------------------------------------------------
# ● 备份目录下指定类型的所有文件
# chdir_name : 目录名称
# type_name : 文件类型
#--------------------------------------------------------------------------
def self.bak_file(chdir_name = "DATA", type_name = "*")
# 创建的目录名称
list_name = "Bak"
# 如果目录不存在的情况下
# Dir.mkdir("#{list_name}") unless FileTest.directory?("#{list_name}")
# 获取目录下指定类型文件
file_name_data = self.file_name("#{chdir_name}","#{type_name}")
return if file_name_data.empty?
for file_name in file_name_data
# 复制文件(备份原文件用)
self.copy(file_name, "#{list_name}")
end
end
#--------------------------------------------------------------------------
# ● 获取目录下指定类型文件
# chdir_name : 目录名称
# type_name : 文件类型
#--------------------------------------------------------------------------
def self.file_name(chdir_name = "DATA", type_name = "*")
file_name_data = []
# 返回到指定目录
Dir.chdir("#{chdir_name}")
for file_name in Dir[type_name.to_s]
file_name_data.push(file_name.to_s) if FileTest.file?(file_name.to_s)
end
return file_name_data
end
#--------------------------------------------------------------------------
# ● 复制文件(备份原文件用)
# file_name : 原文件的名称
# chdir_name : 备份的文件夹名称
# type_name : 备份后附加的文件名后缀
#--------------------------------------------------------------------------
def self.copy(file_name, chdir_name = "Bak", type_name = ".bak")
begin
# 原文件的名称
out_file = "#{file_name}"
# 新备份文件的名称
new_file = "#{chdir_name}/#{out_file}" + "#{type_name}"
# 文件不存在的情况下
unless FileTest.exist?(out_file)
return false
end
# 打开源文件
object = File.open(out_file, "rb")
# 存储源文件数据用数组
object_data = []
# 读取源文件数据
object.each_line { |o| object_data.push(o) }
object.close
return if object_data == []
# 如果目录不存在的情况下
Dir.mkdir("#{chdir_name}") if !FileTest.directory?("#{chdir_name}") and chdir_name != ""
# 建立新文件
new = File.open(new_file, "wb")
# 写入读取到的源文件数据到新文件
object_data.each { |n| new.write(n) }
new.close
object_data = []
# 返回结果
return true
# 错误处理
rescue
return false
end
end
#--------------------------------------------------------------------------
# ● 压缩字符串(Zlib)
# string : 需要操作的字符串
# type : 类型(<=0:加压 >0:解压)
#--------------------------------------------------------------------------
def self.zlib(string,type)
# 即时刷新
self.update
# 返回 如果不是字符串的情况下
return [string] unless string.is_a?(String)
string = string
new_string = string
if type >= 1
new_string = Zlib::Inflate.inflate(string)
else
new_string = Zlib::Deflate.deflate(string, (rand(9) + 1))
end
return [new_string]
end
#--------------------------------------------------------------------------
# ● 方式1:交叉法(执行一次为加密,再执行一次为解密)
# object : 源流数据组
# type : 类型(<=0:加密 >0:解密)
# value : 单元间隔数
#--------------------------------------------------------------------------
def self.deed_1(object, type = 0, value = 2)
result = false
# 存储源文件数据用数组
object_data = object.clone
object_new = []
value = value.to_i
for i in 0...object_data.size
object_new.push(nil)
end
for v in 0...object_data.size
if v != 0 and v != object_data.size-1
if (v % value) == 0
v0 = (v - 1)
v1 = v
# p [v,v0,v1]
object_new[v0] = object_data[v1]
object_new[v1] = object_data[v0]
# 类型(<=0:加密 >0:解密)
if type >= 1
# Zlib 解压
object_new[v0] = self.zlib(object_data[v1], 1)[0]
object_new[v1] = self.zlib(object_data[v0], 1)[0]
else
# Zlib 加压
object_new[v0] = self.zlib(object_data[v1], 0)[0]
object_new[v1] = self.zlib(object_data[v0], 0)[0]
end
else
object_new[v] = object_data[v]
end
else
object_new[v] = object_data[v]
end
# 更新画面(防错:10秒备份)
Graphics.update if (v % 5000) == 0
reslut = true if v == (object_data.size - 1)
end
# 返回 ([流数据数组, 结果])
return [object_new, reslut]
end # def
#--------------------------------------------------------------------------
# ● 方式2:插入法(首单元删除法)
# object : 源流数据组
# type : 类型(<=0:首单元向尾部前面添加(默认:加密) >0:尾部前面单元向首单元前面添加(默认:解密))
# value : 执行次数
#--------------------------------------------------------------------------
def self.deed_2(object, type = 0, value = 2)
result = false
# 存储源文件数据用数组
object_data = object
object_new = object_data.clone
value = value.to_i
for v in 1..value
# 即时刷新
# self.update
# 加密
if type <= 0
# 删除并返回首单元
new = object_new.shift
new = self.zlib(new, 0)[0]
# 将已经删除的首单元数据添加到尾部单元的前面
object_new.insert((object_new.size - 1), new)
reslut = true if v == value
# 解密
else
# 删除并返回尾部前面的单元
new = object_new.delete_at((object_new.size - 1 - 1))
new = self.zlib(new, 1)[0]
# 将已经删除的尾部前面单元数据添加到首单元前面
object_new.insert(0, new)
reslut = true if v == value
end
end
# 返回 ([流数据数组, 结果])
return [object_new, reslut]
end # def
#--------------------------------------------------------------------------
# ● 方式3:插入法(指定单元位移到指定位置上)
# object : 源流数据组
# type : 类型(<=0:指定元向指定位置前面添加(默认:加密) >0:指定位置单元向指定位置上前面添加(默认:解密))
# value : 执行次数
# place : 位移位置([指定位置索引, 位移的所在索引])
# 注意:位置索引按照每行的字节数量而定,一般在1-6左右,超过字节数量上限即出错。
#--------------------------------------------------------------------------
def self.deed_3(object, type = 0, value = 2, place = [0, 3])
result = false
# 存储源文件数据用数组
object_data = object
object_new = object_data.clone
value = value.to_i
place = place
for v in 1..value
# 即时刷新
# self.update
# 加密
if type <= 0
new = object_new.delete_at(place[0])
new = self.zlib(new, 0)[0]
object_new.insert(place[1], new)
reslut = true if v == value
# 解密
else
new = object_new.delete_at(place[1])
new = self.zlib(new, 1)[0]
object_new.insert(place[0], new)
reslut = true if v == value
end
end
# 返回 ([流数据数组, 结果])
return [object_new, reslut]
end # def
end # module
# 应用
#SPG.start_change
#SPG.start_script_data