Project1

标题: 【小工具】内存数据($data)保护脚本 [打印本页]

作者: 电子最终龙    时间: 2013-3-5 13:04
标题: 【小工具】内存数据($data)保护脚本
熟悉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部分做成新的类,初始化进程中读取数据库,但只开放可读端口,避免内存数据库被改写

RUBY 代码复制
  1. #==============================================================================
  2. # ■ Game_Data
  3. #------------------------------------------------------------------------------
  4. #  全游戏内存数据的类。实例在Scene_Title中调用
  5. #==============================================================================
  6.  
  7. class Game_Data
  8.   #--------------------------------------------------------------------------
  9.   # ● 定义实例变量
  10.   #--------------------------------------------------------------------------
  11.   attr_reader    :actors
  12.   attr_reader    :classes
  13.   attr_reader    :skills
  14.   attr_reader    :items
  15.   attr_reader    :weapons
  16.   attr_reader    :armors
  17.   attr_reader    :enemies
  18.   attr_reader    :troops
  19.   attr_reader    :states
  20.   attr_reader    :animations
  21.   attr_reader    :tilesets
  22.   attr_reader    :common_events
  23.   attr_reader    :system
  24.   attr_reader    :maps
  25.   #--------------------------------------------------------------------------
  26.   # ● 初始化对像
  27.   #--------------------------------------------------------------------------
  28.   def initialize
  29.     # 载入数据库
  30.     @actors        = load_data("Data/Actors.rxdata")
  31.     @classes       = load_data("Data/Classes.rxdata")
  32.     @skills        = load_data("Data/Skills.rxdata")
  33.     @items         = load_data("Data/Items.rxdata")
  34.     @weapons       = load_data("Data/Weapons.rxdata")
  35.     @armors        = load_data("Data/Armors.rxdata")
  36.     @enemies       = load_data("Data/Enemies.rxdata")
  37.     @troops        = load_data("Data/Troops.rxdata")
  38.     @states        = load_data("Data/States.rxdata")
  39.     @animations    = load_data("Data/Animations.rxdata")
  40.     @tilesets      = load_data("Data/Tilesets.rxdata")
  41.     @common_events = load_data("Data/CommonEvents.rxdata")
  42.     [url=home.php?mod=space&uid=34015]@system[/url]        = load_data("Data/System.rxdata")
  43.     @maps          = [nil]
  44.     index = 1
  45.     while FileTest.exist?(sprintf("Data/Map%03d.rxdata", index))
  46.       map = load_data(sprintf("Data/Map%03d.rxdata", index))
  47.       @maps.push(map)
  48.       index += 1
  49.     end
  50.   end
  51. end
  52.  
  53. #=========================================
  54. #  使用说明:
  55. #=========================================
  56. #
  57. # 1. 脚本在main前插入
  58. # 2. 找到 Scene_Title 的 main 定义,在“载入数据库”行以下加入
  59. #     语句:data = Game_Data.new
  60. # 3. 把所有  load_data(“xxxx.rxdata”)  改为  data.xxxx,再加上
  61. #     语句 : $data_maps = data.maps
  62. # 4. 找到 Game_Map 的 setup(map_id) 定义,将语句
  63. #     @map = load_data(sprintf("Data/Map%03d.rxdata", @map_id))
  64. #     改为 @map = $data_maps[@map_id]
  65. #==========================================
  66. #    * 注意
  67. #    本脚本可能会延长游戏初始化时间
  68. #==========================================





作者: wingzeroplus    时间: 2013-3-5 18:13
有利有弊,这样虽然保护了
但是如果游戏中需要用到运行时改变数据库的效果就不能用了吧……
作者: 电子最终龙    时间: 2013-3-6 13:29
wingzeroplus 发表于 2013-3-5 20:13
有利有弊,这样虽然保护了
但是如果游戏中需要用到运行时改变数据库的效果就不能用了吧…… ...

一般情況下單機遊戲很少會在執行時動到rxdata吧……除了存檔
原本RGSS中的 $data 就是作為全局常量使用的,全局變量都保存在 $game 實例中,所以基本上數據變動都是在 $game_xxxx 裏面
對應的 Game_Xxxx 類定義開放相應端口就可以了
作者: 晴兰    时间: 2013-5-14 00:18
提示: 作者被禁止或删除 内容自动屏蔽




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1