查看: 4845|回复: 3

[RMXP发布] 【小工具】内存数据($data)保护脚本

[复制链接]

水月·镜花

梦石
10
星屑
403
在线时间
1181 小时
注册时间
2005-10-22
回帖
1118

开拓者

发表于 2013-3-5 13:04:08 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
熟悉RGSS的人都会发现,RGSS1对$data(内存数据库)的保护实在堪忧
为了方便RM编辑器读写数据,硬盘数据库(*.rxdata)里所有数据都开通了attr_accessor,即可读写端口
而游戏初始化时通过$data = load_data("*.rxdata")的方法调用数据到内存
这样一来$data里调用的数据和rxdata一样是全部可读写
如果用户在添加脚本时没有注意,游戏运行中很容易会把$data里的数据改变掉,而这些数据一般是不允许修改的
举个例子,$data_weapons[1]指向1号武器的内存地址,由于$data_weapon直接复制了RPG::Weapon的格式,脚本中存在$data_weapons[1] = 999的情况
于是一件逆天武器就莫名其妙诞生了……虽然默认数据库存取方式下重启游戏就会失效,不过没有RM作者会希望这种情况诞生吧?
以下的脚本原理非常简单,就是将$data部分做成新的类,初始化进程中读取数据库,但只开放可读端口,避免内存数据库被改写

[pre lang="ruby" line="1"]#==============================================================================
# ■ Game_Data
#------------------------------------------------------------------------------
#  全游戏内存数据的类。实例在Scene_Title中调用
#==============================================================================

class Game_Data
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_reader    :actors
  attr_reader    :classes
  attr_reader    :skills
  attr_reader    :items
  attr_reader    :weapons
  attr_reader    :armors
  attr_reader    :enemies
  attr_reader    :troops
  attr_reader    :states
  attr_reader    :animations
  attr_reader    :tilesets
  attr_reader    :common_events
  attr_reader    :system
  attr_reader    :maps
  #--------------------------------------------------------------------------
  # ● 初始化对像
  #--------------------------------------------------------------------------
  def initialize
    # 载入数据库
    @actors        = load_data("Data/Actors.rxdata")
    @classes       = load_data("Data/Classes.rxdata")
    @skills        = load_data("Data/Skills.rxdata")
    @items         = load_data("Data/Items.rxdata")
    @weapons       = load_data("Data/Weapons.rxdata")
    @armors        = load_data("Data/Armors.rxdata")
    @enemies       = load_data("Data/Enemies.rxdata")
    @troops        = load_data("Data/Troops.rxdata")
    @states        = load_data("Data/States.rxdata")
    @animations    = load_data("Data/Animations.rxdata")
    @tilesets      = load_data("Data/Tilesets.rxdata")
    @common_events = load_data("Data/CommonEvents.rxdata")
    @system        = load_data("Data/System.rxdata")
    @maps          = [nil]
    index = 1
    while FileTest.exist?(sprintf("Data/Map%03d.rxdata", index))
      map = load_data(sprintf("Data/Map%03d.rxdata", index))
      @maps.push(map)
      index += 1
    end
  end
end

#=========================================
#  使用说明:
#=========================================
#
# 1. 脚本在main前插入
# 2. 找到 Scene_Title 的 main 定义,在“载入数据库”行以下加入
#     语句:data = Game_Data.new
# 3. 把所有  load_data(“xxxx.rxdata”)  改为  data.xxxx,再加上
#     语句 : $data_maps = data.maps
# 4. 找到 Game_Map 的 setup(map_id) 定义,将语句
#     @map = load_data(sprintf("Data/Map%03d.rxdata", @map_id))
#     改为 @map = $data_maps[@map_id]
#==========================================
#    * 注意
#    本脚本可能会延长游戏初始化时间
#==========================================

[/pre]



梦石
0
星屑
244
在线时间
584 小时
注册时间
2012-9-7
回帖
592
发表于 2013-3-5 18:13:28 | 显示全部楼层
有利有弊,这样虽然保护了
但是如果游戏中需要用到运行时改变数据库的效果就不能用了吧……
FTM正式版已经发布,点击图片开启传送门
回复

使用道具 举报

水月·镜花

梦石
10
星屑
403
在线时间
1181 小时
注册时间
2005-10-22
回帖
1118

开拓者

 楼主| 发表于 2013-3-6 13:29:44 | 显示全部楼层
wingzeroplus 发表于 2013-3-5 20:13
有利有弊,这样虽然保护了
但是如果游戏中需要用到运行时改变数据库的效果就不能用了吧…… ...

一般情況下單機遊戲很少會在執行時動到rxdata吧……除了存檔
原本RGSS中的 $data 就是作為全局常量使用的,全局變量都保存在 $game 實例中,所以基本上數據變動都是在 $game_xxxx 裏面
對應的 Game_Xxxx 類定義開放相應端口就可以了
回复

使用道具 举报

头像被屏蔽
梦石
0
星屑
653
在线时间
3774 小时
注册时间
2011-2-26
回帖
1577

开拓者

发表于 2013-5-14 00:18:27 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部